芥末
发布于 2026-05-29 / 2 阅读
1
0

Agentic Engineering:让 AI Agent 可靠参与软件研发的六条实践

Agentic Engineering 可以理解为一套面向 AI Agent(智能体)的软件工程方法。它关心的问题不是“怎样让 AI 多写代码”,而是“怎样让 AI 在需求、设计、编码、测试、审查这些环节里可靠地产生价值”。

把 AI Agent 放进研发流程后,工程师很容易遇到几个问题:

  • AI 写代码很快,但经常偏离真实需求。
  • 项目上下文一多,AI 的回答开始混乱。
  • 测试能通过,但实现方式不符合团队规范。
  • 一次性让 AI 做完整任务,最后需要人花大量时间返工。
  • 团队知识散落在文档、代码评审和人的脑子里,AI 每次都要重新“猜”。

Agentic Engineering 的核心思想是:不要把 AI 当成一个独立替代工程师的黑盒,而要把它当成需要上下文、约束和反馈的工程协作者。

真正重要的不是提示词写得多漂亮,而是把软件工程里的意图、规则、知识和验证机制结构化,让 AI 每一步都在清晰边界内工作。

三个基本判断

1. 软件工程本质上是意图转化链

软件不是从代码开始的。代码只是最终产物。

一个功能从想法变成可运行系统,通常要经过这样的链条:

flowchart LR
    A[模糊业务意图] --> B[需求说明]
    B --> C[技术设计]
    C --> D[编码实现]
    D --> E[测试验证]
    E --> F[上线运行]

    A -.信息损耗.-> B
    B -.信息损耗.-> C
    C -.信息损耗.-> D
    D -.信息损耗.-> E

每一次转化都会损失信息。

业务方脑子里的真实意图,写成需求时会丢掉背景;需求进入设计时,会丢掉一些边界条件;设计进入编码时,会丢掉一些取舍理由;测试阶段能验证行为,却未必能验证设计是否合理。

AI 的出现并不会消灭这条链路,它只是改变了每个环节的损耗方式。

如果只让 AI 在编码阶段介入,前面需求和设计阶段已经丢失的信息很难在代码阶段补回来。越靠源头的偏差,传播得越远,修正成本也越高。

2. LLM 有三个无法绕开的特征

LLM(大语言模型)能力很强,但它不是稳定的编译器,也不是团队成员脑内知识的镜像。它有三个关键特征:

特征含义对工程协作的影响
上下文决定输出它只能根据当前可见信息生成结果没给项目背景、设计约束、团队规范,就不能期待它自动知道
输出具有概率性相同输入也可能生成不同结果需要审查、测试和约束,不能把一次输出当成确定答案
工作记忆有限且易失上下文过长时,重要信息可能被忽略需要分层加载上下文,而不是把所有代码一次性塞进去

这意味着 AI Agent 的可靠性不是靠“模型更聪明”单独解决的。模型再强,只要上下文混乱、规则缺失、任务过大,它仍然容易跑偏。

3. 人的认知带宽才是稀缺资源

AI 可以快速生成代码、文档、测试用例和设计备选方案,但最终仍然需要人判断:

  • 需求是否真实反映业务目标;
  • 技术方案是否符合系统演进方向;
  • 代码是否可维护;
  • 风险是否可接受;
  • 哪些错误必须修,哪些可以延后。

AI 时代的软件研发瓶颈,很多时候不再是“谁来写代码”,而是“谁来审查、判断和决策”。

所以,好的 AI 协作方式不应该制造更多需要人逐行检查的输出,而应该把人的注意力放到高价值位置:需求澄清、设计取舍、关键风险、规则制定和最终决策。

五个常见误区

误区一:把代码全部喂给 AI,它就能理解项目

上下文不是越多越好。

如果把大量无关代码、过期文档、重复片段一起塞进窗口,AI 看到的是噪声。真正有价值的上下文应该满足三个条件:

维度好的上下文差的上下文
相关性与当前任务直接相关把整个仓库无差别塞进去
结构化有模块边界、接口说明、约束条件只有零散文件和聊天记录
可追溯能看出规则来源和适用范围不知道哪些信息可信、哪些已过期

AI 理解项目的前提,不是拥有全部代码,而是获得足够清晰、足够相关、足够结构化的信息。

误区二:AI 不适合复杂系统

复杂系统里,真正难的不是代码量,而是隐含知识。

例如:

  • 某个接口为什么不能改字段名;
  • 某个模块为什么不能直接访问数据库;
  • 某个缓存为什么必须短过期;
  • 某个异常为什么不能吞掉;
  • 某个调用链为什么要保留幂等逻辑。

这些知识如果只存在于资深工程师脑子里,AI 当然容易犯错。问题不一定是 AI 不够聪明,而是关键约束没有被显式提供。

