https://github.com/humanlayer/12-factor-agents 项目解析
下面这 repo 不是一个“框架”,而是一份工程实践蓝图:用 12 个“因子”把 LLM/Agent 做到可上线、可维护、可观测。作者强调:多数所谓“Agent”其实是确定性软件,只在关键节点撒一点 LLM 魔法;与其一把梭的黑盒框架,不如把这些原则模块化地嵌入你现有系统。这是它的核心立场与价值主张。
项目定位与核心主张
- 定位:受 Heroku《12-Factor App》启发,为“可靠的 LLM 应用/Agent”给出工程原则,而非运行时或 SDK。
- 主张:真正能上生产的“Agent”大多不是“给个 Prompt + 一袋工具 + 循环直到成功”的自动化魔法,而是以确定性控制流为骨架、LLM 只做少量不可枚举的判断与结构化转换。
- 状态:当前版本 v1.0,v1.1 在草案分支推进;仓库还附带 workshops 与 packages 样例。
- 周边:社区正在做 create-12-factor-agent 脚手架,帮助按“12 因子”起 repo,但仍然不是框架。
12 个因子(精炼解读)
官方“短版目录”列出 12 个因子,下面按工程落地要点解读。
- 自然语言 → 工具调用(Structured Tool Calls)把 LLM 的核心能力视为将 NL 转成结构化 JSON/函数调用。你的业务逻辑仍由确定性代码执行,LLM 只产出“下一步要做什么”的结构化指令。落地:用 JSON Schema / Zod / BAML 约束输出,失败就重试/降级。
- 掌控你的 Prompt(Own your prompts)Prompt 属于产品代码的一部分:版本化、评测、回滚、A/B,而不是被某个框架隐藏。配合回放集做离线评估。
- 掌控你的上下文窗(Own your context window)不要把“上下文”交给模型自由堆叠。把该写数据库的就写数据库,只把必要的紧凑摘要与“任务状态”送进上下文(见因子 9)。这也是作者提出“上下文工程(Context Engineering)”的语境。
- 工具 ≈ 结构化输出(Tools are just structured outputs)“工具调用”本质就是结构化消息与纯函数执行:把神秘感去除,统一到你的类型系统与错误处理里。
- 统一执行态与业务态(Unify execution & business state)会话/步骤日志(execution state)与业务状态(business state)共识化:落到同一套持久化/事件溯源里,支持重放、恢复、审计、幂等。
- 启动/暂停/恢复的简单 API(Launch/Pause/Resume)Agent 是长期运行的业务流程,必须能外部可控:HTTP API / Webhook / 队列事件能随时介入暂停、恢复、回滚。
- 把“找人”做成工具调用(Contact humans with tool calls)把人工复核/审批变成第一等公民的工具调用,能发任务到工单/IM,并把人类反馈纳入同一事件流。
- 掌控你的控制流(Own your control flow)控制流归你:用编排器/有向图/状态机明确步骤与回退,不把流程决策完全交给 LLM 循环。作者也举了与 Airflow/Prefect/Dagster 等 DAG 编排类比的上下文。
- 把错误压缩进上下文(Compact Errors into Context Window)错误要结构化提炼后放回上下文,避免把长日志直接塞给模型,既省 tokens 又提升可恢复性。
- 小而专注的 Agent(Small, Focused Agents)按能力/场景切分:若干小 Agent 协作优于一个无所不能的大 Agent。
- 随处触发,直达用户所在(Trigger from anywhere)把 Agent 当作可被任何事件触发的组件:HTTP、Cron、队列、产品内按钮,输出到用户当下渠道。
- 把 Agent 做成“无状态 reducer”(Stateless reducer)把 Agent 设计成从(事件日志 + 输入)→ 新状态的纯函数。真正的“状态”在你的存储层,Agent 本身易于水平扩展与回放。
上面 1→3→8→12 串起来,就是作者给的“理想循环”:LLM 选下一步(JSON)→ 确定性代码执行 → 结果入上下文/状态 → 循环直到 done。文档在 v1.1 草案里把这个循环的伪代码也写明了。
与《12-Factor App》的呼应
- “配置外置/版本化”在这套方法里对应 Prompt 与工具定义也要版本化;
- “日志即事件流”对应 把执行态与业务态统一进事件/存储;
- “无状态进程”对应 Agent 作为 reducer,状态留在外部。
这仓库里有什么
- 主文档(README + content/)**:阐述每个因子的动机与做法,并链接相关参考。
- workshops/ 与 packages/:用于实战演练/样例的目录。
- 版本信息:v1.0 已发布、v1.1 草案分支、跟踪 issue。
适配你的场景(前端/工作流/多媒体编辑)
结合你在 Next.js/React Flow/Node 流程编排与视频编辑里的实践,建议这样落地:
- 把“工具”先类型化(因子 1/4)为关键动作(转码、抽帧、TTS、LoRA 选择、任务编排)定义统一的 ToolCall JSON Schema(Zod/TypeScript 类型),LLM 只产出 intent + args,其余交给确定性代码。
- Prompt 归档与评测(因子 2)把 Prompt 放进 repo(分环境变量注入变体),对关键节点建立离线评测集(回放真实任务与边界 case),以 PR 门禁做 A/B 与回滚。
- 上下文工程(因子 3/9)把完整素材/日志放对象存储+DB,仅把紧凑摘要(失败原因、关键元数据、上一步产出)注入上下文。错误经“提炼器”压缩成结构化摘要再投喂模型。
- 状态统一与可回放(因子 5/12)把“聊天/工具调用/结果”作为同一事件流写入(如 Postgres+事件表或 Kafka),Agent 实现成从事件流 → 新事件的纯函数,可 100% 重放。
- 控制流外置(因子 8)把主流程建成显式状态机/有向图(你已有 React Flow),让 LLM 只在“不可枚举”的判定点起作用;失败/补偿走确定性分支。
- 人类在环(因子 7)把“需要审批/判读”的节点做成 request_human_review 工具,派发到你用的 IM/工单系统,回执进入同一事件流。
- 生命周期 API(因子 6/11)以 /agents/:id/{launch|pause|resume} + webhook/cron 触发器把 Agent 暴露出去:可在产品按钮、CI、消息流里触发与管控。
适用与局限
- 适用:你要强控制、可观测、可审计、能回放的生产级 Agent;不想被某框架限制。
- 局限:不是开箱即用的框架,胶水代码会多;因此社区才做了脚手架 create-12-factor-agent 来“搭骨架”,仍保留完全控制权。