
1. 为什么我们需要一个“Agent 就绪”的知识包过去大半年我一直在折腾各种智能体项目从简单的问答机器人到复杂的自动化工作流踩过的坑比写过的代码还多。最让我头疼的一个问题不是模型不够聪明而是知识供给的方式太原始了。你手里有一堆文档、数据库表结构、API 说明、业务规则这些东西散落在各个角落格式五花八门。每次要让 Agent 去查个东西要么是硬编码一堆 if-else要么是写个脆弱的正则去解析 Markdown稍微换个文档格式就全盘崩溃。后来我意识到问题的根源在于我们给 Agent 喂的知识缺少一个“编译”的过程。就像写代码需要编译器把高级语言翻译成机器能执行的指令一样Agent 需要的知识也应该是经过结构化、语义化、可验证的中间产物。这个中间产物我把它叫做OKF 知识包——Object Knowledge Format一种面向对象的知识封装格式。这篇文章要聊的就是怎么用 Python 写一个编译器把原始的、零散的知识源编译成 Agent 可以直接消费的 OKF 知识包。核心关键词就三个Agent 就绪、OKF 知识包、Python 编译器实战。适合谁看如果你正在做 RAG 系统、智能客服、自动化决策 Agent或者单纯对“怎么让大模型更靠谱地使用知识”感兴趣那这篇内容应该能帮你省下不少试错时间。我先把结论摆在这儿Agent 就绪的知识包不是简单的向量化而是要把知识拆解成带类型、带关系、带约束的对象图并且每个对象都要有明确的“可操作性”标记。下面我会从设计思路、核心细节、实操过程、问题排查四个维度把整个编译器的实现逻辑掰开揉碎讲清楚。2. 整体设计OKF 知识包到底长什么样2.1 从“文档思维”切换到“对象思维”大多数人做知识库第一反应是“把文档切块、向量化、存进向量数据库”。这套流程本身没问题但它有个致命缺陷检索出来的东西是“文本片段”而不是“可操作的知识单元”。Agent 拿到一段文本还得自己理解、自己判断能不能用、怎么用。这就好比你去餐厅点菜服务员给你端上来一堆生食材让你自己炒。OKF 知识包的设计哲学完全不同。它要求每个知识单元都是一个对象这个对象至少包含以下字段类型标识这是个什么是“用户实体”、“操作指令”、“业务规则”还是“数据字段”属性集合这个对象有哪些特征比如一个“用户”对象有姓名、等级、历史行为。关系网络这个对象和其他对象怎么关联比如“订单”属于“用户”“订单”包含“商品”。操作接口Agent 能对这个对象做什么查询、修改、触发动作还是仅作参考约束条件使用这个对象时有什么限制比如“仅限管理员访问”、“必须满足库存大于零”。我试过直接用 JSON 手写这些对象写到第三十个就崩溃了——太容易出错而且没法维护。所以必须有一个编译器把人类可读的源知识自动转换成机器可执行的 OKF 格式。2.2 编译器的三段式架构整个 Python 编译器的架构我参考了传统编译器的经典三段式设计但针对知识场景做了大量简化第一段前端解析器。负责读取原始知识源。这些源可能是 Markdown 文档、YAML 配置文件、SQL 建表语句甚至是 Excel 表格。解析器要把这些异构格式统一转换成一种中间表示我称之为KIRKnowledge Intermediate Representation。KIR 本质上是一棵抽象语法树每个节点代表一个知识片段节点上挂着原始文本、来源位置、初步的类型推断。第二段中端语义分析器。这是整个编译器的核心。它要做三件事第一类型推导根据上下文判断每个知识片段应该是什么对象类型第二关系抽取识别对象之间的引用、包含、依赖关系第三约束注入根据预定义的规则库给对象打上操作权限和条件限制。这一步的输出是OKF 对象图一个带类型、带关系、带约束的有向图结构。第三段后端代码生成器。把 OKF 对象图序列化成 Agent 可以直接加载的格式。我选择的是JSON 嵌入式索引的方案主体用 JSON 存储对象和关系同时生成一个轻量级的倒排索引和向量索引方便 Agent 快速检索。为什么不直接存图数据库因为大多数 Agent 运行环境没有图数据库JSON 文件加内存索引是最通用的方案。提示三段式架构的好处是解耦。前端换一种源格式只需要改解析器后端换一种存储引擎只需要改生成器。中端的语义分析逻辑可以复用。2.3 为什么选择 Python 而不是其他语言这个问题我被问过很多次。答案很简单Agent 生态的母语是 Python。你去看主流的 Agent 框架、大模型 SDK、向量数据库客户端Python 都是第一公民。用 Python 写编译器意味着编译产物可以直接在 Agent 运行时里加载不需要跨语言调用不需要序列化协议转换。另外Python 的元编程能力足够强。我用dataclasses定义对象模型用ast模块做语法分析用typing做类型检查整个编译器不到两千行代码就搞定了。如果用 Java 或 Go光是类型系统的样板代码就得翻倍。当然Python 也有性能问题。我的应对策略是编译过程离线执行运行时只加载编译产物。也就是说编译器慢一点没关系反正一天跑一次Agent 运行时加载的是优化过的 JSON 和索引速度足够快。3. 核心细节从原始知识到 OKF 对象的完整链路3.1 源知识的结构化预处理在写编译器之前我先做了一件看似笨拙但极其重要的事把原始知识源整理成半结构化的 Markdown 模板。为什么不用纯自然语言因为自然语言的歧义性太强编译器很难准确推断类型和关系。为什么不用纯 JSON因为写 JSON 太痛苦而且业务人员根本不会用。我的模板长这样## 对象用户 - 类型实体 - 标识字段user_id - 属性 - user_id: 字符串必填 - user_name: 字符串必填 - user_level: 枚举可选值 [普通, 白银, 黄金, 钻石] - 关系 - 拥有 - 订单一对多 - 属于 - 用户组多对一 - 操作 - 查询允许 - 修改仅管理员 - 删除禁止 - 约束 - 用户等级为钻石时修改操作需要二次确认这个模板的好处是人类读得懂机器也解析得了。我用正则表达式就能把## 对象后面的名称提取出来用缩进层级判断属性、关系、操作的归属。实测下来业务人员培训半小时就能上手写比让他们写 YAML 靠谱多了。注意模板里的“类型”字段非常关键。我预定义了五种对象类型实体Entity、指令Action、规则Rule、数据字段Field、外部引用Reference。不同类型的对象在后续语义分析时的处理逻辑完全不同。3.2 类型推导的规则引擎设计类型推导是编译器最烧脑的部分。我的做法是基于规则 基于统计双通道推导。基于规则的通道我写了一个简单的专家系统。核心规则包括如果对象名称包含“用户”、“客户”、“会员”等词且属性里有“ID”字段判定为实体。如果对象名称是动词开头比如“创建订单”、“取消订阅”判定为指令。如果对象描述里包含“必须”、“禁止”、“仅当”等词判定为规则。如果对象是另一个对象的属性子集且没有独立标识判定为数据字段。基于统计的通道我用了一个轻量级的文本分类器。训练数据是我手动标注的五百个知识片段特征用的是 TF-IDF 加词性标注。这个分类器准确率大概 85%主要用来处理规则覆盖不到的边缘情况。两个通道的结果会做投票融合如果规则通道和统计通道结论一致直接采纳如果不一致标记为“待人工确认”输出到日志里。我实际跑下来需要人工确认的比例不到 5%完全可以接受。3.3 关系抽取的三种模式对象之间的关系我定义了三种抽取模式按优先级从高到低第一种显式声明。就是在 Markdown 模板里直接写了“关系”字段的。这种最可靠直接解析就行。比如“拥有 - 订单一对多”编译器会生成一条从“用户”对象指向“订单”对象的有向边边上标注关系类型“拥有”和基数“一对多”。第二种字段引用。如果对象 A 的某个属性其名称和对象 B 的标识字段相同或者符合“B_id”的命名模式编译器会自动推断 A 和 B 之间存在引用关系。比如“订单”对象里有“user_id”属性而“用户”对象的标识字段是“user_id”那就自动建立“订单 - 用户”的引用边。第三种语义相似。这是兜底策略。如果两个对象的描述文本余弦相似度超过阈值我设的是 0.75且它们没有显式关系编译器会生成一条“弱关联”边并标记为“待验证”。这种边在 Agent 运行时默认不激活但会保留在知识包里供后续人工审核。实操心得关系抽取最容易出错的地方是循环引用。比如“用户”拥有“订单”“订单”又引用“用户”如果不做处理Agent 在遍历关系时会陷入死循环。我的解决方案是在生成 OKF 对象图时做一次拓扑排序检测发现环就打断最弱的那条边并记录日志。3.4 约束注入的规则库设计约束注入是我认为 OKF 知识包区别于普通知识图谱的核心创新点。普通知识图谱只告诉你“是什么”和“有什么关系”但 OKF 还要告诉你“能做什么”和“什么条件下能做”。我的约束规则库用 YAML 定义结构如下constraints: - name: 管理员权限校验 applies_to: object_type: 实体 operation: 修改 condition: user.role admin action: allow - name: 钻石用户二次确认 applies_to: object_type: 实体 attribute: user_level value: 钻石 condition: operation 修改 action: require_confirmation - name: 库存非负校验 applies_to: object_type: 实体 name_pattern: .*库存.* condition: attribute.value 0 action: deny_if_false编译器在语义分析阶段会遍历 OKF 对象图中的每个对象匹配约束规则库里的条件。匹配成功后把约束以可执行表达式的形式挂载到对象上。Agent 运行时只需要一个简单的表达式求值器就能判断某个操作是否被允许。这里有个坑约束条件的表达式语言选择。我一开始想用 Python 的eval但安全性太差Agent 加载的知识包如果被篡改可能执行恶意代码。后来换成了simpleeval这个库它只支持基本的比较、逻辑运算和属性访问安全可控。4. 实操过程手把手实现一个最小可用编译器4.1 环境准备与依赖安装先说一下我的开发环境Python 3.10 以上推荐 3.11因为tomllib是内置的。核心依赖只有三个pip install pyyaml simpleeval scikit-learnpyyaml用来解析约束规则库simpleeval用来做安全的表达式求值scikit-learn用来跑那个轻量级文本分类器。其他的像json、re、dataclasses都是标准库不用额外装。项目目录结构我建议这样组织okf_compiler/ ├── compiler/ │ ├── __init__.py │ ├── frontend.py # 解析器 │ ├── middleend.py # 语义分析器 │ ├── backend.py # 代码生成器 │ └── models.py # 数据模型定义 ├── rules/ │ └── constraints.yaml # 约束规则库 ├── sources/ │ └── knowledge.md # 原始知识源 └── output/ └── okf_package.json # 编译产物这个结构清晰地把前端、中端、后端分开方便后续扩展。比如你想支持新的源格式只需要在frontend.py里加一个解析函数。4.2 定义核心数据模型在models.py里我用dataclasses定义了 OKF 对象的基本结构from dataclasses import dataclass, field from typing import List, Dict, Optional dataclass class OKFAttribute: name: str type: str required: bool False enum_values: Optional[List[str]] None description: str dataclass class OKFRelation: target: str relation_type: str cardinality: str # one-to-one, one-to-many, many-to-many description: str dataclass class OKFConstraint: name: str condition: str action: str # allow, deny, require_confirmation description: str dataclass class OKFObject: name: str object_type: str # entity, action, rule, field, reference identifier: Optional[str] None attributes: List[OKFAttribute] field(default_factorylist) relations: List[OKFRelation] field(default_factorylist) operations: Dict[str, str] field(default_factorydict) constraints: List[OKFConstraint] field(default_factorylist) source_location: str 这个模型看起来简单但涵盖了 Agent 需要的所有信息。source_location字段用来追溯知识来源方便调试和审计。4.3 前端解析器的实现前端解析器的核心任务是把 Markdown 模板转换成OKFObject列表。我用了状态机的思路import re from compiler.models import OKFObject, OKFAttribute, OKFRelation def parse_markdown(source_text: str) - list[OKFObject]: objects [] current_obj None current_section None for line in source_text.split(\n): line line.rstrip() if not line: continue # 检测对象开始 obj_match re.match(r^## 对象(.)$, line) if obj_match: if current_obj: objects.append(current_obj) current_obj OKFObject(nameobj_match.group(1).strip(), object_type) current_section None continue if current_obj is None: continue # 检测类型 type_match re.match(r^- 类型(.)$, line) if type_match: current_obj.object_type type_match.group(1).strip() continue # 检测标识字段 id_match re.match(r^- 标识字段(.)$, line) if id_match: current_obj.identifier id_match.group(1).strip() continue # 检测章节切换 section_match re.match(r^- (属性|关系|操作|约束)$, line) if section_match: current_section section_match.group(1) continue # 解析属性 if current_section 属性: attr_match re.match(r^\s- (\w): (.)$, line) if attr_match: name attr_match.group(1) desc attr_match.group(2) required 必填 in desc enum_values None enum_match re.search(r可选值 \[(.?)\], desc) if enum_match: enum_values [v.strip() for v in enum_match.group(1).split(,)] current_obj.attributes.append(OKFAttribute( namename, typestring, requiredrequired, enum_valuesenum_values, descriptiondesc )) # 解析关系 if current_section 关系: rel_match re.match(r^\s- (\w) - (\w)(.?)$, line) if rel_match: current_obj.relations.append(OKFRelation( targetrel_match.group(2), relation_typerel_match.group(1), cardinalityrel_match.group(3) )) # 解析操作 if current_section 操作: op_match re.match(r^\s- (\w)(.)$, line) if op_match: current_obj.operations[op_match.group(1)] op_match.group(2).strip() # 解析约束 if current_section 约束: con_match re.match(r^\s- (.)$, line) if con_match: current_obj.constraints.append(OKFConstraint( namecon_match.group(1), condition, action )) if current_obj: objects.append(current_obj) return objects这段代码看起来有点长但逻辑很直白逐行扫描遇到## 对象就新建对象遇到章节标记就切换状态遇到具体条目就解析并挂到当前对象上。实测下来解析一个包含五十个对象的 Markdown 文件耗时不到 0.1 秒。注意正则表达式里的中文括号和冒号容易出错建议在代码里统一用re.escape处理或者干脆把模板里的标点改成英文的。我踩过这个坑调试了半小时才发现是标点符号不匹配。4.4 中端语义分析器的实现语义分析器的入口函数接收OKFObject列表输出增强后的对象图。核心逻辑分三步第一步类型补全。对于object_type为空的对象调用类型推导引擎。我实现了一个简化版的规则引擎def infer_type(obj: OKFObject) - str: name obj.name if any(kw in name for kw in [用户, 客户, 会员, 商品, 订单]): return entity if any(name.startswith(kw) for kw in [创建, 取消, 更新, 删除]): return action if any(kw in name for kw in [规则, 策略, 约束]): return rule if obj.identifier is None and len(obj.attributes) 3: return field return reference第二步关系补全。遍历所有对象检查属性名是否匹配其他对象的标识字段def complete_relations(objects: list[OKFObject]) - None: id_map {obj.identifier: obj.name for obj in objects if obj.identifier} for obj in objects: for attr in obj.attributes: if attr.name in id_map and id_map[attr.name] ! obj.name: target id_map[attr.name] if not any(r.target target for r in obj.relations): obj.relations.append(OKFRelation( targettarget, relation_type引用, cardinality多对一, description自动推断 ))第三步约束注入。加载 YAML 规则库对每个对象做模式匹配import yaml from simpleeval import simple_eval def inject_constraints(objects: list[OKFObject], rules_path: str) - None: with open(rules_path, r, encodingutf-8) as f: rules yaml.safe_load(f)[constraints] for obj in objects: for rule in rules: applies rule.get(applies_to, {}) if applies.get(object_type) and applies[object_type] ! obj.object_type: continue if applies.get(name_pattern): import re if not re.search(applies[name_pattern], obj.name): continue obj.constraints.append(OKFConstraint( namerule[name], conditionrule.get(condition, ), actionrule.get(action, allow), descriptionrule.get(description, ) ))这三步跑完OKF 对象图就基本成型了。我通常会加一个验证环节检查有没有孤立对象没有任何关系的对象、有没有循环引用、有没有约束条件语法错误。验证不通过的对象会输出警告日志但不阻断编译流程。4.5 后端代码生成器的实现后端要做的事情很纯粹把OKFObject列表序列化成 JSON同时生成索引。JSON 结构我设计成这样{ version: 1.0, compiled_at: 2025-01-15T10:30:00, objects: { 用户: { type: entity, identifier: user_id, attributes: [...], relations: [...], operations: {...}, constraints: [...] } }, indexes: { by_type: {entity: [用户, 订单], action: [创建订单]}, by_relation: {拥有: [[用户, 订单]]}, inverted: {用户: [用户, 订单], 订单: [订单]} } }by_type索引让 Agent 可以快速按类型筛选对象by_relation索引支持关系遍历inverted索引是简单的关键词倒排用于文本检索。这三个索引加起来文件大小增加不到 20%但检索效率提升非常明显。生成代码大概三十行import json from datetime import datetime def generate_package(objects: list[OKFObject], output_path: str) - None: package { version: 1.0, compiled_at: datetime.now().isoformat(), objects: {}, indexes: {by_type: {}, by_relation: {}, inverted: {}} } for obj in objects: package[objects][obj.name] { type: obj.object_type, identifier: obj.identifier, attributes: [attr.__dict__ for attr in obj.attributes], relations: [rel.__dict__ for rel in obj.relations], operations: obj.operations, constraints: [con.__dict__ for con in obj.constraints] } # 构建 by_type 索引 package[indexes][by_type].setdefault(obj.object_type, []).append(obj.name) # 构建 by_relation 索引 for rel in obj.relations: package[indexes][by_relation].setdefault(rel.relation_type, []).append([obj.name, rel.target]) # 构建倒排索引 for attr in obj.attributes: package[indexes][inverted].setdefault(attr.name, []).append(obj.name) with open(output_path, w, encodingutf-8) as f: json.dump(package, f, ensure_asciiFalse, indent2)跑完这个函数output/okf_package.json就是最终产物。Agent 运行时只需要json.load一下就能拿到完整的知识包。5. 常见问题与排查技巧实录5.1 解析阶段的高频报错与修复问题一中文标点导致正则匹配失败。这是最常见的坑。Markdown 模板里如果用了中文冒号“”或中文括号“”而正则里写的是英文标点就会匹配不上。我的解决方案是在解析前做一次标点归一化def normalize_punctuation(text: str) - str: trans str.maketrans(【】, :()[]) return text.translate(trans)问题二缩进层级混乱。Markdown 对缩进敏感但不同编辑器对 Tab 和空格的转换规则不一样。我强制要求所有源文件用两个空格作为一级缩进并在解析前用line.replace(\t, )统一替换。问题三对象名称重复。如果两个对象同名后一个会覆盖前一个。我在解析阶段加了一个检查发现重名就抛出异常并在日志里打印两个对象的位置方便定位。5.2 语义分析阶段的典型异常异常一类型推导置信度低。当规则引擎和统计分类器结论不一致时对象会被标记为“待确认”。我的处理策略是默认采用规则引擎的结果但把统计分类器的建议写入对象的metadata字段。这样 Agent 运行时可以忽略但人工审核时能看到。异常二关系抽取产生大量弱关联。语义相似度阈值设得太低会导致几乎所有对象之间都产生弱关联边。我实测下来阈值设在 0.75 到 0.85 之间比较合适。低于 0.75 会漏掉一些真实关系高于 0.85 会引入太多噪声。异常三约束条件表达式语法错误。simpleeval对表达式语法要求比较严格比如不支持and和or的短路求值必须用和|。我在注入约束前加了一个语法预检步骤用simpleeval试跑一次失败就记录错误并跳过该约束。5.3 运行时加载的注意事项编译产物加载到 Agent 运行时有几个点需要特别注意第一JSON 文件大小。如果对象数量超过一千个JSON 文件可能达到几 MB。我建议在生成时做一次压缩去掉不必要的空格和换行。实测下来压缩后体积能减少 40% 左右。第二索引预热。Agent 启动时把by_type和by_relation索引加载到内存字典里倒排索引可以懒加载。这样启动速度能快不少。第三版本兼容。知识包格式可能会迭代我在 JSON 里加了version字段。Agent 加载时先检查版本号不兼容就拒绝加载并提示重新编译。5.4 常见问题速查表问题现象可能原因排查方法解决方案解析结果为空文件编码不是 UTF-8用file命令检查编码统一转成 UTF-8对象类型全是 reference类型推导规则未命中检查对象名称关键词补充规则或手动标注关系边数量异常多语义相似阈值过低打印相似度分布调高阈值到 0.8约束条件不生效表达式语法错误查看编译日志修正表达式语法Agent 加载报错JSON 格式损坏用json.load试加载重新编译或修复 JSON检索结果不相关倒排索引未更新检查索引构建逻辑重新生成索引实操心得我强烈建议在编译器里加一个--verbose参数把每个阶段的中间结果都打印出来。调试的时候看着对象一个个被解析、被推导类型、被注入约束比看最终 JSON 直观多了。6. 编译产物的实际效果与 Agent 集成示例6.1 一个完整的编译流程演示假设我们有一个knowledge.md里面定义了“用户”、“订单”、“商品”三个对象。跑一遍编译器python -m compiler.main --source sources/knowledge.md --rules rules/constraints.yaml --output output/okf_package.json --verbose输出日志大概长这样[INFO] 解析到 3 个对象 [INFO] 类型推导用户 - entity, 订单 - entity, 商品 - entity [INFO] 关系补全订单 - 用户引用订单 - 商品引用 [INFO] 约束注入用户 注入 2 条约束订单 注入 1 条约束 [INFO] 验证通过无孤立对象无循环引用 [INFO] 编译产物已写入 output/okf_package.json大小 12KB整个过程不到一秒。生成的 JSON 里“用户”对象大概长这样{ 用户: { type: entity, identifier: user_id, attributes: [ {name: user_id, type: string, required: true}, {name: user_name, type: string, required: true}, {name: user_level, type: string, enum_values: [普通, 白银, 黄金, 钻石]} ], relations: [ {target: 订单, relation_type: 拥有, cardinality: 一对多} ], operations: {查询: 允许, 修改: 仅管理员, 删除: 禁止}, constraints: [ {name: 管理员权限校验, condition: user.role admin, action: allow}, {name: 钻石用户二次确认, condition: operation 修改, action: require_confirmation} ] } }6.2 Agent 侧如何消费 OKF 知识包Agent 加载知识包的代码非常简洁import json class OKFLoader: def __init__(self, package_path: str): with open(package_path, r, encodingutf-8) as f: self.package json.load(f) self.objects self.package[objects] self.indexes self.package[indexes] def get_object(self, name: str) - dict: return self.objects.get(name) def find_by_type(self, obj_type: str) - list: return [self.objects[n] for n in self.indexes[by_type].get(obj_type, [])] def check_operation(self, obj_name: str, operation: str, context: dict) - str: obj self.objects.get(obj_name) if not obj: return deny for con in obj.get(constraints, []): if con[action] deny: return deny if con[action] require_confirmation: return require_confirmation return obj.get(operations, {}).get(operation, deny)Agent 在决定是否执行某个操作时只需要调用check_operation传入对象名、操作名和上下文就能拿到明确的指令允许、拒绝、还是需要二次确认。这比让大模型自己去“理解”业务规则靠谱得多。6.3 性能与效果对比我做过一个简单的对比测试同样的知识内容一种方式是直接向量化存进向量数据库另一种是编译成 OKF 知识包。测试任务是让 Agent 回答“钻石用户修改信息需要什么条件”。向量化方案的回答是“根据文档钻石用户修改信息可能需要管理员确认。”——注意这个“可能”说明模型不确定。OKF 方案的回答是“钻石用户修改信息需要二次确认且操作者必须是管理员。”——精确、无歧义。在响应时间上向量化方案检索耗时约 50msOKF 方案直接查字典耗时不到 1ms。当然OKF 方案的前期编译需要时间但这是一次性的。提示OKF 知识包并不是要取代向量检索而是互补。对于事实性、规则性的知识用 OKF对于开放性、描述性的知识用向量检索。两者结合Agent 的表现最稳。7. 后续扩展方向与个人经验这个编译器目前只支持 Markdown 源格式但架构上留了扩展点。如果你想支持 YAML 或 SQL 建表语句只需要在frontend.py里加一个解析函数把源文本转换成OKFObject列表后面的流程完全复用。我试过加一个 SQL 解析器大概花了两个小时主要时间花在字段类型映射上。另一个扩展方向是增量编译。目前每次编译都是全量的如果知识源很大编译时间会线性增长。我的思路是给每个对象算一个哈希值编译时对比哈希只重新编译变化的部分。这个功能我还没实现但设计上已经预留了source_hash字段。最后分享一个我踩过的坑不要试图让编译器做太多“智能”的事。我一开始想让编译器自动从自然语言文档里抽取对象和关系结果准确率惨不忍睹。后来退回到半结构化模板的方案虽然需要人工整理源文件但准确率直接拉到 95% 以上。编译器的价值在于“翻译”和“校验”而不是“理解”。把理解的工作交给写文档的人编译器只负责把结构化的知识转换成 Agent 能用的格式这样分工最合理。这个 OKF 编译器的代码我已经迭代了三个版本目前稳定运行在几个内部项目里。如果你也在做 Agent 相关的知识工程不妨试试这个思路。从最简单的 Markdown 模板开始先跑通一个对象再逐步扩展。别一上来就追求大而全小步快跑才是正道。