news 2026/5/28 22:52:01

用Skill 管理项目文档:让 Code Agent 读懂你的业务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Skill 管理项目文档:让 Code Agent 读懂你的业务

用 Codex Skill 管理项目文档:让 Code Agent 读懂你的业务

Code Agent 的上限不在模型能力,而在你的仓库里有没有它能读懂的知识。


目录

  • Agent 为什么会把需求做烂
  • 为什么选 Skill 而不是 MCP 或 SDD
  • NVC Practice 的知识架构全景
  • 第一层:repo-map 做路由
  • 第二层:7 个 Skill 覆盖全部业务域
  • 第三层:References 按需展开
  • 渐进式披露的上下文经济学
  • 从"有什么知识"到"怎么用知识"
  • 防腐化:让知识不会越用越错
  • 实操建议

Agent 为什么会把需求做烂

NVC Practice 是一个基于非暴力沟通理论的 AI 练习平台,用户选择场景后和 AI 角色扮演对话,系统按 NVC 四步法(观察→感受→需要→请求)实时评分。后端用 Spring Boot 4 + Spring AI 2.0,涉及多 Agent 协同评分、RAG 知识库检索、场景关卡引擎等模块。

项目不大,但业务耦合度不低。刚开始用 Code Agent 做需求时碰到一个问题:改练习评分逻辑,Agent 找到了评分引擎的代码,按"每个维度独立打分"的思路写了一段实现。看起来没毛病,但它不知道这个项目里 NVC 四步评分不是孤立的——观察、感受、需要、请求四个维度之间有依赖关系:如果用户根本没表达感受,那"需要"和"请求"的评分权重应该降权而不是独立计算。这个规则写在 PRD 里,没写在代码注释里,Agent 自己翻不到。

类似的坑不止一个。练习会话有"闯关"和"自由练习"两种模式,状态机不同;场景关卡的解锁依赖前置场景的通过,但解锁逻辑散落在ScenarioServicePracticeSessionService两个类里;sessionId在练习域和用户画像域里含义不同,混用会导致数据归属错误。

这些问题的根因一样:领域知识没有被结构化地记录在仓库里。代码告诉你"怎么做",但说不清"为什么这样做"、“哪些约束不能碰”。

参考阿里妈妈团队在 AI Coding 实践中的总结——Code Agent 在复杂项目中撞墙,根因是人读不到的知识,Agent 也读不到。NVC Practice 的做法是把项目知识写进仓库,用 Codex Skill 作为载体。


为什么选 Skill 而不是 MCP 或 SDD

MCP 接外部文档

试过,效果不好。项目文档本身有大量过时内容,而且缺乏结构化组织,一次读取直接撑爆上下文窗口。

** SDD(Spec-Driven Development)** 也考虑过。从零开始的新项目用 SDD 效果不错,但 NVC Practice 是持续迭代的存量项目——一个两三百行的代码改动,spec 要写五六百行,维护成本倒挂。spec 随用随弃,知识不累积。

Skill 的渐进式披露机制天然适合这个场景:元数据常驻用于路由判断,主文件按需加载,引用详情延迟读取。“大量知识但每次只需要一部分”——这正好是复杂项目里 Agent 的工作模式。


NVC Practice 的知识架构全景

整个知识体系分三层,对应 Agent 拿到需求后的认知路径:

第一层:AGENTS.md + repo-map Skill(全局索引与路由) ↓ 读完这层,Agent 知道该去哪个业务域 第二层:6 个业务域 Skill(模块核心知识) ↓ 读完这层,Agent 理解业务语义和代码结构 第三层:references/ 目录下的详情文件(按需展开) Agent 判断需要更多信息时才读

加上一个跨域术语字典 Skill,总共 7 个 Skill、约 30 个引用文件。下面逐层展开。


第一层:repo-map 做路由

AGENTS.md是 Agent 拿到需求后读的第一个文件,Token 消耗很少,但完成最关键的决策:我应该读哪个模块的知识。

nvc-repo-mapSkill 承担路由层。核心是一张需求关键词到业务域的映射表:

"登录、注册、token、当前用户、权限" → nvc-auth-user "画像、MBTI、沟通风格、用户分析" → nvc-profile-domain "场景、关卡、解锁、专题、进度" → nvc-scenario-domain "练习、对话、轮次、闯关、自由模式" → nvc-practice-domain "NVC 评分、四步法、维度打分、雷达图" → nvc-scoring-engine "知识库、RAG、文档上传、向量检索" → nvc-knowledge-base "接口、DTO、配置一起改、跨模块" → nvc-change-playbook

附带反面判定规则,防止误路由:

  • "看起来像对话"不一定归练习域——如果它涉及场景解锁逻辑,主域是场景
  • "看起来像评分"不一定归评分引擎——如果它涉及练习会话的状态推进,主域是练习
  • "看起来像用户"不一定归用户模块——如果它涉及画像分析和 MBTI 推断,主域是画像

