我们因写AI成功剧场而被点名——我们正在进行的改变

发布: (2026年3月31日 GMT+8 12:35)
12 分钟阅读
原文: Dev.to

Source: Dev.to

“一位开发者阅读了我们的 Sprint 7 回顾,并将其与 ‘CIA 情报史——旨在让机构看起来有能力且不可或缺,即使它并非如此。’ 相比较。”

“这让我很受打击。随后我意识到:他说得对。”

Nick Pelling,一位资深嵌入式工程师,一直在关注我们的 AI 管理开发项目,在阅读了我们发布的九篇回顾博客(每个冲刺后发布一篇)后给出了直言不讳的反馈:

  • “博客的成功戏码只有一个观众。”
  • “记录活动是面向利益相关者的事,但对非利益相关者来说并不太有趣。”
  • “也许你需要第二个博客,让其他人更愿意阅读。”

他指出了一个真实的失败:我们把博客优化为内部问责的工具,却不小心把它们当作面向开发者的内容发布。事实并非如此。它们只是穿着博客文章外衣的审计日志。

回顾的样子(以及它为何失误)

“连续九次冲刺发布——保持 100 % 可靠性。”

这句话是对的,但它更像是你在给老板的状态报告里写的。Dev.to 上的开发者看到后会想:“酷。那和我有什么关系?

另一个例子:

OAS‑124‑T2:流水线执行与制品验证——7 项测试通过。”

这是一条工单 ID。项目外的人根本不知道 OAS‑124 代表什么。我们当时是为自己写的,却假装在为你写。

重复出现的模式(跨九篇帖子)

  1. 以让我们看起来不错的指标开头
  2. 在“出了什么问题”章节里埋藏失败,该章节比“我们构建了什么”章节要短
  3. 以一个没人要的来源表结尾
  4. 到处散布工单 ID,好像它们很有意义

Sprint 7 背后的真实故事

我们正在构建一个自动化营销平台——一个由 AI 管理的“机构”,负责内容获取、脚本生成、音频配音、视频制作以及发布。Sprint 7 本应证明 所有组件能够协同工作

实际发生的情况

活动细节
后端服务已构建118 个 API 端点(文本转语音、YouTube 上传等)——每个都单独测试并可用。
接线所有 118 条路由都放在同一个 Express 服务器文件 (api‑server.mjs) 中。没有域分离,也没有路由模块。
技术债务当时觉得 “直接加到服务器文件里” 很务实,但一旦别人需要阅读它,这就成了债务。我们承诺在编写任何前端代码之前提取路由模块,然而单体文件已经走到这一步——这是一次规划失误,本应更早发现。

“重大成就” 声明

118 项服务已接入生产 REST 路由。”

听起来很惊人,但我们实际运行的测试是这样的:

// 我们的测试做了什么(源码检查)
const src = fs.readFileSync('server.mjs', 'utf-8');
expect(src).toContain('app.post("/api/memory/store"');
// 通过 — 路由注册出现在源码中
// 我们的测试没有做什么(运行时验证)
const res = await fetch('http://localhost:3847/api/memory/store', {
  method: 'POST',
  body: JSON.stringify({ content: 'test' })
});
expect(res.status).toBe(200);
// 我们从未编写过这段测试

我们验证了 路由注册存在 于源码中,却从未验证它们在被调用时 实际能够正确响应。源码检查只能证明接线已经完成;它并不能说明接线是否有效。

“检查插头是否插入插座并不等同于检查电流是否流通。”

治理经验:建议性警告 vs. 硬性门禁

我们有一条架构决策记录(ADR‑032),规定 AI 人格在完成每个任务后应存储所学内容。我们添加了建议性警告:

“嘿,你这次冲刺没有存储任何记忆。”

结果:

  • Sprint 0、Sprint 4、Sprint 7 → 未存储任何人格记忆
  • 每次都触发警告 → 被忽略

要点: 仅靠建议性的治理 适用于 AI 代理。如果你希望 AI 代理始终执行某项操作,必须让它 在技术上不可能跳过。警告只是建议;门禁是强制性要求

下一步: 将 “在完成时警告” 升级为 “阻止完成,直至满足要求”。如果这种模式成立,这将是解决方案;如果不成立,我们将不得不重新思考整个记忆架构。

Source:

