news 2026/9/7 7:25:17

Understand-Anything domain-analyzer:把代码库提炼成“领域-流程-步骤“三层业务领域图的 Agent 设计解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Understand-Anything domain-analyzer:把代码库提炼成“领域-流程-步骤“三层业务领域图的 Agent 设计解析

Understand-Anything domain-analyzer:把代码库提炼成"领域-流程-步骤"三层业务领域图的 Agent 设计解析

【免费下载链接】Understand-AnythingGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.项目地址: https://gitcode.com/GitHub_Trending/un/Understand-Anything

domain-analyzer 是 Understand-Anything 插件中的业务领域分析专家 Agent:它接收"预处理领域上下文"或"已有知识图谱"二选一作为输入,产出一份三层结构(Business Domain → Business Flow → Business Step)的domain-graph.json,让仪表盘能够以交互式流程图的形式展示代码中的业务逻辑走向。读完本文,你将完整掌握该 Agent 的输入契约、输出 Schema 的每个字段含义、flow_step权重编码顺序的规则细节,以及在核心包中通过 Zod Schema 对领域图做校验与别名归一化的源码实现。

一、domain-analyzer 的角色与两种输入

在 Understand-Anything 的/understand-domain技能流水线中(见 understand-domain SKILL.md),真正"读懂业务"的是 domain-analyzer.md 定义的这个 Agent。它被调度技能(dispatching skill)以子 Agent 形式派发,收到的上下文恰好是以下两种之一:

  • Option A — 预处理领域上下文(来自domain-context.json):包含文件树、入口点、导出/导入关系和代码片段。这份 JSON 由轻量 Python 预处理脚本生成,适用于项目中还没有知识图谱的场景;
  • Option B — 已有知识图谱(来自knowledge-graph.json):一份完整的结构化知识图谱,包含 nodes、edges、layers 和 tours。此时 Agent 直接从节点摘要、标签和关系推导领域知识,无需再读取任何源文件

调度方会在 prompt 中明确告知适用哪种选项,并把上下文数据直接附在 prompt 中。Agent 的任务只有一件事:分析给定上下文,产出一份领域图 JSON 文件

这种"双路径、同输出"的设计在 业务领域知识设计文档中有详细说明:路径 1(轻量扫描)的 token 成本约为完整/understand扫描的 10-20%,路径 2(从图谱推导)则几乎不需要读文件。

二、三层业务结构:Domain / Flow / Step

Agent 输出的领域图采用严格的三层层次结构:

层级含义文档示例
Business Domaindomain节点)高层业务区域"Order Management"、"User Authentication"、"Payment Processing"
Business Flowflow节点)领域内的具体流程"Create Order"、"Process Refund"
Business Stepstep节点)流程内的单个动作"Validate input"、"Check inventory"

规模上文档给出了明确目标:2-6 个 domain、每个 domain 2-5 个 flow、每个 flow 3-8 个 step,小项目可以更少。同时强调两条纪律:"用代码中真实存在的业务术语,而不是泛泛的词汇"以及"不要发明代码中不存在的流程——只记录实际存在的东西"。

三、输出 Schema:完整 JSON 结构与字段说明

Agent 必须产出如下精确结构的 JSON(以下完整继承自 domain-analyzer.md 的 Output Schema 一节):

{ "version": "1.0.0", "project": { "name": "<project name>", "languages": ["<detected languages>"], "frameworks": ["<detected frameworks>"], "description": "<project description focused on business purpose>", "analyzedAt": "<ISO timestamp>", "gitCommitHash": "<commit hash>" }, "nodes": [ { "id": "domain:<kebab-case-name>", "type": "domain", "name": "<Human Readable Domain Name>", "summary": "<2-3 sentences about what this domain handles>", "tags": ["<relevant-tags>"], "complexity": "simple|moderate|complex", "domainMeta": { "entities": ["<key domain objects>"], "businessRules": ["<important constraints/invariants>"], "crossDomainInteractions": ["<how this domain interacts with others>"] } }, { "id": "flow:<kebab-case-name>", "type": "flow", "name": "<Flow Name>", "summary": "<what this flow accomplishes>", "tags": ["<relevant-tags>"], "complexity": "simple|moderate|complex", "domainMeta": { "entryPoint": "<trigger, e.g. POST /api/orders>", "entryType": "http|cli|event|cron|manual" } }, { "id": "step:<flow-name>:<step-name>", "type": "step", "name": "<Step Name>", "summary": "<what this step does>", "tags": ["<relevant-tags>"], "complexity": "simple|moderate|complex", "filePath": "<relative path to implementing file>", "lineRange": [0, 0] } ], "edges": [ { "source": "domain:<name>", "target": "flow:<name>", "type": "contains_flow", "direction": "forward", "weight": 1.0 }, { "source": "flow:<name>", "target": "step:<flow>:<step>", "type": "flow_step", "direction": "forward", "weight": 0.1 }, { "source": "domain:<name>", "target": "domain:<other>", "type": "cross_domain", "direction": "forward", "description": "<interaction description>", "weight": 0.6 } ], "layers": [], "tour": [] }