第二层:7 个 Skill 覆盖全部业务域

每个 Skill 是一个 SKILL.md 主文件加上一组 references/ 引用文件。主文件控制在 3000 字以内,覆盖四个维度。

业务域 Skills

nvc-practice-domain为例:

路由判定

:需求命中练习会话创建、对话轮次推进、闯关/自由模式切换、练习报告生成时使用。

使用顺序

:先看lifecycle.md确认会话处于哪个阶段,再看round-pipeline.md确认单轮对话的完整流程,改状态推进时看state-machine.md,改报告生成时看practice-report.md

关键入口

:直接列出代码入口的完整路径——

app/src/main/java/nvc/practice/modules/practice/api/PracticeController.java app/src/main/java/nvc/practice/modules/practice/service/PracticeSessionService.java app/src/main/java/nvc/practice/modules/practice/service/PracticeRoundService.java app/src/main/java/nvc/practice/modules/practice/service/PracticeReportService.java

必守约束

  • 练习会话的"闯关模式"和"自由练习"是两套状态机,不要混写
  • 一轮对话里 AI 的回复和用户的回复必须成对存在,不能只存一半
  • 练习报告的雷达图数据来源于每轮评分的维度均值,不是最后一轮的分数
  • 闯关模式下,只有当轮评分全部达标才能解锁下一轮,不能跳过

评分引擎 Skill

nvc-scoring-engine是项目里最复杂的模块。主文件要覆盖:

四步评分的依赖关系

:观察→感受→需要→请求不是四次独立调用。如果用户没表达感受,需要和请求的评分应该降权。评分引擎内部有一个NvcDependencyGraph定义维度间的依赖关系。

Multi-Agent 编排

:5 个 Agent(观察官、感受官、需要官、请求官、综合官)的执行顺序和并行策略。观察官和感受官可以并行,但需要官必须等感受官的结果。

结构化输出契约

:每个 Agent 返回的 JSON 结构、评分范围(0-10)、反馈字段格式,必须和前端的雷达图组件对齐。

跨域支撑 Skills

nvc-change-playbook:当改动同时涉及接口、DTO、评分逻辑和数据库表结构时,提供影响检查清单和回滚策略。


第三层:References 按需展开

nvc-practice-domain为例,引用文件覆盖练习生命周期的每个切面:

文件内容
lifecycle.md会话状态(CREATED → IN_PROGRESS → COMPLETED / ABANDONED)和推进链路
round-pipeline.md单轮对话执行顺序:幂等检查 → AI 生成回复 → 用户回复 → 四步评分 → 推进轮次
state-machine.md闯关模式和自由练习两套状态机的完整定义
practice-report.md报告生成逻辑:维度均值计算、雷达图数据结构、AI 总结生成
gotchas.md易错点:sessionId 归属校验、轮次编号连续性、评分回滚

Agent 不会一开始就加载全部文件。改评分逻辑只读round-pipeline.md,改状态推进只读state-machine.md


渐进式披露的上下文经济学

Skill 的三级加载设计直接决定了上下文消耗:

层级何时加载Token 消耗作用
元数据(name + description)始终可见~100 字路由判断:这个 Skill 跟当前需求有关吗?
主文件正文(SKILL.md)Skill 被触发时~3000 字理解业务语义、代码结构、制定方案
引用详情(references/)Agent 判断需要时按需展开具体流程、API 定义、易错点

对比"把所有知识塞进一个大 prompt",渐进式披露让 Agent 在合适的时机获取正确的知识。上下文窗口不会被撑爆,注意力不会被无关信息稀释。


从"有什么知识"到"怎么用知识"

NVC Practice 的 Skills 经历了一轮关键迭代。

最初版本只写了业务规则,没有标注这些规则对应代码中的哪些流程。Agent 需要自行推理"这条规则大概和哪段代码有关"——大部分时候能猜对,但准确率不稳定。比如它知道"NVC 评分要考虑维度间的依赖",但不知道这个依赖关系定义在NvcDependencyGraph里,可能会去改NvcScoreService的打分逻辑而不是调整依赖图。

改进后,每个 Skill 的主文件直接列出关键入口的完整代码路径,引用文件中的每条业务规则都标注了对应的代码位置。round-pipeline.md里写的不是"评分前要检查依赖关系",而是:

1. 调 NvcDependencyGraph.resolveDependentDimensions(currentDim) 获取前置维度 2. 检查前置维度的评分是否已产出,未产出则标记为降权 3. 调 ObservationAgent / FeelingAgent / NeedAgent / RequestAgent 分别评分 4. 调 SummaryAgent 汇总,生成结构化评分结果 5. 成功后写入 practice_turn 表,失败则回滚本轮状态

Agent 读完这层,不需要猜,直接知道改哪里。


