【Agent】AI编程工程化实践 ------ Context上下文工程,SDD规范驱动开发,MCP&Skills
文章目录
-
- [1、Context Engineering --- 真正的护城河](#1、Context Engineering — 真正的护城河)
- [2、Spec ------ SDD 规范驱动开发,把不确定性压到前面](#2、Spec —— SDD 规范驱动开发,把不确定性压到前面)
-
- [2.1 SDD 核心理念](#2.1 SDD 核心理念)
- [2.2 SDD 工程实践,提示词精确度](#2.2 SDD 工程实践,提示词精确度)
- [3、MCP & Skills ------ AI编程的工具与能力层](#3、MCP & Skills —— AI编程的工具与能力层)
-
- [3.1 MCP 工具](#3.1 MCP 工具)
- [3.2 Skills 从"工具调用"到"业务Context 封装"](#3.2 Skills 从“工具调用”到“业务Context 封装”)
1、Context Engineering --- 真正的护城河
在AI编程里,模型能力会持续升级,但团队之间真正的差距,往往来自上下文工程。所谓Context Engineering,不是把所有文件都塞给AI,而是把"当前任务最需要的信息"按优先级、结构和验证方式交给模型。它决定了Agent是在真实工程环境里工作,还是在模糊描述里猜代码。
一个可落地的判断标准是:如果把同一个任务交给不同Agent,只要它们读取同一份上下文、遵守同一套规则、运行同一组验证,就能得到方向一致、质量可控的结果,那么上下文工程就是有效的。
1.1 why it work? ------ 理解LLM的本质
LLM的基本机制是"基于已有文本预测下一个token"。这句话听起来简单,但对AI编程非常关键:模型不是天然理解你的项目,而是根据它当前看见的输入、工具返回、代码片段和自己已经生成的内容,持续生成后续输出。因此,Prompt、代码、日志、测试结果、规范文档都会成为模型推理的一部分。
从这个机制出发,可以得到几个工程结论:
- 上下文就是模型的工作现场。模型没有独立于上下文之外的项目记忆。如果仓库结构、业务术语、历史约定、接口兼容要求没有出现,它就只能用通用经验补全。
- 推理依赖中间状态。让Agent先读代码、列假设、拆任务、再实现,本质上是在构造更稳定的中间token序列,降低后续生成跑偏的概率。
- 输出具有概率性。工程上不能指望模型每次都"正好懂你",而要用约束、示例、验收标准和测试把可选空间收窄。
- 长任务会遗忘重点。一次修改跨越多个文件、多轮工具调用、多次失败重试时,早期约束容易被淹没,需要用计划、状态摘要、检查清单把重点拉回工作区。
在Coding Agent场景里,最常见的问题不是"模型不会写代码",而是"模型基于错误假设写了很多代码"。比如你说"给订单加导出功能",模型可能默认导出全部订单、默认CSV、默认同步下载、默认普通用户也能导出、默认字段来自前端列表。但真实项目里可能要求只导出当前筛选结果、异步生成XLSX、管理员权限、字段遵守财务口径、生成操作审计日志。缺失的上下文越多,模型猜测越多。
因此,给Agent任务时要尽量把"猜测空间"变成"决策空间"。不要只说:
text
帮我实现订单导出。
更好的输入是:
text
目标:在订单管理页增加导出功能。
范围:只导出当前筛选条件下的订单,不导出全量。
格式:xlsx,字段顺序参考 docs/order-export-fields.md。
权限:仅 admin 和 finance 角色可见按钮并可调用接口。
性能:超过 5000 条时走异步任务,前端展示任务状态。
兼容:不要修改现有 /api/orders 查询接口的返回结构。
验证:补充权限测试、字段映射测试、超过阈值的异步测试。
这不是"提示词变长",而是把模型必须知道的决策点前置。LLM越强,越能利用这些约束;但如果约束缺失,强模型也只是更自信地猜。
一个实用原则是"三层上下文":
- 任务上下文:这次要做什么、为什么做、完成标准是什么。
- 工程上下文:现有代码模式、技术栈、测试命令、目录边界、依赖约束。
- 反馈上下文:运行结果、错误日志、失败测试、人工审查意见。
Agent的工作质量,取决于这三层是否形成闭环。只给任务不给工程上下文,容易写出不符合项目风格的代码;只给工程上下文不给完成标准,容易做多或做偏;只写代码不反馈测试结果,错误就无法收敛。
可以把Agent工作流压缩成一个简单状态机:
text
Understand -> Explore -> Plan -> Implement -> Verify -> Summarize
^ | |
| v v
+------ clarify <----- failure --- review
真正的上下文工程,就是让每个状态都有清晰输入和输出。Explore阶段输出影响面,Plan阶段输出修改路径,Verify阶段输出测试证据。这样,模型不是一次性"生成答案",而是在工程反馈中逐步收敛。
1.2 上下文工程 ------ Agent.md
所有AI编程工具都有上下文窗口,可以理解为模型的工作记忆。窗口大不等于效果好,关键是上下文密度。高密度上下文包含当前任务所需的事实、约束和验证方式;低密度上下文则充满过期文档、无关代码、重复日志和泛泛要求。上下文工程的目标,是让token花在决策点上。
可把上下文分成四类:
| 类型 | 内容 | 例子 | 维护方式 |
|---|---|---|---|
| 全局上下文 | 仓库级规则 | 技术栈、启动命令、测试命令、代码规范 | 根目录 AGENTS.md / Agent.md |
| 模块上下文 | 局部业务规则 | 订单状态机、支付回调约束、权限模型 | 模块目录 README 或 design doc |
| 任务上下文 | 本次需求和验收 | 目标、范围、非目标、验收标准 | issue、spec、prompt |
| 反馈上下文 | 执行结果 | 测试失败、日志、截图、review意见 | Agent运行记录、CI、报告 |
Agent.md适合承载全局上下文。它不需要写成项目百科,而要写成Agent工作手册,重点回答"在这个仓库里怎么安全地做事"。一个更干货的模板如下:
md
Agent Guide
Project:
- Runtime: Node.js 20, pnpm
- Framework: Next.js + NestJS
- Package manager: only pnpm, do not use npm/yarn
Commands:
- Install: pnpm install
- Dev: pnpm dev
- Type check: pnpm typecheck
- Unit test: pnpm test
- E2E: pnpm e2e
Architecture Rules:
- API types live in `packages/contracts`
- Frontend must not import server-only modules
- Database writes must go through `OrderService`, not repository directly
Coding Rules:
- Reuse existing UI components in `src/components/ui`
- Do not add dependencies without explaining why
- Keep public API backward compatible unless spec says otherwise
Verification:
- For API changes: run unit tests + contract tests
- For UI changes: run typecheck + screenshot check
- For migrations: include rollback notes
Known Pitfalls:
- `order.status = PAID` does not mean fulfillment completed
- `tenantId` must be included in all order queries
模块级上下文可以更贴近业务。比如订单模块可以维护:
md
Order Module Notes
State Machine:
CREATED -> PAID -> FULFILLED -> CLOSED
CREATED -> CANCELLED
PAID -> REFUNDED
Invariants:
- paid orders cannot be deleted
- refund must create an audit record
- all queries must include tenantId
Tests:
- state transitions: `pnpm test order-state`
- export behavior: `pnpm test order-export`
上下文不是一次性文档,而是运行时策略。做任务时,可以按以下顺序收集信息:
- 读全局规则:确认命令、技术栈、禁止事项。
- 搜索入口:用关键词找到路由、组件、服务、测试。
- 读相邻实现:优先模仿同类功能,而不是凭空设计。
- 找验证口:确认测试文件、类型检查、启动方式。
- 写任务状态:记录已确认事实、待确认问题、风险点。
一个可直接给Agent的任务上下文模板:
md
Task:
实现/修复:
Background:
当前行为:
期望行为:
Scope:
In:
-
Out:
-
Constraints:
- 不改动:
- 必须复用:
- 兼容要求:
Acceptance Criteria:
- [ ]
- [ ]
Verification:
- 命令:
- 手工检查:
上下文压缩也很重要。长任务中,不要让早期探索结果无限堆积,可以定期把工作状态压缩成:
text
Confirmed:
- Export endpoint is `POST /api/orders/export`
- Existing permission helper is `canExportOrders(user)`
Changed:
- Added async export task when count > 5000
Open:
- Need confirm whether finance role can export refunded orders
Verify:
- pnpm test order-export
- pnpm typecheck
高质量上下文有三个特征:短、准、可验证。短,意味着不把无关信息塞进窗口;准,意味着过期规则及时删除;可验证,意味着每个重要约束都能落到命令、测试、截图或人工检查上。上下文工程最终不是文档工作,而是把AI编程从"凭感觉生成"变成"按证据执行"。
2、Spec ------ SDD 规范驱动开发,把不确定性压到前面
AI编程最大的风险通常不是"写不出来",而是"写出来的不是你真正要的"。SDD的核心价值,是把需求、边界、接口、验收标准前置,让AI在明确契约下实现,而不是在模糊描述里发挥。
Spec不是形式主义文档,而是AI协作的源头上下文。它越清晰,后面计划、任务拆解、代码生成、测试验证就越稳定。
2.1 SDD 核心理念
SDD,Spec-Driven Development,强调先写规格,再写代码。它与"先让AI生成一版看看"的区别在于:Vibe Coding追求快速产出,SDD追求可控交付。原型阶段可以随意一点,但进入团队研发、核心业务、多人协作或高风险改动时,必须把不确定性提前暴露。
SDD可以理解为四段式:
text
Specify -> Plan -> Tasks -> Implement
规格 方案 任务拆解 编码与验证
每一段都有明确产物:
| 阶段 | 产物 | 主要问题 | 人的职责 | AI的职责 |
|---|---|---|---|---|
| Specify | 需求规格 | 要做什么,边界在哪 | 定义业务目标和取舍 | 整理规格、发现歧义 |
| Plan | 技术方案 | 怎么做,影响哪些模块 | 审查架构和风险 | 找代码、给方案、列风险 |
| Tasks | 任务清单 | 先做什么,如何验收 | 确认优先级 | 拆分步骤和验证点 |
| Implement | 代码和测试 | 是否满足规格 | review和验收 | 实现、测试、修复 |
SDD的第一个原则是"Spec是契约,不是说明书"。说明书可以宽泛,契约必须可判断。比如"导出体验要好"不是契约,"点击导出后3秒内出现任务创建反馈,任务完成后可下载xlsx文件,失败时展示失败原因"才是契约。
第二个原则是"先定义非目标"。很多需求跑偏,不是因为目标没说,而是非目标没说。比如:
md
Non-goals:
- 本期不支持导出历史归档订单
- 本期不改造现有订单查询接口
- 本期不支持自定义字段选择
非目标能显著降低AI过度实现的概率。Agent很容易"顺手"重构、补抽象、加配置、改接口;非目标就是刹车。
第三个原则是"验收标准要能变成测试"。可以用Given-When-Then写法:
md
Given 当前用户是 finance 角色
And 订单列表筛选条件为 status=PAID
When 用户点击导出
Then 系统创建一个异步导出任务
And 导出的文件只包含 PAID 订单
And 文件字段顺序与 `docs/order-export-fields.md` 一致
这种格式的好处是,它天然接近测试用例。AI可以据此生成单元测试、集成测试或E2E测试,人也能快速判断有没有遗漏。
第四个原则是"Spec随代码一起演进"。规格不是写完就锁死。实现过程中发现旧接口不支持、性能成本过高、权限规则冲突,都应该回到Spec修改,而不是在代码里偷偷绕开。否则代码和规格很快分裂,后续Agent再基于旧Spec工作时会继续犯错。
一个最小可用Spec模板:
md
Spec: Order Export
Goal:
让管理员和财务人员按当前筛选条件导出订单。
Users:
- admin
- finance
Rules:
- 只导出当前筛选条件命中的订单
- 超过 5000 条时创建异步任务
- 导出必须记录 audit log
API Contract:
POST /api/orders/export
Request: { filters: OrderFilters }
Response: { taskId: string, status: "pending" }
Edge Cases:
- 无权限:403
- 无数据:生成空文件,保留表头
- 任务失败:前端展示失败原因
Acceptance:
- [ ] 权限正确
- [ ] 字段顺序正确
- [ ] 大数据量走异步
- [ ] 有审计日志
SDD并不是要让所有需求都写成长文档,而是按风险匹配规格粒度。低风险任务可以写轻量Spec;涉及数据、权限、支付、迁移、对外API、跨团队协作时,Spec必须更完整。衡量标准很简单:如果AI实现错了,返工成本越高,Spec就越要前置。
2.2 SDD 工程实践,提示词精确度
SDD落地的关键,是把"提示词"升级成"规格生产流程"。不要直接让AI写代码,可以先让它按固定模板输出Spec,并要求它列出歧义点。
推荐流程:
- 用户给出原始需求。
- Agent整理为Spec草案。
- Agent列出必须澄清的问题和默认假设。
- 用户确认或修改。
- Agent生成Plan和Tasks。
- 用户确认后再实现。
- Agent按Acceptance Criteria验证。
一个可复用的SDD启动提示词:
text
你先不要写代码。请根据我的需求产出一份Spec草案,包含:
1. Goal
2. Background
3. In Scope / Out of Scope
4. User Stories
5. Business Rules
6. API/Data Contract
7. Edge Cases
8. Acceptance Criteria
9. Open Questions
要求:
- 对不确定内容不要擅自决定,放到 Open Questions。
- 对低风险细节可以给出 Default Assumption。
- Acceptance Criteria 必须可测试。
当Spec确认后,再进入Plan:
text
基于已确认Spec,请先不要改代码。
请阅读相关代码后输出技术方案:
- 影响文件和模块
- 数据流变化
- 复用的现有模式
- 需要新增/修改的测试
- 风险和回滚方案
- 不建议采用的方案及原因
Plan确认后,拆Tasks:
md
Task:s
- [ ] 找到现有导出/任务队列实现,确认复用方式
- [ ] 增加 export API 的权限校验
- [ ] 增加导出任务创建逻辑
- [ ] 实现字段映射和xlsx生成
- [ ] 前端增加导出按钮和任务状态提示
- [ ] 补充权限、字段、大数据量测试
- [ ] 运行 typecheck/test 并记录结果
提示词精确度可以用"六要素"检查:
| 要素 | 差的写法 | 好的写法 |
|---|---|---|
| 目标 | 优化登录 | 减少登录失败后的重复输入 |
| 范围 | 做完整一点 | 只改登录页和登录API,不改注册 |
| 约束 | 代码优雅 | 复用现有 Form、Toast、AuthService |
| 数据 | 支持筛选 | 支持 status、createdAt、tenantId |
| 边界 | 注意异常 | 401跳登录,403显示无权限,5xx可重试 |
| 验收 | 能用就行 | 给出3个测试用例并全部通过 |
SDD实践中最容易踩的坑:
- 只写功能,不写非目标,导致AI扩大范围。
- 只写正常流程,不写异常流程,导致线上边界失败。
- 只写UI,不写数据契约,导致前后端理解不一致。
- 只写实现任务,不写验证任务,导致交付不可判断。
- Spec确认后继续口头改需求,却不更新Spec。
可以把Spec质量用下面的清单审一遍:
md
Spec Review Checklist:
- [ ] 是否说明了用户和业务目标?
- [ ] 是否明确 In Scope / Out of Scope?
- [ ] 是否有 API 或数据结构契约?
- [ ] 是否覆盖权限、空数据、错误、并发/大数据量?
- [ ] 是否定义了可测试的验收标准?
- [ ] 是否说明不允许改动的兼容边界?
- [ ] 是否能直接拆成开发任务?
最终交付时,也让Agent按Spec回填结果:
md
Delivery Report:
- Implemented:
- Changed Files:
- Acceptance Criteria:
- [x] ...
- Verification:
- `pnpm test order-export`: passed
- `pnpm typecheck`: passed
- Risks:
- Follow-ups:
这样,SDD就不只是"写文档",而是把需求、实现、测试、交付报告串成同一条线。AI生成速度越快,这条线越重要;否则团队只会更快地制造返工。
3、MCP & Skills ------ AI编程的工具与能力层
当AI进入真实研发流程,它不能只靠聊天窗口。它需要读取文件、搜索代码、运行命令、访问设计稿、查询日志、检查CI。MCP和Skills分别解决两个层面的问题:MCP让Agent能标准化使用工具,Skills让Agent按团队沉淀的方法完成任务。
3.1 MCP 工具
MCP,Model Context Protocol,可以理解为模型和外部工具之间的标准接口。它把"资源读取"和"工具调用"抽象出来,让AI客户端可以用统一方式连接文件系统、Git、数据库、浏览器、Figma、日志平台、内部系统等能力。
对AI编程来说,MCP最直接的收益是减少复制粘贴,让模型接触实时事实。比如:
| 场景 | 没有MCP | 有MCP |
|---|---|---|
| 查代码 | 用户手动贴片段 | Agent搜索仓库并打开文件 |
| 查设计 | 用户截图描述 | Agent读取Figma节点和变量 |
| 查数据库 | 用户转述schema | Agent查询只读schema |
| 查错误 | 用户贴部分日志 | Agent检索完整trace |
| 验证页面 | 用户肉眼看 | Agent打开浏览器截图检查 |
一个MCP Server通常会暴露三类能力:
text
Resources: 可读取的上下文
- file://src/order/service.ts
- docs://payment/refund-policy
- db-schema://orders
Tools: 可执行的操作
- search_code(query)
- run_tests(pattern)
- query_logs(traceId)
- get_figma_node(nodeId)
Prompts: 可复用的任务提示
- review_api_change
- generate_migration_plan
工程上接入MCP,不建议一开始就追求"大而全"。更好的顺序是从低风险、高频场景开始:
- 代码检索:搜索文件、读取文件、查看diff。
- 文档检索:读取架构文档、接口文档、业务规则。
- 只读查询:数据库schema、日志、监控、CI结果。
- 本地验证:运行测试、类型检查、lint。
- 高风险操作:发布、写数据库、改配置,必须加确认和审计。
MCP设计时要重点关注权限。一个好用的工具不只是"能做事",还要"做事边界清楚"。建议按风险分级:
yaml
tools:
read_file:
risk: low
approval: never
run_tests:
risk: low
approval: never
query_prod_logs:
risk: medium
approval: on_sensitive_query
deploy_service:
risk: high
approval: always
execute_sql:
risk: high
approval: always
allowlist:
- SELECT
MCP工具命名和返回格式也会影响Agent效果。工具名要表达语义,不要只暴露底层API。比如 getOrderExportSpec(orderType) 比 httpGet(url) 更容易让模型正确使用。返回结果要结构化,避免把大段无关文本塞回上下文:
json
{
"status": "failed",
"command": "pnpm test order-export",
"summary": "2 failed, 18 passed",
"failures": [
{
"test": "finance can export paid orders",
"reason": "expected 200, received 403",
"file": "order-export.test.ts"
}
]
}
落地MCP时,可以用这份检查清单:
md
MCP Checklist:
- [ ] 工具是否有明确名称和描述?
- [ ] 输入参数是否有schema和示例?
- [ ] 输出是否结构化、可被Agent继续使用?
- [ ] 是否限制了访问范围?
- [ ] 高风险操作是否需要确认?
- [ ] 是否记录调用日志和调用人?
- [ ] 失败信息是否能指导下一步?
MCP不是让AI"拥有更多权限",而是让AI在明确权限内接触事实、调用工具、获得反馈。没有治理的工具调用会放大风险;有边界、有审计、有验证的MCP,才是企业AI编程的基础设施。
3.2 Skills 从"工具调用"到"业务Context 封装"
MCP解决"能调用什么工具",Skills解决"遇到某类任务应该怎么做"。工具调用是能力点,Skill是工作流。一个好的Skill会把任务识别、上下文获取、执行步骤、验证方式和注意事项封装起来,让Agent复用团队最佳实践。
可以把Skill理解成"可执行的经验文档"。它不是一句"请写高质量代码",而应该像下面这样具体:
md
Skill: implement-admin-list-page
When to use:
- 新增后台管理列表页
- 修改已有列表页的筛选、表格、批量操作
Context to collect:
- 路由配置
- 同类列表页实现
- API contract
- 权限配置
- UI组件库用法
Steps:
1. 找到最相似的已有列表页
2. 复用页面布局、Table、FilterForm、Pagination
3. 对齐API字段和前端类型
4. 增加空状态、加载态、错误态
5. 补充权限控制和测试
Verification:
- pnpm typecheck
- pnpm test admin-list
- 浏览器检查桌面和移动端布局
Skill与普通文档的区别,在于它面向Agent执行。它要告诉Agent"先看哪里、复用什么、避免什么、如何验证"。尤其在企业项目里,很多关键知识不是框架通用知识,而是团队约定:按钮权限怎么配、错误码怎么翻译、审计日志怎么写、租户ID从哪里取、哪些服务不能直接调用。
一个成熟Skill通常包含五个部分:
| 部分 | 作用 | 示例 |
|---|---|---|
| Trigger | 什么时候使用 | "涉及支付回调时使用" |
| Context | 需要收集什么 | API文档、状态机、日志样例 |
| Procedure | 怎么执行 | 先补测试,再改服务,再验证 |
| Constraints | 禁止/必须事项 | 不直接写DB,必须记录audit |
| Verification | 如何验收 | 单测、集成测试、回放日志 |
以"修复线上Bug"为例,Skill可以这样设计:
md
Skill: production-bugfix
Procedure:
1. 收集错误信息:traceId、版本号、时间范围、用户影响面
2. 查最近变更:git log、release notes、相关PR
3. 定位代码路径:日志关键词、接口路由、服务方法
4. 先写复现测试:用失败用例锁定问题
5. 做最小修复:避免顺手重构
6. 跑回归验证:相关测试 + 类型检查
7. 输出风险说明:影响范围、回滚方式、是否需补数据
Rules:
- 不在未复现前做大范围重构
- 不修改无关格式
- 涉及数据修复必须单独出脚本和回滚方案
Skills和MCP的组合方式是:Skill编排流程,MCP提供工具。比如生产Bug修复Skill可能调用日志MCP查trace,调用Git MCP查最近变更,调用文件系统MCP读代码,调用测试工具运行回归。没有Skill,Agent可能会随意调用工具;没有MCP,Skill只能停留在建议。二者结合后,AI才像一个遵守团队流程的工程助手。
设计Skill时要避免两个问题:
- 太抽象:只写"遵守最佳实践""保证安全可靠",Agent无法执行。
- 太僵硬:把文件路径、字段、流程全部写死,项目一变就失效。
更好的写法是"稳定规则写死,可变信息让Agent查证"。例如:
md
Stable Rules:
- 所有订单查询必须带 tenantId
- 支付回调必须幂等
- 对外API字段不能删除,只能兼容新增
Dynamic Lookup:
- 具体路由请搜索 `orderRoutes`
- 同类测试请搜索 `*.order-export.test.ts`
- UI组件优先参考最近3个月新增的后台页面
Skill也需要版本化和复盘。每次Agent在某类任务上失败,都应该反向更新Skill:是少了上下文?少了禁止事项?验证命令不完整?工具返回不清晰?这样Skill会从"经验记录"变成"组织能力资产"。
最终,一个团队的AI工程体系可以这样分层:
text
Model : 通用推理和生成能力
Context : 项目事实、任务目标、约束和反馈
Spec : 需求契约和验收标准
MCP : 工具与外部系统连接
Skills : 可复用任务工作流
Verification: 测试、CI、截图、审查
这套分层的重点不是追求复杂,而是让AI每次工作都能回答四个问题:我该看什么?我该按什么规则做?我能调用什么工具?我怎么证明做对了?能稳定回答这四个问题,AI编程就从"尝试一下"进入了工程化阶段。
参考资料:
Agent.md
trae 2026 企业级AI编程实践手册
千问云-SDD编程
awesome-design-md
ai编程工具