复杂系统要让 AI 参与,必须把架构原则、模块边界、业务规则和历史决策沉淀成可读取、可版本化、可复用的工程知识。

误区三:AI 提效等于更快写代码

如果需求错了,代码写得越快,返工也越快。

AI 的价值不应该只发生在编码阶段。它可以更早参与:

flowchart TD
    A[需求阶段] --> A1[追问模糊点]
    A --> A2[补充边界条件]
    A --> A3[生成验收标准]

    B[设计阶段] --> B1[列出方案]
    B --> B2[分析取舍]
    B --> B3[识别风险]

    C[编码阶段] --> C1[实现代码]
    C --> C2[补测试]
    C --> C3[修复局部问题]

    D[验证阶段] --> D1[检查规范]
    D --> D2[生成评审清单]
    D --> D3[定位失败原因]

    A --> B --> C --> D

越靠前的阶段,信息损耗影响越大。AI 如果能帮助人把需求讲清楚、把设计边界写清楚,后面的代码生成质量会明显更稳定。

误区四:测试通过就可以提交

测试只能证明某些输入下行为符合预期,不能证明设计没有偏差。

一段代码可能通过测试,但仍然存在这些问题:

  • 违反分层架构,把业务逻辑写进控制器;
  • 绕过统一权限校验;
  • 使用团队禁止的依赖;
  • 异常处理方式不符合规范;
  • 命名和模块划分让后续维护变困难;
  • 只覆盖了正常路径,没有覆盖失败路径。

因此,AI 生成代码之后,验证不能只停在自动化测试。需求、设计、代码和运行行为需要不同层次的检查。

误区五:AI 应该像人一样独立完成整个任务

让 AI 一次性完成大任务,风险会快速累积。

原因很简单:LLM 的输出有概率性,工作记忆又有限。一个大任务通常包含多个决策点,只要前面某个小决策偏了,后续生成内容就会沿着错误方向继续展开。

更稳妥的做法是把任务切小,并在关键节点验证。

flowchart LR
    A[大任务] --> B[拆成小任务]
    B --> C[生成 Spec]
    C --> D[审查 Spec]
    D --> E[生成代码]
    E --> F[审查代码]
    F --> G[运行测试]
    G --> H[集成验证]

步长越短,每一步的检查成本越低;约束越清晰,AI 偏离目标的概率越小。

六条实践

实践一:Context Engineering,让上下文成为工程资产

Context Engineering 可以翻译为“上下文工程”。它不是简单写提示词,而是系统性管理 AI 工作所需的信息。

一个可靠的上下文通常包括:

  • 当前任务目标;
  • 业务背景;
  • 输入输出约定;
  • 相关模块和接口;
  • 架构边界;
  • 编码规范;
  • 测试要求;
  • 不允许做的事情;
  • 已知风险和历史决策。

Spec-First:先写规格,再写代码

Spec-First 的意思是编码前先产出结构化规格说明。规格说明不必很长,但要把意图锚定下来。

可以使用类似下面的格式:

feature: 用户登录失败次数限制

goal:
  - 防止暴力破解密码
  - 在不影响正常用户体验的前提下限制高频失败尝试

scope:
  include:
    - 密码登录
    - 失败次数统计
    - 临时锁定账号
  exclude:
    - 第三方 OAuth 登录
    - 短信验证码登录

rules:
  - 同一账号连续 5 次密码错误后锁定 15 分钟
  - 登录成功后清空失败次数
  - 锁定期间返回明确错误码 ACCOUNT_LOCKED
  - 管理员重置密码后清空失败次数

interfaces:
  - POST /api/login
  - LoginService.authenticate
  - LoginAttemptRepository

acceptance_criteria:
  - 连续 4 次失败后仍允许第 5 次尝试
  - 第 5 次失败后账号进入锁定状态
  - 锁定期间即使密码正确也不能登录
  - 15 分钟后自动解除锁定

这样的规格可以直接成为 AI 编码的高质量上下文,也能让人提前发现需求漏洞。

Docs as Code:文档和代码一起版本化

Docs as Code 的意思是把文档当成代码管理。设计文档、接口约定、架构规则和运行手册应该进入仓库,跟随代码一起评审、提交、回滚。

例如:

repo/
  docs/
    architecture/
      module-boundaries.md
      database-access-policy.md
    specs/
      login-rate-limit.yaml
    decisions/
      adr-001-use-redis-for-login-attempts.md
  src/
  tests/

这样做有两个好处:

  1. AI 可以读取同仓库里的当前规则,减少靠聊天记录传递知识。
  2. 团队成员修改代码时,也能同步修改对应文档,避免文档长期失真。

渐进式披露:按任务加载上下文

上下文窗口有限,不能把所有东西一次性塞进去。更好的方式是分层加载:

flowchart TD
    A[任务描述] --> B{需要哪些信息}
    B --> C[业务规则]
    B --> D[相关接口]
    B --> E[模块边界]
    B --> F[编码规范]
    C --> G[生成 Spec 或代码]
    D --> G
    E --> G
    F --> G
    G --> H{结果是否缺信息}
    H -- 是 --> B
    H -- 否 --> I[进入审查]

核心原则是:当前任务需要什么,就给什么;发现缺口,再补充上下文。

这比一次性灌入大量文件更稳定,也更容易定位 AI 为什么犯错。

实践二:按乔哈里窗做人机分工

乔哈里窗原本用来描述人与人之间的信息认知差异。放到 AI 协作里,可以用来划分人和 AI 各自适合处理的区域。

区域人是否知道AI 是否知道协作方式
开放区知道知道自动化执行,例如常规代码生成、格式调整、测试补全
盲区知道不知道人显式注入项目私有知识,例如业务规则、历史决策、团队规范
潜能区不知道知道利用 AI 的通用知识补充方案,例如设计模式、安全风险、边界用例
未知区不知道不知道人和 AI 共同探索,通过实验、调研和反馈逐步收敛

这张表能帮助团队避免两个极端:

  • 只让 AI 做机械任务,浪费它在方案分析和知识补充上的能力;
  • 把项目私有知识默认交给 AI 猜,导致实现偏离真实系统。

对开放区,可以尽量自动化;对盲区,必须把知识写清楚;对潜能区,可以让 AI 提供备选方案;对未知区,要把任务设计成探索过程,而不是要求一次给出最终答案。

实践三:让 AI 参与研发全链条

AI 不应该只在“写代码”时出现。不同阶段里,它承担的角色应该不同。

阶段AI 更适合的角色典型产出
需求阶段引导者澄清问题、边界条件、验收标准
设计阶段协作者方案对比、风险列表、接口草案
编码阶段执行者代码实现、单元测试、局部重构
审查阶段检查者Review 清单、规范检查、潜在缺陷
维护阶段知识沉淀助手故障复盘、规则补充、文档更新

关键点在于,每个阶段的产出都应该成为下一阶段的上下文。

flowchart LR
    A[需求澄清] --> B[结构化 Spec]
    B --> C[技术设计]
    C --> D[任务拆分]
    D --> E[代码实现]
    E --> F[测试与审查]
    F --> G[规则与知识沉淀]
    G --> B

例如,需求阶段生成的验收标准,可以直接变成测试用例;设计阶段的接口约定,可以直接进入编码上下文;代码审查中发现的问题,可以沉淀为团队规则。

这样 AI 不是在每个阶段重新开始,而是在一条连续的工程链路里工作。

实践四:小任务加多层验证,控制错误累积

AI Agent 的任务粒度越大,越容易在中途积累偏差。任务拆分应该遵循一个简单原则:每一步都要有清晰输入、清晰输出和可验证结果。

例如,不要直接给 AI 一个大任务:

实现完整的优惠券系统。

可以拆成:

1. 根据业务规则生成优惠券系统 Spec。
2. 设计优惠券领取、使用、过期、回滚的数据模型。
3. 为领取接口生成 API 设计。
4. 实现 CouponService.claimCoupon。
5. 为 claimCoupon 补充并发场景单元测试。
6. 检查实现是否违反库存扣减和幂等规则。

每一步都能独立检查,问题不会拖到最后才暴露。

验证也要分层,而不是只跑测试。

验证层次检查对象典型问题
Spec Review需求和验收标准目标不清、边界遗漏、规则冲突
Design Review模块、接口、数据模型分层错误、依赖方向错误、风险未处理
Code Review代码实现可读性差、异常处理错误、规范违反
自动化测试函数和模块行为正常路径失败、边界条件错误
集成测试多模块协同接口不兼容、事务边界错误、状态不一致

这套验证链路对应软件工程的意图转化链。需求层面的错误靠 Spec Review 发现,设计层面的错误靠 Design Review 发现,代码行为错误靠测试发现。每一层都负责不同类型的问题。

实践五:Knowledge as Code,把团队知识写成可执行规则

Knowledge as Code 的意思是把团队知识当成代码一样管理。

很多团队的最佳实践并不缺,只是分散在这些地方:

  • 资深工程师的经验;
  • 代码评审评论;
  • 事故复盘记录;
  • 零散文档;
  • 群聊讨论;
  • 过期 Wiki。

这些知识如果没有结构化,AI 很难稳定使用,团队新人也很难快速掌握。

可以把规则写成结构化 Skill:

skill: service-layer-transaction-rule
name: Service 层事务边界规则
scope:
  - src/main/java/**/service/**/*.java

rules:
  - 事务注解只能出现在 Service 层公开方法上
  - Controller 不允许直接访问 Repository
  - Repository 不允许调用外部 HTTP 服务
  - 同一个事务内不允许执行长耗时远程调用

