在上一篇《让 Agent 的执行结果更容易追溯:NagaAgent 中四个 Skills 的调整》里,我写了自己整理执行记录时遇到的问题:一份 Journal 列出了很多技术信息,过一段时间回看,却仍然需要在各个章节之间来回查找,才能弄清某个决定为什么这样做、任务又凭什么算完成。
那篇文章 主要记录了我怎样调整四个 Skills 的职责。这一篇想展开当时提到的两份阅读材料:Anthropic 的《Trustworthy agents in practice》,以及 AWS 对 ADR(架构决策记录)流程的说明。
我把它们放在一起读,是因为自己希望 Agent 能在项目里持续推进工作,同时也希望从这些工作中学习工程判断。执行过程需要留出多少自主空间,重要选择又应该留下什么依据,这两个问题一直连在一起。
Agent 执行到什么地方,需要把决定交回来
Anthropic 描述的 Agent 会自行规划、调用工具,再根据结果调整行动。文章沿用了五项原则:人类控制、与人类价值观对齐、交互安全、透明度和隐私保护。与我的实践关系最直接的是人类控制:通过整体计划和权限决定行动范围,并区分可以自行调查的事实与需要用户澄清的意图。文章也指出,反复请求批准会带来摩擦,用户可能逐渐忽略这些提示。原文:Trustworthy agents in practice
这和我使用 Agent 时的需求很接近。交给它一个工作单元,我希望它先检查当前仓库,再决定怎样落实。计划里提到的文件可能已经改名,预想的接入点可能不再合适。只要目标和明确约束仍然成立,这些事实应该由它去查清,并据此调整做法。
但有些变化需要重新作决定。
例如,任务要求迁移文档,执行中发现少了几份文件。确认来源后把文件补回来,仍然是在完成原来的任务。如果它顺手迁入旧分支的生产代码,或者因为重新验证比较麻烦,就把旧分支的测试结果算作新分支已经通过,任务范围和验收含义都变了。这种变化需要交回用户处理。
因此,我理解的 bounded autonomy,也就是有边界的自主执行,首先要把授权说清楚:目标是什么,哪些要求必须遵守,做到什么程度才算完成。Agent 可以在这些条件内选择方法;遇到会改变目标、验收或授权范围的问题,就要说明冲突,等用户明确尚未解决的事项。
这个边界也不能简单画在"读文件"和"改文件"之间。修改一个局部实现可能已经包含在任务授权里,而一句"这个检查以后必须通过才能合并",即使暂时没有改代码,也涉及项目规则。高风险或不可逆的操作,需要在执行前明确授权;已经授权的普通步骤则不必反复确认。
结合自己的项目,我会把这套安排写成下面几项:
- Plan 和项目规则写清目标、范围、明确要求与验收条件。
- Agent 根据仓库事实选择实现,在执行反馈出现后调整方法。
- 日志、测试产物和决策说明留下可检查的依据。
- 超出已有授权的决定交回用户,确认后再继续相关工作。
这是我对实践的整理。Anthropic 的文章还把模型、运行约束、工具和环境都纳入考虑,并讨论提示注入等安全问题。我的 Skills 主要约束执行与记录方式,实际权限和隔离仍需运行环境提供。Anthropic 原文
ADR 让我注意到,代码会省略很多背景
AWS 对 ADR 的说明很具体:它记录有架构意义的决定,至少包含背景、决定及其后果。决定有负责人,也有提出、评审和接受或拒绝的过程。ADR 被接受或拒绝后,原有内容保留为历史;后续改变需要新建 ADR 并重新评审。新决定被接受后,旧记录标记为 Superseded,即已被替代。原文:Architectural decision record process
我关心的是这种记录方式怎样帮助后来的人理解代码。
在最终实现里,往往只能看到"这里用了缓存""失败后增加重试""测试替换了某个依赖"。这些代码表达了选中的做法,却不一定能解释当时为什么需要它。相同的实现,可能出于性能要求,也可能是在绕开一个暂时无法修改的接口。维护者面对这两种背景,后续处理方式会很不一样。
当时的业务要求、现有架构、时间和成本,都会影响一个方案是否合适。只剩下实现细节,容易把某次有条件的选择当成长期规则。
放到我自己的执行记录里,我希望重要决定至少能说清这段关系:
当时的目标和仓库事实
→ 暴露了什么问题,受到什么约束
→ 为什么选择这个做法
→ 带来了哪些效果和代价
→ 条件发生什么变化时,需要重新考虑
如果当时确实比较过别的方案,就把相关取舍补进来。没有发生过的比较,不必为了填满模板,事后编出几个显然不合适的选项。
我也不会把每项局部修改都单独写成 ADR。会影响公共接口、系统结构或长期依赖的决定,值得正式记录并评审;一次工作单元里的局部选择,可能在 Journal 中留下几句话就够了。这是我把 ADR 的思路用于日常执行记录时作出的取舍。
这里还有一个时间上的区别。项目进度需要不断更新,历史决定的背景却应该保留。如果以后更换实现,读者仍然需要知道旧方案在什么条件下被采用,以及哪个新条件促成了调整。直接把旧理由改成今天的解释,会丢掉这段变化。
用 C0-3 把授权、选择和验证连起来
上一篇里的 C0-3,是为 CI 保存结构化测试报告的工作单元。原先测试已经能让检查通过或失败,后续排查还需要找到具体用例、失败消息,以及它们对应的代码版本和运行记录。历史报告保存了这次工作的选择与验证过程,下面按本文的关注点重新整理。案例背景也可以回看上一篇的 C0-3 部分。
先看任务边界。C0-3 要解决的是测试报告的生成和保存,测试断言与退出码继续负责测试结论。它没有包含"把 Stream 检查设为合并必需项"这个决定,也没有承担验证真实 LLM 或完整 Agent 工作流的任务。
这使自主执行有了具体范围:Agent 可以围绕报告路径、上传条件和运行标识落实方案,并验证失败后是否仍能取回报告。至于某个检查是否必须阻止合并,历史计划把它留给了后续单独的人工决定。
再看实现选择。如果只记下"增加 JUnit,配置上传步骤",过一段时间我还是要重新推断这些配置的用处。根据历史报告,可以把理由整理成这样:
当时两个工作流缺少可下载的结构化测试报告,后续排查需要把失败用例和具体运行对应起来。因此,每个测试套件生成 JUnit,并在上传产物的名称中保留 suite、run ID 和 attempt,便于区分不同套件、运行与重试。测试失败时仍需要诊断材料,所以上传步骤使用
if: always()继续尝试;预期报告缺失时,通过if-no-files-found: error暴露这个缺口。上传成功不会覆盖原来的测试失败。
这段是依据历史材料整理的解释示例。它把配置与要解决的问题接在了一起,后续修改上传方式时,也能据此找出需要保留的行为。
其中还有一个很适合说明决策背景的细节:报告保留 14 天。
只看 retention-days: 14,我不知道这个数字来自平台限制、成本考虑,还是某种项目要求。报告留下了我确认采用 14 天方案的记录,也写明了它的前提:用短期存储覆盖通常的 PR review 和问题排查。如果以后需要长期趋势查询或更长时间留存证据,就要重新考虑存储方式。
因此,记录这个决定时,"当时接受短期留存"比单独记住"14 天"更有用。我以后可以判断新需求是否还落在原来的前提里。
不过,选择理由写清楚以后,仍然需要验证结果。
"本地生成了 XML"只支持本地报告生成这件事。C0-3 的验收还要求在托管运行中取回报告,尤其要检查测试失败后的路径。历史报告在 8 月 31 日补充了这部分证据:pytest 步骤失败,上传步骤成功;下载后的报告经过摘要比对和 XML 解析,可以定位失败断言。
这个结果支持相应运行中的失败报告保存行为。它没有验证 runner 被强制终止后仍能上传,也没有把使用受控依赖的测试扩展成真实 LLM 验证。具体 run、版本和解析结果,需要继续保留在证据记录里。
同一个 C0-3,因而可以从几个位置检查:授权范围决定它能做哪些事,决策说明解释为什么这样实现,执行产物支持实际结果,验收再判断这些结果是否满足任务要求。某个位置缺了信息,其他记录不能自动补上。
四个 Skills 怎样保存和衔接这些信息
回到上一篇的调整,我把这些职责分给四个 Skills,是因为自己查阅它们的时机不同。刚完成工作时,我先看交付;修改已有实现时,我找理由;隔了一段时间回来,则需要知道项目进行到了哪里。
沿用 C0-3,可以这样理解它们的衔接:
| Skill | 在这个案例里需要交代的内容 |
|---|---|
evidence-backed-execution-rationale |
为什么失败后仍尝试上传;运行标识和保留期解决什么问题;哪些条件变化后需要调整方案。 |
evidence-backed-work-unit-journal |
实际完成了哪些报告保存能力;成功和失败路径分别有哪些证据;还有哪些情况未经验证。 |
plan-progress-checkpoint |
依据原定验收条件更新 C0-3 状态,并关联验收记录;后续合并规则的决定仍属于对应工作单元。 |
plan-reentry-guide |
告诉重新回到项目的人当前进展、下一步及其理由,并指向需要细读的记录。 |
其中,Rationale 约束重要决定应该怎样解释。执行方法仍由 Agent 在任务授权范围内选择,Rationale 要求把事实、问题、选择及验证范围说清楚。打开文件、搜索符号、普通格式化这些动作,不需要各自附一段理由。
这类解释也不必每次都新建文件。对局部决定,可以放在相关改动说明或 Journal 里;需要长期反复查阅时,再给它一个稳定的位置。其他文档引用同一份依据,能少掉很多重复内容。
Journal 则需要区分理由与结果。方案为什么合理,可以链接到已有解释;本次实际检查了什么、结果对应哪个版本,仍然要在结果记录中交代。Checkpoint 据此更新计划状态,Re-entry 再从计划与记录整理后续阅读入口。
上一篇的 MIG-1 恰好说明了这种衔接为什么有必要。它完成了文档迁移,旧测试结果仍然属于原版本。Journal 需要保留这项限制,进度记录里的完成状态只对应文档迁移,重新进入项目的指南也要让读者看到目标分支还有哪些工作待验证。否则,几份文档即使单独看都通顺,连起来仍可能给人错误印象。
这套设计对记录也提出了要求:引用要能找到,版本要能对应,当前状态与历史材料之间的差异要说清。把报告缩短,只解决了阅读量的问题;这些联系有没有留下来,还得逐项检查。
我想从记录里学到的判断
对我这种边做项目边学工程的人来说,决策说明还有一个用途:以后遇到相似问题时,能知道从哪里开始判断。
拿 C0-3 来说,我希望记住的是失败路径也需要保存诊断证据。下次处理构建日志、批处理结果或者其他异步任务时,如果发现"任务一失败,后面的记录步骤就不再执行",就值得检查结果判定与证据收集是否绑得太紧。至于用什么配置,要回到具体工具与运行环境里确认。
同样,14 天保留期让我注意的是证据生命周期与使用需求的关系。短期排查与长期查询需要的存储安排不同。决定记录里保留了需求和前提,我才有机会在条件变化时重新判断,调整具体的保留期限或存储方式。
这也是 execution-rationale 保留学习模式的原因:需要时说明当前选择涉及的工程原则,以及以后遇到什么现象时值得考虑它。解释可以随着工作一起给出,不必每一步都停下来提问。
目前,这四个 Skills 完成的是职责与输出要求的调整。C0-3 和 MIG-1 都是调整前的历史案例,它们帮助我检查记录应该保留什么,还不能证明新版 Skills 已经改善了实际效果。
接下来,我想在真实工作单元里使用它们,再隔一段时间回看:能否找到一个决定当时的依据;改动条件后,能否知道该重新检查哪些地方。如果仍然要把整段会话翻一遍,才能猜出当时为什么这样做,记录方式就还需要继续改。