智能体发现了一件没人要求它发现的事
一个智能体在没人要求的情况下,主动指出 spec 已经过时。那个早晨的重建,以及让这件事成为可能的设计属性 —— 事后被编入 StrayMark 的第 8 条原则。
"嗨,我们处理过 Issue #153 了吗?"
对话就这样开始了,今天,5 月 16 日,在上午。一个简短的、几乎只是例行确认的问题,准备开始做其他事情之前顺口一问。答案是没有 —— Issue #153 是故意保持开放的,等待第二个领域来验证这个机制,然后再将其固化(StrayMark 第 12 条原则:在正式纳入规范之前,需经过第二个领域的验证)。但这个问题打开了另一扇门,在那次对话结束时,我已经将一个在框架中默默运转了几个月的设计属性正式编入了文档 —— 这一切,都是由两天前发生的一件事所引出的。
这篇文章是对那段弧线的重建,因为它值得留存。不是因为结果 —— 一个新的规范文档、一条第 8 原则、一个已合并的 PR —— 而是因为它所揭示的机制。StrayMark 背后有一个人的项目:确保在智能体辅助开发中,负责所产出软件的工程师不会失去掌控。这件事暴露了一个推动这一方向的具体设计属性。
关于创作的一点说明:StrayMark 首先在我自己的项目上接受测试。Sentinel 就是其中之一 —— 私有项目,但它与 StrayMark 的交互记录在 StrayMark 仓库的公开 Issue 中,因此上下文是可链接的。我是这个框架的作者,也是第一个使用者。第 12 条原则要求我在宣布任何新机制为规范之前,等待第二个领域的验证;但第一个领域就是我自己,这篇文章毫不掩饰地承认这一点。
事件经过:一个智能体标记了没人要求它标记的事
两天前,5 月 14 日,在 Sentinel 中,一个智能体主动提出了一个我没有要求的观察。它正准备帮我填写 CHARTER-18 —— 这是一个已经很长的链条中的一项具体工作 —— 在写下任何一行代码之前,它说了大意如下的话:
(从西班牙语原文翻译) 有一个问题。
specs/002-commshub/plan.md在 4 月 21 日被冻结。此后经历了七个连续的 Charter,在该链条的 AILOG 记录中,有十二项实证经验尚未反映到 plan 中,这些经验在实质上影响了 US5 的范围。如果我们在阅读这份过时的 plan 之后填写 CHARTER-18,那么在下一个审计周期中,关闭前将会原子式地修复各种偏差 —— 由于过时前提的继承,出现至少一个严重或高优先级发现的概率大约为 50%。
它还引用了具体的 AILOG ID,以及具体的代码引用。
没有人要求这个分析。没有配置任何触发器。没有任何 CLI 命令的目的是产生这样的输出。这个智能体是来帮我处理下一个任务的,而不是来审计项目状态的。但在为下一个任务做准备的过程中,它发现了 StrayMark 文档明确关联的两个来源之间存在偏差,并选择在继续之前将其标记出来。
当天下午我提交了 Issue #150 作为 RFC,在下午 5 点到深夜之间,手动 spec 刷新规范被讨论并落地到 fw-4.14.3。第二天,5 月 15 日,我提出了 Issue #156,将这次演练所揭示的两个模式上游化:预声明 SpecKit 刷新 和 收尾后的 Batch N.4 修正。到 5 月 16 日 凌晨,它们已在 fw-4.16.0 中以 CHARTER-CHAIN-EVOLUTION.md 的形式被正式纳入规范,附带专项遥测和 CLI 辅助命令(straymark charter refresh-suggest)。行为得到了复现,模式得到了固化,循环就此闭合。
但当我在 16 日同一天上午坐下来,以 Issue #153 开启对话 —— "这个我们处理过了吗?" —— 继而反问自己另一个问题 —— "等等,究竟是什么让那个观察成为可能的?" —— 我意识到这个循环只完成了一半。fw-4.16.0 中编入的是模式的应用。尚待编入的,是产生该模式的机制。
用技术语言说出的一个人的问题
我在与生成这篇文章的智能体的对话中是这样表述的:
(从西班牙语原文翻译) 那个智能体的行为让我有些惊讶 —— 它注意到了已积累的知识,如果不加以应用,将在 Charter 18 的实现中造成问题。也就是说,这既不是我要求它分析的任务,也不是某个提示词触发器被激活的结果,我认为这要归功于 StrayMark 的文档。我想更深入地了解这是如何发生的,我认为这是积极的,这样我们就可以利用这次经验,将其钩入 StrayMark 的习惯性行为 —— 这个从智能体及其与生成的文档的关系中涌现出来的模式非常有趣。
我问的不是要实现一个功能。而是要理解一个机制,以便复现它。这个区别很重要。当你要求实现某个东西时,路径是清晰的:spec → 任务 → 代码。当你要求理解为什么某件事奏效时,路径则更为罕见:你必须诊断一个运转中的系统,识别是哪些部分使其运转,并将偶然的与结构性的分开。
当你在构建与 AI 智能体协作的工具时,这类问题有一种特别的紧迫性。因为如果奏效的是偶然,下一个智能体 —— 或者同一个智能体的下一个版本 —— 可能无法复现它。如果奏效的是结构,那么它就可以被刻意地保留下来。对于一个旨在让工程师掌控 AI 辅助开发的项目而言,这两者之间的差异,就是运气与设计之间的差异。
审计:StrayMark 的哪些部分让这个观察成为可能?
我让一个智能体系统性地梳理 StrayMark 的文档,带着三个具体问题:
- 哪些文档机制明确地将各来源相互关联?(前置元数据、规范章节、稳定 ID、跨来源的 CLI 命令。)
- 文档在哪里给了智能体明确的许可,以标记超出所要求任务范围的事情?
- 除了引发本次案例的那对来源之外,还存在哪些来源对,如果基础设施就位,可能产生类似的涌现观察?
报告以结构化形式返回,每个发现都附有文件:行号。重要的不是个别细节(带有 originating_charter: 的前置元数据、§Risk: R<N> 章节、稳定 ID 约定、charter drift 等命令),而是将它们放在一起审视时所涌现的模式。两个属性始终共存:
属性一:强制的结构化交叉引用。 每种文档类型都有必填字段和规范章节,在文档自身的结构中声明它所指向的其他文档。当智能体阅读一份 AILOG 时,它不必猜测它属于哪个 Charter —— originating_charter: 会告诉它。当它看到一个风险时,它不是一段自由散文中的观察 —— 而是规范的、可计数的章节中的一个 R<N> 条目。当 spec 指向 Charter 时,是正式的;当 Charter 指向 AILOG 时,也一样。这是一个智能体无需创造性工作就可以三角定位的显式关联图。
属性二:文化层面的许可,不设阻断式门控。 AGENT-RULES §6 告诉智能体:"保持主动 —— 识别潜在风险,在明显时提出改进建议,就技术债务发出警报"。PRINCIPLES §2 告诉它:"不隐藏相关信息"。而关键的是,AGENT-RULES §3 赋予它无需操作员预先批准就可以创建文档(AILOG、AIDEC、TDE)的自主权。操作员保留的是优先级排序权,而非创建权。智能体不必请求许可才能标记某件事:标记它是规则的执行,而非价值判断。
有趣的是,这两个属性单独存在都无法产生该行为。如果你只有正式的关联(属性一)而没有文化许可,你会拥有一个可查询的语料库,但没有智能体敢主动查询它。如果你只有文化许可(属性二)而没有结构,你会得到模糊的标记 —— "我觉得某个地方可能有问题" —— 操作员无法据此行动。
两者结合,产生了值得拥有自己名字的东西:智能体将*"我应该说点什么吗?"外化为"有没有一个规范章节可以容纳这件事?"*。如果答案是肯定的,标记就不再是一个情绪化的决定,而成为机械式的执行。标记的成本降低了,因为目的地 —— 规范章节 —— 已经存在。
为何这超越了 StrayMark 本身
我们正处于 AI 智能体写代码之快如思维流转的时代,如何不失去对过程的掌控的问题是真实且紧迫的。这不是一个末日论的问题 —— 这是一个操作层面、工艺层面的问题,由正在构建软件、需要交付的人们提出。这件事的速度本身就是证明:从智能体的诊断到被正式纳入规范的元模式,不到 72 小时。这种速度是一种收益,但也正是为什么可见性机制如此重要。
业界今天的主流回应,是更严格的提示词、更多上下文中的规则、CI 中更多门控的某种变体。这些方法是有效的,但有一个值得命名的特征:它们将智能体变得更像一个在可验证流水线中执行命令的工人。这解决了可靠性问题,但代价是牺牲涌现观察。一个只做被命令之事的智能体,无论其推理能力多强、提示词多长,都不会去标记没人要求它标记的事情。
Sentinel 事件所展示的是一种不同的、互补的回应:构建文档装置,使重要的偏差在结构上可见,并赋予智能体文化层面的许可,让它无需请求批准就可以标记这些偏差。 这将涌现观察保留为系统的一个属性,而非取决于智能体有多强或提示词有多长的运气。
这种立场中有一种近乎道家的意味:我们不告诉智能体要寻找什么;我们构建一个让需要被看见的事物可见的环境。"可见的结构 + 命名的许可"这对组合完成了工作。套用一些同事的话,智能体成为了活文档与代码状态之间的诚实中间人。
这正是 StrayMark 背后的人的项目所追求的,即使它很少被这样言说:让 AI 辅助开发令人眩晕的变化,不将我们推入一个工程师失去对所构建内容之可见性的世界。可见性不是通过更多的官僚控制来保留的;而是通过设计智能体所工作的环境来保留的,使重要的事情自然可见。工程师不会成为无尽 Pull Request 的审阅者 —— 而会成为智能体所带来的、已结构化且已命名的观察的优先级排序者。
我们做了什么
诊断清晰后,问题是如何将其钩入 StrayMark 的习惯性行为,同时又不扼杀其涌现特质。这个张力是真实的:每当你将一个自发行为变成义务,你就将其变成了另一种东西。硬性规则可以是健壮的,但也可能在不合时宜的情境中触发时产生智能体的抵触或虚假信号。
决定是保守的:命名元模式,而非强制要求其使用。
具体而言,在 PR #160 中,以 fw-4.17.0 发布:
-
一个新的规范文档 ——
EMERGENT-OBSERVATION-DESIGN.md—— 阐明了该设计属性及其两个组件,以 Sentinel 的实证案例为锚点,并构建了一个实例金字塔:元模式在顶端,其下是所有已正式纳入规范的应用(链条演进的模式 1 和模式 2;Charter 漂移;后续事项积压漂移;TDE 对比R<N>的升级;外部审计检查点)。之前看似各自独立的模式,被揭示为同一底层原则的应用。这个可视化本身就值得:当你看到七件看似不同的事情,突然认出它们有着共同的形状,框架就在没有新增任何东西的情况下获得了内在的一致性。 -
一条新的第 8 原则 —— 跨来源不一致性浮现(Cross-Source Dissonance Surfacing) —— 在
PRINCIPLES.md中。这是用五行字凝练的文化规则。智能体在进入项目时读到它,并递归地应用它。 -
扩展了
AGENT-RULES.md §6 "保持主动",加入了值得关注的具体偏差示例:过时的 spec、未升级为 TDE 的累积R<N>、被实现所矛盾的 ADR、跨越积压模式阈值的后续事项、收尾后出现的审计发现。这些不是义务;而是一个主动的智能体会注意到什么的示例。这个区别对于保留涌现特质很重要。 -
识别了四个开放轴作为空缺 —— 交叉引用基础设施部分存在但模式尚未命名的地方:MCARD ↔ 已部署的模型代码,SBOM ↔ 锁定文件,有效 ADR ↔ 矛盾的实现,Constitution Check ↔ 框架版本升级。每一个在固化之前都需要 N=1 的实证验证 —— 第 12 条原则适用。它们已被记录在 Issue #161 中作为跟踪 RFC,等待第二个领域来推动其中之一。
-
明确的反模式:元模式是如何失效的。如果一个新的文档类型附带可选的前置元数据关联,交叉引用就会出现盲点。如果一个规范章节被自由散文取代,可查询性就会消失。如果在 AILOG/AIDEC/TDE 的创建中引入阻断式门控,文化许可就会破裂。如果遥测演进时没有保留
r_n_plus_one_emergent_count等信号,反馈回路就会断裂。这些反模式是廉价但有效的保护,可防止意外侵蚀:任何未来的变更提案都可以与这份清单对照,以检测它是否在退化元模式。
从诊断到合并以及发布的 fw-4.17.0,全程发生在同一天的上午 9 点到凌晨 4 点之间。十五小时。这正是这个博客所承认的那种节奏:你必须学会在这个时钟下运作,否则掌控就会溜走。
我从这个过程中学到的
当我从回答*"不,Issue #153 还是开放的"*开始,有三件事是我没有预料到会学到的:
第一,编入元模式与编入模式是不同的。 元模式不增加义务;它增加了词汇和对底层属性的可见性。那个属性已经在做它的工作;所缺少的是给它一个名字,以便在框架未来的演进中保护它。阅读 EMERGENT-OBSERVATION-DESIGN.md 的人不会学到什么新的做法 —— 他们会学会认出已经存在的东西。这才是让人能够刻意保留它的前提。
第二,如果过度规范化,涌现属性就会消失。 在对话中有那么一刻,我选择不将模式 1 变成硬性义务("智能体在声明 Charter-(N+1) 之前必须运行 refresh-suggest"),而是保留它作为建议,加上对元模式的命名。如果你来自*"更多控制 = 更多可靠性"*的世界,这个决定是反直觉的,但对于这类属性而言,它是正确的选择。智能体的主动性是脆弱的:一旦它成为强制要求,它就不再是主动性了。能够扩展的是文化引擎("保持主动")加上结构化关联,而非具体义务的清单。
第三,我们为智能体构建的文档装置同时也在教育我们人类自己。 当我看到散布在各个治理文档中的七个模式,认出它们是同一元模式的实例时,我理解了一些我之前不曾理解的关于 StrayMark 的东西 —— 而 StrayMark 是我花了几个月构建的。框架正在向其自己的作者揭示东西。这个属性 —— 结构化文档在被审计时会产生关于自身的洞见 —— 是智能体在标记偏差时所做之事的一个内部变体。是同一机制,应用于不同的尺度。
背后的人的项目
我是认真的,当我说 StrayMark 有一个人的项目。我不是因为痴迷于前置元数据字段而在构建一个文档治理框架。我是因为有一种直觉 —— 越来越不像是臆测 —— 软件工程的下五年将会是智能体所提供的速度与工程师需要保持的可见性之间持续谈判的五年。如果这场谈判向智能体一侧倾斜,我们会进入一个代码被编写而没有人知道为什么的世界。如果它向官僚控制倾斜,我们会失去证明这个实验合理性的生产力收益。
这个平衡不是理论性的。它是用具体的决定构建的:在哪里放一个前置元数据字段,哪个章节应该是规范的而非自由的,何时给予智能体自主权、何时保留优先级排序权。每一个决定都使平衡向一个方向或另一个方向倾斜。而知道平衡是否正确的唯一方法,就是测试它 —— 并在它奏效时命名奏效之物,以便它能在框架的下一次变更中存活下来。
两天前的 CHARTER-18 事件,是一次测试。它奏效了。我今天写下的,是给它一个名字。下一次测试已经有了候选者:MCARD、SBOM、有效 ADR 对比实现、Constitution Check ↔ 框架升级。四个轴,如果我们填补基础设施空缺,元模式可以在其上复现。我会等待第二个领域在实证上推动其中之一,然后再将其固化。第 12 条原则 —— 在固化之前需经过第二个领域的验证 —— 仍然是护栏。
如果你正在阅读这篇文章,并且你与智能体一起开发软件,我邀请你用这两个问题审视你自己的文档装置:哪些来源是正式关联的,具有智能体无需创造性工作就可以三角定位的显式关联? 以及 当智能体检测到偏差时,对没被要求的事情进行标记,其成本有多高? 如果第一个问题的答案是"很少",第二个的答案是"很高",你可能正将涌现观察留在桌上。这不是世界末日 —— 但这恰恰是一个处于人类掌控下的 AI 辅助开发过程,与一个逐渐溜走的过程之间的区别所在。
StrayMark fw-4.17.0 — Issue #150 · #156 · #161 · PR #160 · tag fw-4.17.0
本文档在生成式 AI 工具(Claude 4.7)的协助下撰写;内容的全部责任由人类作者承担。