examples:
  bad:
    - Controller 中直接调用 userRepository.save()
    - Repository 中通过 HTTP 调用库存服务
  good:
    - Controller 调用 UserService,由 UserService 管理事务
    - 远程调用放在事务外,必要时使用最终一致性方案

review_checklist:
  - 是否存在跨层调用
  - 是否在事务中执行远程调用
  - 是否把业务规则泄漏到 Controller

这些 Skill 可以放进仓库,并在 AI 编码、审查、生成测试时加载。

repo/
  .agent/
    skills/
      service-layer-transaction-rule.yaml
      api-error-code-rule.yaml
      redis-cache-rule.yaml
      unit-test-style.yaml

这样 AI 不只是代码生成器,也成为团队知识的分发载体。每个成员和 AI 协作时,都能自动获得相同的工程规则。

实践六:Error-Driven,把错误变成持久知识

AI 犯错不可怕,可怕的是同类错误反复出现。

Error-Driven 的做法是把错误纳入知识生命周期:发现错误,诊断根因,再沉淀成规则或 Skill,防止复发。

flowchart LR
    A[AI 生成结果] --> B[审查或测试发现错误]
    B --> C[定位根因]
    C --> D{属于哪类问题}
    D --> E[上下文缺失]
    D --> F[规则缺失]
    D --> G[任务拆分过大]
    D --> H[验证不足]

    E --> I[补充文档或 Spec]
    F --> J[新增 Rule / Skill]
    G --> K[调整任务粒度]
    H --> L[增加检查项或测试]

    I --> M[进入知识库]
    J --> M
    K --> M
    L --> M
    M --> A

错误根因通常可以分成几类:

错误表现可能根因沉淀方式
AI 改错模块模块边界没写清增加架构边界文档
AI 使用了禁用依赖依赖规则缺失增加依赖白名单或黑名单 Skill
AI 没处理边界条件Spec 不完整补充验收标准模板
AI 生成代码风格不一致编码规范未结构化增加代码风格规则
AI 一路错到底任务太大拆分任务并增加中间审查

这种机制把知识来源分成两条线:

  • 自上而下:把已有架构原则、编码规范、设计约束提前写进规则。
  • 自下而上:从真实错误里提炼新规则,逐步扩充知识库。

两条线结合后,团队的 AI 协作能力会持续积累,而不是每次都靠某个人临时提醒。

一套可落地的工作流

把六条实践合在一起,可以形成一条相对稳定的 AI 协作流程:

sequenceDiagram
    participant 人 as 工程师
    participant AI as AI Agent
    participant Repo as 代码仓库
    participant CI as CI/CD

    人->>AI: 提供目标和背景
    AI-->>人: 生成澄清问题和 Spec 草案
    人->>AI: 修正 Spec,补充私有知识
    AI-->>人: 生成设计方案和风险列表
    人->>AI: 确认方案,拆分小任务
    AI->>Repo: 基于规则和上下文生成代码
    人->>AI: 要求按 Skill 做自查
    AI-->>人: 输出 Review 清单和修正建议
    Repo->>CI: 运行自动化测试和集成测试
    CI-->>人: 返回测试结果
    人->>Repo: 合并代码并沉淀新增规则

在实际使用时,可以把它压缩成几个固定动作:

  1. 任务开始前写 Spec:目标、范围、规则、验收标准必须清楚。
  2. 编码前加载必要上下文:只加载相关文档、接口、规则和模块代码。
  3. 把大任务拆成可验证小任务:每一步输出都要能审查。
  4. 生成后先让 AI 自查:要求它根据团队 Skill 列出风险和违反点。
  5. 人做关键决策:重点看需求偏差、设计取舍和高风险代码。
  6. 错误要沉淀:同类问题不能只修代码,还要补规则。

判断一个 AI 协作流程是否健康

可以用几个问题检查现有流程:

检查问题如果答案是否定的,通常意味着
编码前是否有结构化 Spec?AI 可能只是根据模糊描述猜需求
团队规则是否能被 AI 读取?规范依赖人工反复提醒
任务是否被拆成可审查的小步?错误会在长链路里累积
是否有 Spec、Design、Code、Test 多层验证?测试通过也可能存在设计偏差
AI 犯错后是否会新增规则?同类错误会不断复发
人的审查是否集中在关键决策上?工程师可能被大量低价值检查耗尽注意力

Agentic Engineering 的重点不是追求 AI 全自动完成软件开发,而是用工程方法降低不确定性。AI 负责生成、整理、分析和执行,人负责提供私有知识、确认关键判断、制定规则和管理风险。

当上下文、任务边界、验证机制和知识沉淀都被工程化之后,AI Agent 才能从“偶尔好用的代码助手”变成“可持续协作的研发伙伴”。


评论