防腐化:让知识不会越用越错

过时的知识比没有知识更危险。当 Skill 文件说评分流程是 A→B→C,而实际代码已经改成了 A→C,Agent 会按错误流程写代码,而且不会怀疑知识的正确性。

使用时反向校验

Agent 读完 Skill 再去看实际代码时,天然处于一个能交叉比对的位置。发现知识描述和代码现状不一致,就在输出方案的同时标注差异。几乎没有额外成本——Agent 本来就要读知识、读代码,比对只是顺带完成。

变更时同步更新

nvc-change-playbook的主文件里有一条硬约束:改完评分逻辑或场景配置后,必须检查对应的 Skill 文件是否需要同步更新。nvc-scoring-engine的 scripts 目录下放一个extract_agent_contracts.py,从评分 Agent 的代码中提取输出字段契约。跑一次脚本,生成的契约如果和 Skill 里写的不同,说明知识该更新了。

这套机制不是为了自动化,而是为了在知识和代码之间建一个一致性锚点。


实操建议

从一个模块开始。

NVC Practice 的 7 个 Skill 不需要一次性写完。先写练习域(最复杂的那个),跑通几个真实需求后,再扩展到评分引擎、场景域、画像域。

触发描述比正文更重要。

元数据里的description字段决定了 Agent 会不会读这个 Skill。写得太窄会漏触发,写得太宽会误触发。做法是把触发条件写成"需求命中某个 API 路径或涉及某个业务动作",同时附带反面条件。

统一流程命名。

每段最小划分的业务逻辑确定唯一的流程名词。“单轮对话评分"在练习域、评分引擎域、变更剧本里都叫同一个名字,不叫"轮次评估"也不叫"维度打分”。跨模块推理时 Agent 靠名字匹配关联关系,命名不统一直接导致推理断裂。

把约束写成人话。

比起"评分维度间存在依赖关系,需在评分前解析依赖图","如果用户没说感受,需要和请求的分数要往下降"更容易被 Agent 正确执行。口语化的约束比格式化的规范文档更有效。

脚本是校验锚点,不是替代品。

自动生成的索引文件用来和手工维护的知识交叉比对。两者不一致,以代码为准,更新 Skill。


写在最后

NVC Practice 的 7 个 Skill、约 30 个引用文件,回答的是一个问题:如果明天换一个完全不了解这个项目的人(或 Agent)来改代码,他需要知道什么才能不犯错?

答案不在代码注释里,不在 wiki 里,也不在每次口头交接的记忆里。答案在仓库里,在 Agent 每次动手前能读到的那份结构化知识里。

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

别再手动拖拽了!用Qt的QSplitter实现可拖拽布局,5分钟搞定专业级UI

用QSplitter打造可定制化专业界面:从效率工具到IDE级布局实战每次打开那些优秀的IDE或数据可视化工具,你是否注意到它们窗口分割的丝滑体验?用户能自由调整各个面板的大小,甚至保存自己偏好的布局——这种专业级的交互体验&#x…

作者头像 李华
网站建设 2026/5/28 22:49:04

Activiti 5.22 保姆级入门:从25张表结构到第一个流程实例

Activiti 5.22 实战入门:从零构建请假审批系统在数字化转型浪潮中,工作流引擎已成为企业级应用的核心组件。作为Java领域最成熟的流程引擎之一,Activiti以其轻量级架构和BPMN2.0标准支持,成为众多企业的首选方案。本文将基于5.22版…

作者头像 李华
网站建设 2026/5/28 22:46:08

8086/8088中断栈操作详解

1. 完整压栈过程(从中断触发到当前)第一阶段:硬件自动压栈(中断响应时)当 INT 1 指令执行或单步中断触发时,CPU 自动按顺序压入:顺序压入内容大小SP 变化1FLAGS2 字节SP ← SP - 22CS2 字节SP ←…

作者头像 李华
网站建设 2026/5/28 22:46:05

【C++】零基础入门 · 第 10 节:结构体与类

在前面的章节中,我们学习了变量、数组、函数、指针和动态内存。这些都是 C++ 的基础构件,但随着程序变得越来越复杂,你会发现一个问题:相关的数据散落在各个变量里,传递和管理起来非常麻烦。比如要表示一个学生的信息(姓名、年龄、成绩),你得定义三个独立的变量,每次传…

作者头像 李华
网站建设 2026/5/28 22:44:21

项目介绍 MATLAB实现基于偏最小二乘回归(PLS)进行回归预测(含模型描述及部分示例代码)专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢

MATLAB实现基于偏最小二乘回归(PLS)进行回归预测的详细项目实例项目背景介绍偏最小二乘回归,简称 PLS,是一种兼顾降维、特征提取与回归建模的统计学习方法,在高维、多共线、样本量有限、噪声干扰明显的真实工程场景中具有很高的实用价值。许多…

作者头像 李华