几个值得注意的细节:

  1. 节点 ID 前缀约定domain:flow:step:前缀之后必须使用kebab-case(如domain:order-management,而不是domain:OrderManagement);step 的 ID 形如step:<flow-name>:<step-name>,天然把步骤挂到所属流程上。
  2. domainMeta按节点类型分工:domain 节点用entities/businessRules/crossDomainInteractions描述实体、业务规则与跨域交互;flow 节点用entryPoint/entryType标注触发方式(如POST /api/orders),entryType取值限定为http|cli|event|cron|manual
  3. layerstour有意留空:领域图由仪表盘单独视图渲染,不使用 layers 和 tours。
  4. step 节点可携带代码定位filePath(相对项目根目录)+lineRange;若无法确定精确文件,则省略这两个字段而不是猜测。

flow_step 权重编码顺序:一条容易被忽视的关键规则

文档第一条规则是整个领域图"步骤有序"机制的核心:

flow_step 的 weight 编码顺序:使用 0-1 之间的小数权重。对于 N 个步骤:第一个 = 1/N 四舍五入到 1 位小数,第二个 = 2/N,依此类推。5 步示例:0.1, 0.2, 0.3, 0.4, 0.5;15 步示例:0.1, 0.1, 0.1, ...(步长为round(1/N, 1),最小 0.1)。核心要求是权重单调递增且全部落在0.0 到 1.0 闭区间内。

这条规则的意义在仪表盘源码中得到印证:DomainGraphView.tsx 中,领域视图正是收集flow_step边,把edge.weight存入stepOrderMap,再按 weight 排序渲染"从左到右"的步骤链路——也就是说,Agent 输出的权重值直接决定流程图上步骤的先后顺序,权重乱序等于流程图乱序。

四、八条规则与硬性约束

domain-analyzer.md 在 Rules 一节给出 8 条分析规则:

  1. flow_step 权重编码顺序(如上节详述);
  2. 每个 flow 必须通过contains_flow边连接到某个 domain
  3. 每个 step 必须通过flow_step边连接到某个 flow——这保证了三层结构的连通性,任何节点都不允许"悬空";
  4. 跨域边cross_domain)描述 domain 之间的交互,可用可选的description字段解释交互内容;
  5. step 节点的文件路径必须相对项目根目录;无法确定时省略filePathlineRange
  6. 具体而非泛化——使用代码中真实的业务术语;
  7. 不臆造代码中不存在的 flow
  8. 规模适配:2-6 个 domain、每 domain 2-5 个 flow、每 flow 3-8 个 step。

Critical Constraints 一节进一步给出 6 条硬性约束,这些约束与后续校验环节一一对应:

  • 所有节点 ID 前缀后必须是 kebab-case;
  • 所有weight值必须在 0.0 到 1.0 闭区间内;
  • 每个节点必须有非空summary至少一个 tag
  • complexity只能是simple/moderate/complex三者之一;
  • 不得创建重复节点 ID
  • 不得创建自引用边

五、源码级佐证:核心包如何校验领域图

Agent 的约束并非"口头约定",而是在核心包的 Zod Schema 中强制执行。以下结论均可在仓库源码中直接确认。

5.1 节点类型与领域边类型是 Schema 的一等公民

packages/core/src/schema.ts 中,GraphNodeSchematype枚举在常规代码节点(file、function、class……)之外显式包含"domain", "flow", "step"三个领域类型,并带有可选的domainMeta字段:

export const GraphNodeSchema = z.object({ id: z.string(), type: z.enum([ "file", "function", "class", "module", "concept", // ... "domain", "flow", "step", // ... ]), // ... summary: z.string(), tags: z.array(z.string()), complexity: z.enum(["simple", "moderate", "complex"]), domainMeta: DomainMetaSchema.optional(), }).passthrough();

同文件中EdgeTypeSchema定义了 38 种边类型,其中领域专用的三种单列一类(schema.ts#L12):

"contains_flow", "flow_step", "cross_domain", // Domain

GraphEdgeSchema则对 Agent 文档中"weight 必须在 0.0 到 1.0 之间"这条约束做了机器校验:weight: z.number().min(0).max(1)

5.2 DomainMeta 的类型定义

packages/core/src/types.ts#L31-L38 给出了与 Agent 文档中domainMeta字段完全对应的 TypeScript 接口:

export interface DomainMeta { entities?: string[]; businessRules?: string[]; crossDomainInteractions?: string[]; entryPoint?: string; entryType?: "http" | "cli" | "event" | "cron" | "manual"; }

entryType的五个枚举值与 Agent 文档中 flow 节点domainMeta.entryType的取值列表完全一致。

5.3 别名归一化:容忍 LLM 的"近义表达"

由于领域图由 LLM 生成,实际输出常用近义词而非规范类型名。schema.ts 维护了节点类型别名表,把 LLM 常见的变体归一化到规范类型:

// Domain aliases — "process" intentionally excluded (ambiguous with OS/Node.js process) business_domain: "domain", business_flow: "flow", business_process: "flow", task: "step", business_step: "step",

边类型同样有别名表(schema.ts#L131-L133):has_flow → contains_flownext_step → flow_stepinteracts_with → cross_domain。值得注意的一个细节:注释明确说明故意排除process这个别名,因为它与操作系统/Node.js 的process概念有歧义。

5.4 测试用例:领域图的端到端校验示例

packages/core/src/tests/domain-types.test.ts 提供了一个最小但完整的领域图夹具,恰好就是 Agent 文档中"Order Management"示例的落地版本:domain:order-management→(contains_flow,weight 1.0)→flow:create-order(带domainMeta: { entryPoint: "POST /api/orders", entryType: "http" })→(flow_step,weight 0.1)→step:create-order:validate(带filePath: "src/validators/order.ts"lineRange: [10, 30])。该测试文件验证了 5 类行为,均可直接运行复核:

  • 含 domain/flow/step 节点与contains_flowflow_step边的图能通过validateGraph
  • 追加domain:logistics与带descriptioncross_domain边(weight 0.6)后仍合法;
  • 节点类型写成business_domain/business_flow/business_step时被自动归一化为domain/flow/step
  • 边类型写成has_flow/next_step时被归一化为contains_flow/flow_step
  • 校验过程中domainMeta完整保留在输出节点上。

这组测试实质上就是对 Agent 输出契约的"验收标准":只要生成的domain-analysis.json满足文档中的 Schema 与约束(哪怕类型名写成别名),标准校验管线就能通过。

六、上下游流水线:上下文从哪来,结果到哪去

Agent 不是孤立运行的。结合 understand-domain SKILL.md 的六个阶段,完整链路如下:

  1. Phase 0 — 确定 PROJECT_ROOT 与数据目录:输出落在项目的数据目录$UA_DIR(新目录为.ua/,若项目已存在旧目录.understand-anything/则沿用旧目录,保证老项目无需迁移)。若当前在 git worktree 中,还会把输出重定向到主仓库根目录(worktree 会话结束数据会被销毁,issue #133);

  2. Phase 1 — 检测已有图谱:若$UA_DIR/knowledge-graph.json存在且未传--full,先做新鲜度检查(对比图谱记录的gitCommitHashgit diff的项目范围变更),然后走"从图谱推导"路径;否则走轻量扫描;

  3. Phase 2 — 轻量扫描(Option A 的原料来源):运行 extract-domain-context.py 生成$UA_DIR/intermediate/domain-context.json。设计文档将其定位为"cheat sheet":廉价 Python 预处理 → 昂贵 LLM 拿到干净的小输入 → 更低成本换更好结果。该脚本的上下文预算在源码顶部以常量固定(extract-domain-context.py#L31-L37):

    • 文件树最大深度 6 层、每目录最多 50 个文件、全局最多 5000 个文件;
    • 签名采样最多 40 个文件、每文件最多 80 行;
    • 入口点最多 200 个;
    • 输出 JSON 硬上限 512 KB——_truncate_to_fit()按"先砍文件树 → 再砍签名预览 → 再砍入口片段 → 最后减少签名/入口数量"的顺序渐进裁剪,保证不超出 Agent 上下文限制。

    入口点检测覆盖五类触发模式(extract-domain-context.py#L77-L121),与 flow 节点entryType的五个取值对应:Express/Koa/Flask/FastAPI 等 HTTP 路由、CLI 命令(.command、argparse 子命令)、事件监听(.on@EventHandler等)、定时任务(@Cron/@Scheduled等),以及export function handleXxx/processXxx/onXxx这类通用导出处理器。文件签名提取还会按controllerservicehandlerworkflowjob等业务逻辑关键词给文件打分排序,优先采样最可能含业务逻辑的文件(extract-domain-context.py#L256-L272)。

  4. Phase 3 — 从图谱推导(Option B 的原料来源):直接读取knowledge-graph.json,把全部节点(类型、名称、摘要、标签)、边(尤其calls/imports/contains)、层描述和 tour 步骤整理为结构化上下文,无需读任何源文件;

  5. Phase 4 — 领域分析:读取$PLUGIN_ROOT/agents/domain-analyzer.md(即本文档),带着 Phase 2/3 的上下文派发子 Agent,Agent 把结果写入$UA_DIR/intermediate/domain-analysis.json

  6. Phase 5 — 校验与保存:用标准图谱校验管线(Schema 已支持 domain/flow/step 类型)校验;校验失败时记录警告但保存有效部分(错误容忍策略);最终保存到$UA_DIR/domain-graph.json,并清理中间文件domain-analysis.jsondomain-context.json

  7. Phase 6 — 启动仪表盘:自动触发/understand-dashboard,仪表盘检测到domain-graph.json后默认展示领域视图。

七、结果写入与响应规范

domain-analyzer.md 的 Writing Results 一节对 Agent 的最终行为做了三点限定:

  1. JSON 必须写入项目数据目录(.ua/,或存在时的旧目录.understand-anything/)下的intermediate/domain-analysis.json使用 prompt 中给定的精确输出路径
  2. 项目根目录由 prompt 提供,Agent 不自行猜测;
  3. 文本响应只允许返回简短摘要:创建了哪些 domain、flow、step 的数量,以及关键领域名称;严禁在文本回复中贴出完整 JSON——这既避免污染会话上下文,也让 Phase 5 的校验环节有唯一可信的数据来源。

八、小结:一份"契约式"的 Agent 定义

从源码结构看,domain-analyzer.md 并不只是一个提示词,而是一份与工程管线严丝合缝的输出契约:它的节点/边类型对应 schema.ts 中的 Zod 枚举与别名表;它的 weight 区间约束对应z.number().min(0).max(1);它的flow_step权重排序约定被 DomainGraphView.tsx 直接消费为步骤渲染顺序;它的"Order Management"示例在 domain-types.test.ts 中有同名夹具做回归验证。对希望自定义或扩展该 Agent 的开发者来说,理解"文档约束 — Schema 校验 — 测试夹具 — 仪表盘消费"这条闭环,是保证领域图稳定生成的关键;对使用者而言,只需记住:保证上下文输入来自两条合法路径之一、让 Agent 只写intermediate/domain-analysis.json、由标准管线完成校验落盘,即可得到一份可交互探索的业务领域图。

【免费下载链接】Understand-AnythingGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.项目地址: https://gitcode.com/GitHub_Trending/un/Understand-Anything

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 7:24:39

rtk 的 GitHub Copilot 集成:PreToolUse 命令重写 Hook 的实现与验证

rtk 的 GitHub Copilot 集成&#xff1a;PreToolUse 命令重写 Hook 的实现与验证 【免费下载链接】rtk CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies 项目地址: https://gitcode.com/GitHub_Tren…

作者头像 李华
网站建设 2026/9/7 7:22:45

STM8外部中断从原理到实战:寄存器配置与避坑指南

简介&#xff1a;STM8外部中断程序开发包&#xff0c;面向使用IAR环境的嵌入式初学者与开发者&#xff0c;系统梳理了外部中断的触发源、模式选择、优先级设置、嵌套处理及标志清除等关键知识点&#xff0c;并结合实验工程演示MCU如何对外部事件做出实时响应&#xff0c;帮助读…

作者头像 李华
网站建设 2026/9/7 7:21:46

BiSeNet语义分割实战:从ZIP包到完整训练推理

简介&#xff1a;BiSeNet.zip 是一份针对实时语义分割任务、基于 BiSeNet 的完整工程包&#xff0c;面向需要快速构建和训练自定义数据集的深度学习开发者&#xff0c;解决了从数据准备、模型训练到测试推理的流程适配问题。压缩包内共149个文件&#xff0c;主要包含 Python 脚…

作者头像 李华
网站建设 2026/9/7 7:21:06

QMK固件开发环境完整搭建指南

QMK固件开发环境完整搭建指南 【免费下载链接】qmk_firmware Open-source keyboard firmware for Atmel AVR and Arm USB families 项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware QMK固件是面向 Atmel AVR 和 Arm USB 芯片族的开源键盘固件&#xff0…

作者头像 李华
网站建设 2026/9/7 7:21:03

视觉定位新范式:从弱标签到城市级地图的规模化之路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 7:19:38

电力负荷预测实战:数据清洗、特征工程与模型选型全解析

简介&#xff1a;电力负荷预测分析资源包&#xff0c;面向电力系统从业人员、数据分析与机器学习学习者&#xff0c;聚焦短期、中期、长期负荷预测任务。负荷预测是电网规划与调度的重要基础&#xff0c;短期结果影响机组启停&#xff0c;中长期结果支撑运营检修与扩容决策。包…

作者头像 李华