Understand-Anything /understand-domain 设计解析:从代码中萃取三层业务领域知识图谱
本文基于 Understand-Anything 仓库中的设计规格 2026-04-01-business-domain-knowledge-design.md,系统讲解 /understand-domain 技能的设计动机、领域图数据模型、双路径分析流水线与 Dashboard 渲染方案。读完后,你将理解如何用"领域—流程—步骤"三层抽象把业务逻辑从代码结构中剥离出来,并掌握从预处理脚本、LLM 分析 Agent 到 domain-graph.json 落盘、可视化 drill-down 的完整技术链路。
一、问题与方案:从"结构依赖"走向"业务语义"
设计文档开篇指出了既有知识图谱的局限:文件级依赖关系在 IDE 中本就能看到,当文件数量庞大时,罗列依赖边并不能降低认知负荷——开发者仍然需要在脑中重建"这段代码到底在做什么"。真正缺的是业务领域知识:内嵌在代码里的逻辑与领域概念,而非结构性接线。
对应的解决方案是新增 /understand-domain 技能:从代码库中萃取业务领域知识,并在 Dashboard 中渲染为横向流程图(horizontal flow graph)。提供两种视图模式:高层的 Domain 视图(可用时默认)与既有的 Structural 视图,并通过开关切换。
架构上采用设计文档中的 Approach C:独立文件、共享 Schema(Shared Schema):
- 领域数据存放在独立文件
domain-graph.json中,复用同一套KnowledgeGraph类型系统,仅扩展新的节点/边类型; - Dashboard 同时探测两个文件并提供视图切换;
- 领域节点可以通过 ID 引用结构节点(structural node),实现下钻。
文档给出了选择独立文件的四个理由:/understand-domain 可以轻量独立运行,也可以与完整图谱并存;共享 Schema 使搜索、校验、过滤对两种图都生效;不会污染结构图谱;每个文件本身都是独立合法的。这一决策在当前仓库中得到了落实——types.ts 中 GraphNode 携带可选的 domainMeta?: DomainMeta 字段,KnowledgeGraph 根结构(nodes/edges/layers/tour)不变,领域图因此可以直接走既有的校验与持久化通道。
二、领域图 Schema:三层层级与新节点、边类型
三层业务层级
- Business Domain(顶层)——如 "Purchasing"、"Logistics"、"Warehouse Management";
- Business Flow(中层)——如 "Create Order"、"Process Refund";
- Business Step(叶子)——如 "Validate input"、"Check inventory"、"Persist order"。
新增节点类型(3 种)
| 类型 | 用途 | 示例 |
|---|---|---|
domain |
业务领域簇 | "Order Management"、"Logistics" |
flow |
领域内的业务流程 | "Create Order"、"Process Refund" |
step |
流程中的单个步骤 | "Validate order input" |
在 types.ts 中,NodeType 现已包含 domain | flow | step(该文件注释标注节点类型共 27 种,其中 3 种属于 domain 类)。
新增边类型
| 类型 | 用途 |
|---|---|
contains_flow |
domain → flow |
flow_step |
flow → step(通过 weight 字段编码顺序,如 0.1、0.2、…) |
cross_domain |
domain → domain(领域间交互) |
implements |
step → 结构图中的 file/function 节点 ID(跨图引用) |
从源码结构看,types.ts 的 EdgeType 中新增的 Domain 类别边为 contains_flow | flow_step | cross_domain 三种;implements 复用的是既有的 Structural 结构边类型,用于把 step 指向结构图中的文件/函数节点,实现跨图 drill-down 引用。
flow_step 的顺序编码在实现中约定为:权重取 0–1 之间单调递增的分数值。domain-analyzer.md 给出了具体规则:对 N 个步骤,第 i 步取 i/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 为步长递增)。
节点结构示例
Domain 节点(携带 domainMeta 中的实体、业务规则、跨领域交互):
// domain node
{
id: "domain:order-management",
type: "domain",
name: "Order Management",
summary: "Handles the complete order lifecycle...",
tags: ["e-commerce", "core-business"],
complexity: "complex",
domainMeta?: {
entities: ["Order", "LineItem", "OrderStatus"],
businessRules: ["Orders require inventory check before confirmation"],
crossDomainInteractions: ["Triggers Logistics on order confirmed", "Reads from Customer Service for buyer info"]
}
}
Flow 节点(携带入口点信息):
{
id: "flow:create-order",
type: "flow",
name: "Create Order",
summary: "Customer submits a new order through the API",
tags: ["write-path", "api"],
complexity: "moderate",
domainMeta?: {
entryPoint: "POST /api/orders",
entryType: "http" | "cli" | "event" | "cron" | "manual"
}
}
Step 节点(叶子节点,直接挂 filePath 与 lineRange 指向代码):
{
id: "step:create-order:validate-input",
type: "step",
name: "Validate order input",
summary: "Checks request body against order schema, rejects invalid payloads",
tags: ["validation"],
complexity: "simple",
filePath: "src/validators/order-validator.ts",
lineRange: [12, 45]
}
上述 domainMeta 的字段在 types.ts 中被定义为 DomainMeta 接口:entities?、businessRules?、crossDomainInteractions?、entryPoint?、entryType?(枚举 http | cli | event | cron | manual),与设计文档完全一致。
文件输出
领域图保存到项目的数据目录(设计文档写作时为 .understand-anything/domain-graph.json,当前实现中数据目录已演进为优先 .ua/、存在旧目录时兼容 .understand-anything/,见后文持久化部分)下的 domain-graph.json——与 knowledge-graph.json 同构、独立合法。persistence/index.ts 中新增了 DOMAIN_GRAPH_FILE = "domain-graph.json" 常量与 saveDomainGraph() / loadDomainGraph() 两个函数:保存前会做文件路径清洗(sanitiseFilePaths);加载时默认走 validateGraph 校验,校验失败抛出 Invalid domain graph 错误,可通过 options.validate: false 跳过。
三、分析流水线:两条路径,同一输出
Path 1:轻量扫描(无既有图谱时)
File tree scan
→ Static entry point detection (tree-sitter)
→ Route definitions, exported handlers, main(), event listeners, cron decorators
→ Feed to LLM: file tree + detected entry points + sampled file contents
→ LLM outputs: domains, flows, steps, cross-domain interactions
→ Build domain-graph.json
Token 成本约为一次完整 /understand 扫描的 10–20%。其核心思想(在 SKILL.md Phase 2 中表述得更直白)是:预处理脚本不产出领域图,而是产出"原料"(文件树、入口点、exports/imports),让昂贵的 LLM 把精力花在真正的领域分析上,而不是用几十次工具调用去探索代码库——"便宜的 Python 预处理 → 昂贵 LLM 拿到小而干净的输入 → 更少的成本获得更好的结果"。
Path 2:从既有图谱推导
Load knowledge-graph.json
→ Extract: all nodes, edges, layers, summaries, tour
→ Feed to LLM: graph data as structured context
→ LLM outputs: domains, flows, steps, cross-domain interactions
→ Build domain-graph.json
这条路径几乎免费:不需要读任何源文件,LLM 直接基于既有的节点摘要、标签与调用边进行推理。
路径选择:/understand-domain 检查数据目录下 knowledge-graph.json 是否存在——存在走 Path 2,否则走 Path 1。--full 参数可强制走 Path 1(即使图谱存在也重新扫描)。
Agent 结构
新增一个 Agent:domain-analyzer(opus 模型),两条路径都由它处理;大型代码库可按入口点分组分批处理。该 Agent 的完整定义见 agents/domain-analyzer.md,它规定了:
- 输入二选一:Option A 为
domain-context.json(预处理上下文),Option B 为既有knowledge-graph.json; - 输出 Schema:完整的
KnowledgeGraphJSON,project段含 name/languages/frameworks/description/analyzedAt/gitCommitHash,layers与tour有意留空(Dashboard 用独立视图渲染领域图,不使用 layers/tour); - 规则:flow_step 权重单调递增且限于 0–1;每个 flow 必须经
contains_flow连到 domain;每个 step 必须经flow_step连到 flow;step 的filePath相对项目根,无法确定时省略filePath和lineRange;规模建议为 2–6 个领域、每域 2–5 个流程、每流程 3–8 个步骤,小项目可以更少; - 硬约束:节点 ID 前缀后必须为 kebab-case(如
domain:order-management而非domain:OrderManagement);每个节点必须有非空summary和至少一个 tag;complexity只能取simple | moderate | complex;禁止重复 ID、自引用边,以及虚构代码库中不存在的领域/流程。
四、预处理脚本:extract-domain-context.py
设计文档将脚本定位为技能附带脚本(bundled with the skill),放在 understand-anything-plugin/skills/understand-domain/ 下(而非用于开发工具的 scripts/),在 LLM Agent 之前运行,输出 .understand-anything/intermediate/domain-context.json。实际实现 extract-domain-context.py 的调用方式为 python extract-domain-context.py <project-root>,输出到数据目录(.ua/ 或遗留 .understand-anything/)的 intermediate/domain-context.json。
关键配置参数
脚本头部定义了一组控制上下文规模的常量,这是"控制 token 成本"的核心手段:
| 常量 | 默认值 | 作用 |
|---|---|---|
MAX_FILE_TREE_DEPTH |
6 | 文件树最大扫描深度 |
MAX_FILES_PER_DIR |
50 | 每目录最多文件数 |
MAX_FILES_TOTAL |
5000 | 文件树总量上限 |
MAX_SAMPLED_FILES |
40 | 提取签名的采样文件数上限 |
MAX_LINES_PER_FILE |
80 | 每文件签名提取的起始行数 |
MAX_ENTRY_POINTS |
200 | 入口点数量上限 |
MAX_OUTPUT_BYTES |
512 KB | 输出文件体积上限,保证落在 Agent 上下文限制内 |
入口点检测模式
脚本内置 ENTRY_POINT_PATTERNS 正则表,覆盖六类入口(与设计文档"route decorators、app.get/post、main()、event listeners"等描述对应并实际扩展):
- http:Express/Koa 路由(
app|router|server.get/post/...('/...'))、Flask/FastAPI/NestJS 装饰器路由(@route/@get/@PostMapping等)、Next.js/Remix 路由处理函数(export async function GET/POST/...); - cli:
.command('name')(commander 风格)、add_parser('name')(argparse); - event:
.on('event')监听器、@EventHandler/@Subscribe/@Listener装饰器; - cron:
@Cron('@...')、@Schedule(...)、crontab 等; - http(GraphQL/gRPC):
@Query("...")等 resolver、.proto中的service Xxx {; - manual:导出的处理函数(
export (async )?function (handle*|process*|on*))。
每个命中项记录 file、line、type、description、match(截断至 120 字符)与 snippet(签名 + 后几行,截断至 300 字符),落实了设计文档"代码片段保持简短(签名 + 前几行,而非完整函数体)"的要求。
文件签名与元数据
extract_file_signatures() 按"业务逻辑优先"策略采样:文件名中包含 controller、service、handler、router、model、repository、usecase、event、middleware、workflow、job 等关键词的文件得分更高,被优先提取 exports/imports(分别取前 20 个)与不超过 500 字符的 preview。extract_metadata() 读取 package.json、Cargo.toml、go.mod、pyproject.toml、pom.xml、README 等元数据文件,截取关键片段,让 LLM 理解项目的业务定位。
体积控制:渐进式裁剪
_truncate_to_fit() 实现四级渐进裁剪,确保输出不超过 512 KB:① 文件树截断到前 200 项;② 签名 preview 截断到 200 字符;③ 入口点 snippet 截断到 100 字符;④ 签名列表缩到 20 个、入口点缩到 100 个。
领域上下文输出结构
设计文档规定的 domain-context.json 结构(文件树、入口点、文件签名)如下:
{
"fileTree": ["src/api/orders.ts", "src/services/...", "..."],
"entryPoints": [
{
"file": "src/api/orders.ts",
"type": "http",
"method": "POST",
"path": "/api/orders",
"handler": "createOrder",
"lineRange": [15, 45],
"snippet": "async function createOrder(req, res) { ... }"
}
],
"fileSignatures": {
"src/services/order-service.ts": {
"exports": ["createOrder", "cancelOrder", "getOrderById"],
"imports": ["inventory-service", "pricing-service", "order-repo"],
"summary": null
}
}
}
实际实现中该结构还包含 projectRoot、fileCount 与 metadata 段,并且脚本明确不依赖重型库(仅标准库 re、json、pathlib),自行解析 .gitignore 为正则模式、跳过 node_modules/.git/dist 等目录、跳过符号链接以避免死循环——对应设计文档"Walk the file tree (respecting .gitignore)"的要求。
五、技能集成与执行流程
SKILL.md 将设计文档的 7 步执行流细化为 Phase 0–6,并补充了若干实战工程细节:
- Phase 0:解析
PROJECT_ROOT与$UA_DIR——含 worktree 重定向:若当前目录是 git worktree(通过比较git rev-parse --git-dir与--git-common-dir判断),输出会重定向到主仓库根,避免 worktree 会话结束时数据目录被销毁(issue #133);数据目录优先保留遗留.understand-anything/,否则使用.ua/。同时解析PLUGIN_ROOT(依次尝试CLAUDE_PLUGIN_ROOT、~/.understand-anything-plugin、符号链接解析、codex/opencode/pi 的克隆安装路径),用于定位 Agent 定义文件。 - Phase 1:检测既有图谱——若
knowledge-graph.json存在且未传--full,先做新鲜度检查:读取图谱元数据中的project.gitCommitHash,与HEAD做项目作用域的 diff(必须带-- .pathspec,避免 monorepo 中相邻项目的变更误报过期;哈希不一致但项目 diff 为空不算过期),有变更则提示先运行/understand刷新图谱。 - Phase 2:轻量扫描(Path 1)——运行
python ./extract-domain-context.py "$PROJECT_ROOT",产出domain-context.json。 - Phase 3:从图谱推导(Path 2)——读取
knowledge-graph.json,把节点(类型/名称/摘要/标签)、边(尤其calls/imports/contains)、层描述与 tour 步骤整理为结构化上下文,无需读源文件。 - Phase 4:领域分析——读取
$PLUGIN_ROOT/agents/domain-analyzer.md,派发 subagent,输出写到intermediate/domain-analysis.json。 - Phase 5:校验与保存——走标准图谱校验流水线(schema 已支持 domain/flow/step);校验失败时记录警告但保存有效部分(错误容忍);保存到
domain-graph.json,清理两个 intermediate 文件。 - Phase 6:自动触发
/understand-dashboard——Dashboard 检测到domain-graph.json后默认展示 Domain 视图。
六、Dashboard:Domain 视图
视图切换
- 左上角胶囊开关:"Domain" / "Structural";
domain-graph.json存在时 Domain 视图为默认;- 只存在一个图文件时不显示切换开关;
- 切换视图时保留侧边栏状态。
App.tsx 中,store 同时持有 graph、domainGraph 与 viewMode 三个状态,仅当结构图与领域图同时存在时才渲染切换开关,与设计文档"only one graph file exists, no toggle shown"一致。
横向流程布局
设计文档规定:布局引擎为 Dagre(rankdir: "LR",从左到右);缩放行为分三层——缩小看整个领域簇(圆角大矩形,簇间为 cross_domain 边);点击领域展开为横向"泳道"展示 flows;点击 flow 展示从左到右的 step 逐步追踪。
实现上,DomainGraphView.tsx 保留了这一从左到右的方向语义:组件先同步构建节点/边,再异步执行布局;源码注释明确写着"DomainGraphView used dagre LR; preserve that direction with ELK",即以 ELK 布局引擎的 "elk.direction": "RIGHT" 承接原 Dagre LR 方案。布局问题会通过 store 汇入 WarningBanner 提示;无领域图时给出引导文案"Run /understand-domain to generate one"。
领域簇与流程追踪渲染
领域簇卡片(设计文档示意):
┌─────────────────────────────────────┐
│ Order Management │
│ "Handles the complete order..." │
│ │
│ Entities: Order, LineItem, Status │
│ Flows: Create Order, Cancel Order │
│ Rules: "Requires inventory check" │
└─────────────────────────────────────┘
──cross_domain──→ [Logistics]
- 领域簇使用金色/琥珀色描边(与既有主题一致),簇面上展示 summary、实体列表、流程数量与规则摘要;
- 跨领域边为粗虚线并带标签。
流程追踪渲染:
POST /api/orders
┌──────────┐ ┌──────────────┐ ┌───────────┐ ┌──────────┐ ┌────────────┐
│ Validate │───→│ Check │───→│ Calculate │───→│ Persist │───→│ Send │
│ Input │ │ Inventory │ │ Pricing │ │ Order │ │ Confirm │
└──────────┘ └──────────────┘ └───────────┘ └──────────┘ └────────────┘
- step 由
flow_step边按weight排序、自左向右连接; - 左侧显示入口点标签作为流程触发器;
- 点击 step 后侧边栏显示详情并链接到结构视图。
侧边栏适配与 Drill-Down
- 选中 domain:显示 summary、业务规则、实体、跨域交互、可点击的 flow 列表;
- 选中 flow:显示入口点信息、按序步骤列表、复杂度;
- 选中 step:显示描述、"View in code" 链接(切换到结构视图并导航到对应文件/函数)、上一步/下一步链接;
- 跨视图下钻:当 step 存在指向结构节点 ID 的
implements边时,侧边栏出现 "View implementation" 按钮,点击后切换到结构视图并定位该节点;面包屑形如Domain: Order Management > Flow: Create Order > Step: Validate Input → [structural view]。
NodeInfo.tsx 中同样按 viewMode 与 domainGraph 分支渲染领域侧边栏,CodeViewer 在 domain 模式下切换活动图为 domainGraph,均与上述设计对齐。
七、错误容忍与归一化别名
流水线级容错
| 阶段 | 错误处理 |
|---|---|
| 预处理脚本 | 单文件解析失败则跳过并继续,记录被跳过文件;入口点检测为尽力而为(best-effort) |
| LLM 输出解析 | 与既有 parseTourGenerationResponse() 同策略——从 markdown 中提取 JSON,处理部分响应 |
| Schema 校验 | 复用既有自动修复流水线:sanitize → normalize(别名)→ apply defaults → validate;丢弃损坏的节点/边,不让整图失败 |
| 跨图引用 | implements 边指向不存在的结构节点 ID 时保留边并标记 unresolved;Dashboard 渲染该 step 但不提供下钻链接 |
领域专属校验规则
- 没有 flow 的 domain:告警但保留(summary/entities 仍有价值);
- 没有 step 的 flow:告警但保留(入口点信息仍有价值);
- step 顺序损坏:
weight缺失/重复时按数组位置重新编号; - 孤儿 step:未连接任何 flow 的 step 挂到合成的 "Uncategorized" flow;
- 重复 domain:按名称相似度模糊匹配合并,flows 合并;
- 空的领域图:Dashboard 显示错误横幅——"Domain extraction failed — try running
/understandfirst for richer context, then/understand-domain"。
Dashboard 韧性
- domain 节点缺少
domainMeta时,侧边栏仅展示 summary/tags; domain-graph.json整体校验失败时,回退到结构视图并显示警告横幅;- 部分有效的图谱渲染其有效部分。
归一化别名与实现差异
设计文档给出了节点与边类型的别名映射(LLM 可能输出同义词,校验流水线将其归一):
// Node type aliases
"business_domain" → "domain"
"process" → "flow"
"workflow" → "flow"
"action" → "step"
"task" → "step"
// Edge type aliases
"has_flow" → "contains_flow"
"next_step" → "flow_step"
"interacts_with" → "cross_domain"
"implemented_by" → "implements"
对照 schema.ts 中的实现表,可以观察到两处有意偏离设计文档的收紧:
- 节点别名实际为
business_domain → domain、business_flow / business_process → flow、task / business_step → step,而process被刻意排除——源码注释说明其"与操作系统/Node.js 的 process 概念歧义";workflow、action也未收录,降低了误归一风险; - 边别名收录了
has_flow、next_step、interacts_with,但implemented_by没有被映射到implements——注释指出该别名会反转边的方向,LLM 应直接使用implements并保证 source/target 正确。
这些细节说明别名表的最终取舍比设计稿更保守:宁可让未知类型走"丢弃损坏节点"的容错路径,也不做可能引入错误方向关系的激进映射。
八、变更地图
设计文档列出的改动面与实际仓库落点对应如下:
| 领域 | 变更 | 仓库对应 |
|---|---|---|
packages/core/src/types.ts |
新增 3 种节点类型、域边类型、domainMeta 可选字段 |
types.ts:DomainMeta 接口与 GraphNode.domainMeta |
packages/core/src/schema.ts |
扩展 Zod schema 与新类型别名 | schema.ts:节点/边别名表及 DomainMeta 校验 |
packages/core/src/persistence/ |
新增 loadDomainGraph() / saveDomainGraph() |
persistence/index.ts |
skills/understand-domain/extract-domain-context.py |
新预处理脚本(随技能打包) | extract-domain-context.py |
agents/domain-analyzer.md |
新 Agent 定义 | domain-analyzer.md |
skills/understand-domain.md |
新技能定义 | SKILL.md(含 --full 参数) |
packages/dashboard/src/store.ts |
新增 domainGraph、viewMode 状态 |
已在 App.tsx 等处消费 |
packages/dashboard/src/components/ |
新增 DomainGraphView.tsx、DomainClusterNode.tsx、StepNode.tsx 等;修改 App.tsx、NodeInfo.tsx、FilterPanel.tsx |
DomainGraphView.tsx、DomainClusterNode.tsx、StepNode.tsx 均已存在 |
packages/dashboard/src/utils/ |
新增领域横向布局工具 | 布局能力现由共享的 ELK 工具(如 elk-layout.ts)承担,方向参数保持 LR |
九、小结
/understand-domain 的设计可以用三句话概括:
- 数据层——用"domain → flow → step"三层节点与
contains_flow/flow_step/cross_domain" / 跨图implements引用,把业务语义叠加在既有KnowledgeGraph类型系统之上,并以独立的domain-graph.json` 文件落盘,与结构图谱互不污染; - 流水线层——"Python 廉价预处理 + opus 领域分析 Agent"的组合,把 LLM 输入压缩到 512 KB 以内的干净上下文;有图谱时直接从图谱推导,把 token 成本压到最低;
- 体验层——Dashboard 的 Domain/Structural 双视图、左侧到右的流程泳道、以及 step → 代码位置的 drill-down,让"代码在做什么"这一问题从结构依赖图中被真正回答。
值得注意的是,从设计稿到落地,几处工程决策(数据目录 .ua/ 迁移与兼容、worktree 重定向、图谱新鲜度检查、别名表收紧、Dagre → ELK 布局迁移)都体现了同一原则:领域图谱必须像结构图谱一样,能在真实项目的混乱环境(遗留目录、worktree、monorepo、LLM 不稳定输出)下可靠地跑通并优雅降级。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00