1. 为什么我决定让代码来写 PRD做后端和业务中台的朋友大概率都经历过这种场面需求评审会上产品经理讲得眉飞色舞开发在下面疯狂记笔记等到真正动手写代码的时候发现当初记的那几条规则根本对不上——字段的边界条件没写清楚状态流转的触发时机含糊其辞异常分支更是全靠脑补。最后代码写完了PRD 还停留在某个共享文档的初稿状态谁也不敢说这份文档和线上跑的逻辑是一致的。我所在的团队做的是偏交易和结算方向的系统业务规则密集、状态机复杂一个订单从创建到结算要经过十几个状态节点每个节点都有各自的校验条件和触发动作。这种场景下PRD 和代码脱节带来的代价特别高改一个规则要翻三四个文档新人接手要花两周才能理清主流程测试同学写用例全靠对着代码反推。我一直在想能不能让代码本身成为 PRD 的源头而不是让 PRD 和代码各说各话。这个想法在接触到 AI Agent 的 Skill 机制之后变得可行了。所谓 Skill你可以理解成给 AI Agent 装的一个专业技能包——它把某类任务的输入格式、处理逻辑、输出规范封装在一起Agent 调用这个 Skill 就能稳定地完成特定工作。我设计并落地了两个 Skill一个负责从代码里抽取业务规则另一个负责把规则渲染成结构化的 PRD 文档。两个 Skill 串起来就实现了代码自己写出 PRD这件事。这篇文章我会把整套方案的来龙去脉讲清楚为什么选 Skill 而不是直接写脚本、两个 Skill 各自怎么设计、业务规则怎么从代码里被识别出来、生成的 PRD 怎么保证可追溯、以及我在实操中踩过的那些坑。如果你也在做 AI Agent 相关的开发或者被 PRD 和代码不一致的问题折磨过这篇内容应该能给你一些可以直接抄作业的思路。2. 把业务规则从代码里捞出来的第一个 Skill2.1 业务规则到底藏在代码的哪些角落在动手写 Skill 之前我先花了两天时间做了一件事把现有代码里承载业务规则的地方全部梳理一遍。这个梳理过程比我想象中重要得多因为它直接决定了 Skill 的输入设计。以我们系统的 Python 代码为例业务规则主要分布在这么几个位置。第一类是校验函数比如validate_order_amount、check_settlement_cycle这种函数名本身就带着业务语义函数体里是一堆 if-else 判断。第二类是状态机的转移表通常是一个字典或者枚举定义了从哪个状态可以到哪个状态、触发条件是什么。第三类是配置化的规则比如费率表、限额表这些以常量或配置文件的形式存在。第四类是注释和 docstring很多老代码里真正的业务意图其实写在注释里代码只是实现手段。这四类位置的信息密度和结构化程度完全不同。校验函数和状态机是结构化的适合程序化抽取配置化规则需要结合上下文理解注释和 docstring 则是非结构化的自然语言恰恰是 AI 最擅长处理的部分。所以我的第一个 Skill 设计思路就是用程序化手段抽取结构化部分用 AI 理解非结构化部分两者合并成完整的业务规则集。这里有个经验不要一上来就想让 AI 读全部代码。代码量一大上下文窗口根本放不下而且大量与业务无关的工具代码会稀释 AI 的注意力。先做人工梳理圈定业务规则密集区再让 Skill 聚焦处理这些区域效果会好很多。2.2 Skill 的输入契约设计给 AI 划定工作边界Skill 设计里最关键的一步是定义输入契约。我见过很多 AI Agent 项目失败就是因为输入太随意Agent 每次拿到的信息格式都不一样输出自然不稳定。我的第一个 Skill 叫rule_extractor它的输入契约是这样的{ source_files: [ { path: order/validators.py, content: ..., language: python } ], rule_scope: order_lifecycle, extraction_dimensions: [ validation_rules, state_transitions, config_constraints, business_intents ] }source_files是要分析的代码文件列表每个文件带上路径、内容和语言类型。rule_scope是规则范围用来告诉 Skill 这次关注的是哪个业务域避免它去分析无关代码。extraction_dimensions是抽取维度明确要求 Skill 从哪几个角度去提取规则。这个契约设计背后有个考量AI Agent 的输出质量很大程度上取决于输入约束的清晰度。你告诉它帮我分析这段代码它会给你一堆泛泛而谈的总结你告诉它从校验规则、状态转移、配置约束、业务意图四个维度分析每个维度输出结构化 JSON它就能给出可用的结果。2.3 抽取逻辑的三层处理管线rule_extractor内部的处理逻辑我设计成了三层管线这个分层是踩过坑之后才定下来的。第一层是语法层解析。用 Python 自带的ast模块把代码解析成抽象语法树然后遍历树节点识别出函数定义、条件判断、字典字面量这些结构。这一层完全是确定性的不涉及 AI目的是把代码的骨架先提取出来。比如遇到一个函数里有连续的 if-elif-else语法层就能定位到这些分支的位置和条件表达式。第二层是语义层理解。把语法层提取出的结构连同原始代码片段一起送给 AI让 AI 判断这段逻辑对应的是什么业务规则。举个例子代码里写if order.amount 10000 and order.type B2B语法层只能告诉你这是个条件判断语义层要理解出B2B 订单金额超过一万元时需要特殊处理这条业务规则。第三层是关联层整合。把语义层输出的零散规则按照业务实体和流程节点做关联整合。比如订单创建时的金额校验和订单结算时的金额校验可能来自不同文件但它们属于同一个业务实体的不同生命周期阶段关联层要把它们串起来。# 语法层解析的核心逻辑示意 import ast def extract_structural_elements(source_code): tree ast.parse(source_code) elements [] for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): elements.append({ type: function, name: node.name, lineno: node.lineno, docstring: ast.get_docstring(node) }) elif isinstance(node, ast.If): elements.append({ type: condition, lineno: node.lineno, test: ast.unparse(node.test) }) return elements这三层管线的价值在于把确定性工作和不确定性工作分开。语法解析交给程序保证准确语义理解交给 AI发挥它的长处关联整合再用程序做规则化的拼接。这样整个 Skill 的输出既稳定又灵活。2.4 让 AI 稳定输出结构化规则的提示词技巧语义层是整个 Skill 里最不确定的部分因为 AI 的输出质量波动很大。我试了好几版提示词最后总结出几个关键技巧。第一个技巧是用 JSON Schema 约束输出格式。不要只说输出 JSON而是把完整的 schema 写进提示词里包括每个字段的类型、含义、示例值。AI 看到具体的 schema输出的结构就稳定多了。第二个技巧是给 few-shot 示例。我在提示词里放了两三个输入代码片段 → 输出规则 JSON的完整示例覆盖了校验规则、状态转移、配置约束三种典型情况。有了示例AI 就知道该往哪个方向理解。第三个技巧是要求 AI 标注置信度和来源。每条规则都要带上confidence字段high/medium/low和source_location字段文件路径加行号。置信度低的规则我会人工复核来源信息则是后面做可追溯的基础。{ rule_id: order_amount_b2b_threshold, rule_type: validation, description: B2B 类型订单金额超过 10000 元时触发人工审核, condition: order.type B2B AND order.amount 10000, action: trigger_manual_review, confidence: high, source_location: order/validators.py:45-52 }这套提示词技巧用下来AI 输出的规则准确率从最初的六成左右提升到了九成以上。剩下的那一成主要靠置信度标注筛出来人工处理。3. 第二个 Skill把规则渲染成可追溯的 PRD3.1 PRD 模板的骨架怎么定第一个 Skill 输出的是结构化的规则 JSON第二个 Skill 的任务是把它变成人读得懂的 PRD。这里有个设计决策PRD 的模板骨架是固定的还是动态生成的我一开始想做成动态生成让 AI 根据规则内容自己决定文档结构。试了一版之后发现不行生成的文档每次结构都不一样产品经理和测试同学根本没法形成阅读习惯。后来改成固定骨架加动态填充文档的章节结构是固定的但每个章节里的内容根据规则动态生成。固定骨架长这样文档概述、业务实体说明、状态流转图、规则明细表、异常处理、变更记录。这个骨架覆盖了 PRD 的核心要素而且和大多数团队的 PRD 阅读习惯吻合。这里有个容易忽略的点PRD 的读者不只是产品经理还有开发、测试、运营。不同角色关注的点不一样。开发关注规则的技术实现细节测试关注边界条件和异常分支运营关注业务影响。所以我在规则明细表里加了影响角色字段标注每条规则主要影响哪些角色方便不同读者快速定位自己关心的部分。3.2 规则到文档段落的映射逻辑从规则 JSON 到 PRD 段落中间需要一个映射逻辑。这个映射不是简单的一对一而是要根据规则的类型和关联关系做聚合。校验类规则聚合成规则明细表里的行每条规则一行列出规则 ID、描述、条件、动作、来源。状态转移类规则聚合成状态流转图和配套的转移说明表。配置约束类规则单独成节因为这类规则通常需要结合具体的配置值来说明。业务意图类规则则融入文档概述和各个章节的说明文字里作为背景信息。映射逻辑里有个细节值得说规则的排序。我最初按规则 ID 排序结果文档读起来很跳跃。后来改成按业务生命周期排序——订单创建的规则在前支付、发货、结算的规则依次往后。这样读文档就像跟着业务流程走一遍理解成本低很多。def map_rules_to_sections(rules, template): sections {} # 按业务生命周期阶段分组 lifecycle_order [creation, payment, fulfillment, settlement] grouped group_by_lifecycle(rules, lifecycle_order) for stage, stage_rules in grouped.items(): sections[stage] { validation_rules: [r for r in stage_rules if r[rule_type] validation], state_transitions: [r for r in stage_rules if r[rule_type] transition], config_constraints: [r for r in stage_rules if r[rule_type] config] } return sections3.3 可追溯性的三个锚点可追溯是这个方案的核心卖点也是我在设计时最花心思的地方。可追溯意味着从 PRD 里的任何一条规则都能追溯到它在代码里的来源反过来代码改动之后也能定位到 PRD 里哪些内容需要更新。我设计了三个追溯锚点。第一个是规则 ID每条规则有唯一 ID这个 ID 在规则 JSON 和 PRD 文档里保持一致。第二个是代码位置每条规则记录它在源代码里的文件路径和行号范围。第三个是版本指纹每次生成 PRD 时记录当时代码的 commit hash这样能知道这份 PRD 对应的是哪个版本的代码。这三个锚点组合起来追溯链路就完整了PRD 里的规则 ID → 规则 JSON 里的 source_location → 源代码的具体行 → 对应版本的 commit。任何一环出问题都能快速定位。{ prd_metadata: { generated_at: 2025-01-15T10:30:00Z, source_commit: a3f8c2d, rule_count: 47, traceability_index: { order_amount_b2b_threshold: { file: order/validators.py, lines: 45-52, commit: a3f8c2d } } } }3.4 生成结果的校验与人工复核环节AI 生成的东西不能直接信这是我在多个项目里反复验证过的教训。所以第二个 Skill 的输出必须经过校验环节。自动校验做三件事检查规则 JSON 的完整性有没有缺字段、检查 PRD 文档的结构章节是否齐全、检查追溯锚点的一致性规则 ID 在两边是否对得上。这三项校验都是程序化的能拦住大部分低级错误。人工复核则聚焦在内容质量上。我会让产品经理重点看规则描述是否准确、业务意图是否理解到位让测试同学重点看边界条件和异常分支是否完整。复核发现的问题反馈回去调整提示词或者补充 few-shot 示例让 Skill 下一轮生成得更好。这个自动校验加人工复核的闭环是保证 PRD 质量的关键。纯自动生成适合做初稿但最终定稿一定要有人把关。4. 两个 Skill 串起来之后的实际运行效果4.1 一次完整的生成流程演示说了这么多设计来看一次实际的运行流程。假设我们刚改完订单模块的代码需要更新 PRD。第一步触发rule_extractorSkill。输入是订单模块的几个核心文件validators.py、state_machine.py、config.py。Skill 跑完输出一份规则 JSON包含 47 条规则其中校验规则 23 条、状态转移 12 条、配置约束 8 条、业务意图 4 条。第二步人工快速过一遍规则 JSON。重点看置信度标注为 medium 和 low 的规则这次有 5 条需要复核其中 2 条 AI 理解有偏差手动修正。第三步触发prd_rendererSkill。输入是修正后的规则 JSON 和 PRD 模板配置。Skill 输出一份完整的 PRD 文档Markdown 格式包含所有章节和追溯信息。第四步自动校验加人工复核。自动校验通过人工复核发现状态流转图里少了一个异常分支补充之后重新生成。整个流程走下来从代码改动到 PRD 更新大概花了四十分钟。对比之前纯手工写 PRD 动辄半天的效率提升还是很明显的。4.2 生成质量的数据观察跑了一个多月积累了二十多次生成记录我统计了一下质量数据。规则抽取的准确率按置信度分层看high 置信度的规则准确率在 96% 左右medium 在 82% 左右low 在 60% 左右。这个分布符合预期也验证了置信度标注的有效性——它确实能把不确定的规则筛出来。PRD 文档的可用性我让产品经理和测试同学做了主观评分。结构完整性评分 4.5/5内容准确性评分 4.2/5可读性评分 4.0/5。扣分主要在可读性上AI 生成的文字有时候还是偏机械需要人工润色。追溯功能的实际使用频率超出我预期。代码 review 的时候开发会直接查 PRD 里的规则来源确认改动影响范围。测试写用例的时候也会顺着追溯链路去看代码实现理解边界条件。这个功能成了整个方案里被使用最多的部分。4.3 哪些场景下这套方案特别香用下来这套方案在几类场景下价值特别突出。业务规则密集且频繁变更的系统。比如交易、结算、风控这类系统规则多、改得勤手工维护 PRD 根本跟不上。用 Skill 自动生成每次代码改动后重新跑一遍PRD 始终和代码同步。多人协作、交接频繁的团队。新人接手项目最痛苦的就是理不清业务规则。有了可追溯的 PRD新人可以顺着规则来源去看代码理解速度快很多。需要审计和合规的场景。有些业务需要证明系统行为符合业务规则可追溯的 PRD 就是最好的证据。每条规则都能追到代码每个代码改动都能追到 PRD 更新记录。反过来如果业务规则很简单、变更很少或者团队规模很小、沟通成本本来就低这套方案的投入产出比就没那么高。工具要匹配场景不能为了用而用。5. 实操中踩过的坑和对应的解法5.1 AI 把工具代码误判成业务规则这是最早踩的坑。rule_extractor第一次跑的时候把日志打印、参数格式化这些工具代码也当成业务规则抽出来了输出里混了一堆记录订单日志格式化金额显示这种根本不是业务规则的东西。根因是 Skill 没有区分业务代码和工具代码。解法是在输入契约里加了rule_scope字段并且在提示词里明确说明只抽取与业务逻辑相关的规则忽略日志、格式化、序列化等工具性代码。同时语法层解析的时候加了一个过滤规则函数名里包含log、format、serialize、parse这类关键词的直接跳过。这个坑的教训是AI 不会自动区分什么重要什么不重要你得明确告诉它。输入契约里的 scope 定义比事后过滤有效得多。5.2 状态转移规则抽取不完整状态机是我们系统的核心但rule_extractor一开始抽出来的状态转移规则总是缺几条。排查发现状态转移的定义方式有好几种有的是字典字面量有的是枚举类有的是数据库配置。Skill 只识别了字典字面量这一种。解法是扩展语法层的识别逻辑把枚举类和数据库配置也纳入解析范围。枚举类通过ast识别Enum子类数据库配置则通过读取配置文件来获取。同时在提示词里补充了这几种定义方式的 few-shot 示例让 AI 知道状态转移可能以多种形式出现。这个坑提醒我代码里的同一种业务概念可能有多种实现形式。设计 Skill 的时候要把这些形式都考虑到否则抽取结果就是残缺的。5.3 生成的 PRD 里规则描述太技术化第一版生成的 PRD规则描述写得很技术化比如当 order.type 字段值为 B2B 且 order.amount 字段值大于 10000 时调用 manual_review 服务。产品经理看了直摇头说这不是 PRD这是代码注释。根因是提示词里没有强调面向业务读者这个要求。解法是在prd_renderer的提示词里加了明确的角色设定你是一个资深产品经理面向业务读者撰写 PRD避免使用代码变量名和技术术语用业务语言描述规则。改完之后同样的规则被描述成B2B 类型订单金额超过一万元时系统自动提交人工审核。这个描述产品经理和运营都能看懂。5.4 追溯锚点在代码重构后失效代码重构是常态但重构之后行号会变追溯锚点里的行号就对不上了。这个问题困扰了我一阵子。解法是把追溯锚点从行号改成函数名加规则特征。行号会变但函数名相对稳定规则特征比如条件表达式的关键部分也不容易变。追溯的时候先用函数名定位到函数再用规则特征在函数内定位具体位置。这样即使代码重构追溯链路也不会断。def resolve_traceability(anchor, source_code): # 先用函数名定位 func_node find_function(source_code, anchor[function_name]) if not func_node: return None # 再用规则特征在函数内定位 for node in ast.walk(func_node): if matches_feature(node, anchor[rule_feature]): return node.lineno return None5.5 大文件处理时的上下文超限有个核心业务文件有三千多行直接塞给 AI 会超出上下文窗口。解法是分块处理先按函数边界把文件切成多个块每块单独送给 AI 分析最后把结果合并。分块的时候要注意保持函数的完整性不能把一个函数从中间切开。分块处理还带来一个额外好处可以并行处理多个块速度更快。我用 Python 的concurrent.futures做了并行化三千行的文件处理时间从原来的三分钟降到了四十秒左右。6. 关于 Skill 设计和 AI Agent 落地的一些个人体会这套方案跑下来我对 AI Agent 的 Skill 设计有了些更具体的认识分享几条我觉得最有价值的。Skill 的边界要清晰职责要单一。我一开始想把抽取和渲染做成一个 Skill结果提示词越写越长AI 的输出越来越不稳定。拆成两个 Skill 之后每个 Skill 的提示词都短了很多输出质量反而上去了。一个 Skill 只做一件事做好一件事这个原则在 AI Agent 开发里同样适用。确定性工作交给程序不确定性工作交给 AI。这是我在整个方案里贯彻最彻底的一条原则。语法解析、格式校验、追溯锚点管理这些都是确定性的用程序做又快又准。语义理解、自然语言生成这些是不确定性的交给 AI。两者结合才能既稳定又灵活。输入契约的设计比提示词技巧更重要。我花在输入契约设计上的时间比花在提示词调优上的时间多得多。事实证明这个投入是值得的。清晰的输入契约能让 AI 的输出质量提升一个档次而且更稳定。人工复核环节不能省。AI 生成的内容无论准确率多高都需要人工把关。这不是对 AI 不信任而是对业务负责。我的做法是把人工复核聚焦在 AI 不确定的部分低置信度规则和高风险部分核心业务规则这样既保证了质量又控制了人工成本。可追溯性是 AI 生成内容可信度的基石。AI 生成的东西最怕的就是不知道它从哪来、为什么这么写。有了可追溯性每一条生成内容都能找到来源和依据可信度就上来了。这个思路不仅适用于 PRD 生成任何 AI 生成内容的场景都值得借鉴。最后说个实际的这套方案我目前只在订单和结算两个模块落地了其他模块还在逐步推广。推广过程中最大的阻力不是技术而是习惯——大家习惯了手工写 PRD对 AI 生成的东西有天然的不信任。我的做法是先在小范围跑通用实际效果说话等大家看到效率提升和追溯带来的便利接受度自然就上来了。技术方案落地从来都不只是技术问题。