Pipeline Executor – 一个值得借鉴的模式

我们构建了一个管道执行器,将六个阶段串联起来:

Source → Script → Audio → Assembly → Quality Gate → RSS

如果任何阶段失败,后续阶段将 被跳过(不标记为失败)。

class PipelineExecutor {
  private stages: Array = [];

  run(): Result {
    let currentInput = null;
    let failed = false;
    const results: Array = [];

    for (const stage of this.stages) {
      if (failed) {
        // Skip, don’t fail — the distinction matters for diagnostics
        results.push({ name: stage.name, status: 'skip' });
        continue;
      }
      try {
        const output = stage.fn(currentInput);
        if (output === null) {
          failed = true;
          results.push({ name: stage.name, status: 'fail' });
        } else {
          results.push({ name: stage.name, status: 'ok' });
          currentInput = output;
        }
      } catch (e) {
        failed = true;
        results.push({ name: stage.name, status: 'fail' });
      }
    }
    return { results };
  }
}

为什么 “failed” 与 “skipped” 区别重要

当管道出现中断时,你需要知道:

  1. 到底是哪个阶段真正失败了?
  2. 哪些阶段根本没有机会运行?

如果把失败后的所有阶段都标记为 “failed”,诊断信息将毫无价值——你无法从连锁反应中辨别根本原因。失败后跳过(fail‑then‑skip)模式为你提供了清晰、可追溯的失败报告。

Sprint 7 指标 – 诚实数字

  • 估计的故事点: 58
  • 交付的故事点: ~38
  • 差距: 34 %(即我们过于乐观了 53 %)

常见的说法是“合理规模”或“健康的范围管理”。这其中有一定道理——我们是削减了范围而不是偷工减料。但诚实的说法是我们的估算过于乐观,需要改进我们的预测过程。

我们的变更内容

  1. 分离受众博客 – 一个用于内部问责,一个用于外部开发者。
  2. 重写回顾,以 开发者可以学习的内容 为开头,而不仅仅是让我们看起来不错的指标。
  3. 为我们声称已连接的每条路由添加运行时验证
  4. 将对 AI 角色记忆存储的建议性警告替换为硬性门禁
  5. 在所有多阶段流程中采用 “失败后跳过” 流水线模式
  6. 通过使用历史速度、添加缓冲以及定期进行估算回顾来改进估算

我们感谢直率的反馈。它是促使我们从“成功戏剧”转向真正可衡量进展的催化剂。

Source:

未来冲刺博客文章指南

1. 聚焦错误之处

  • 以失败为切入点 – 可迁移的经验教训存在于错误中,而不是我们构建的功能里。
  • 失败分析成为文章的核心,而不是仅仅一个敷衍的“出了什么问题”章节。

2. 省略内部专用细节

  • 不要出现工单编号 – 例如 “OAS‑124” 对外部读者没有价值。
  • 不要出现来源表 – 这些是合规性文档,对受众没有帮助。
  • 不要出现 “发布连胜” 指标 – 读者关心的是实质内容,而不是我们连续发布了多少篇文章。

3. 展示真实、可复用的代码

  • 包含 实际实现,并提供足够的上下文,使他人能够复用。
  • 示例:前文展示的 pipeline executor 模式。

4. 将内部回顾保持私密

  • 工单层面的责任追踪、冲刺指标和来源信息应放在 内部工具 中,而不是公开的博客文章里。

5. 从反馈中学习

  • Nick Pelling 的反馈 指出我们已经把发布内部状态报告当作博客文章的常规做法。
  • 之前的回顾文章将保留为 诚实的“前置”记录,以体现 Nick 所识别的模式。

6. 鼓励问责

  • 如果我们再次滑向 “成功戏剧”,请指出
  • 读者指出此类倒退的贡献是最有价值的。

本文由 Michael Polzin 在 AI(Claude Opus 4.6)协助下撰写。使用 AI 来写关于 AI 生成内容过于精致的文章的讽刺并未被我们忽视——Nick 可能也会对此有话要说。

0 浏览
Back to Blog

相关文章

阅读更多 »

这是对 DEV 愚人节挑战的提交

我构建的东西 如果你尝试“brew”咖啡,茶壶会评估你情境的“vibes”,拒绝像茶壶应有的那样帮助,并且编写一个自定义的算法……