Hotdry.

Article

生产级 LLM 应用的十二要素原则:从框架依赖到可控架构

12-Factor Agents 提出了一套面向生产环境的 LLM 应用架构原则,强调确定性工作流、人机协作设计与优雅降级,帮助开发者跳出框架陷阱,构建真正可交付的 AI 系统。

2026-05-19ai-systems

引言:当 Agent 框架遇上生产环境

在 LLM 应用开发的浪潮中,一个令人困惑的现象正在浮现:开发者们热衷于使用各种 Agent 框架(从 LangChain 到 CrewAI 再到 SmolAgents)快速搭建原型,却在接近生产部署时陷入瓶颈。HumanLayer 团队近期开源的 12-Factor Agents 项目(GitHub 获 21k+ stars)正是针对这一痛点,提出了一套借鉴经典 12-Factor App 方法论的生产级架构原则。

该项目的核心洞察颇为犀利:大多数真正投入生产的 AI Agent 并非如宣传般 "完全自主",而是由确定性代码构成骨架,仅在关键决策点让 LLM 介入。这种 "LLM 点缀式" 架构与主流框架倡导的 "给模型一个目标 + 工具包,让它自己循环直到完成" 的模式形成鲜明对比。

核心洞察:为什么 80% 的质量门槛难以跨越

HumanLayer 团队在与上百位 SaaS 构建者(多为技术创始人)交流后发现了一条典型的开发路径:

  1. 确定要构建 Agent → 2. 产品设计 → 3. 选用框架快速开发 → 4. 达到 70-80% 质量 → 5. 发现不足以面向客户 → 6. 反向工程框架内部机制 → 7. 从头重建

问题的根源在于,框架为了提供 "开箱即用" 的体验,往往将提示词、控制流、状态管理等关键要素封装在抽象层之下。当开发者需要针对特定场景调优时,不得不深入框架内部,最终发现从零构建反而更可控。

12-Factor Agents 的理念是:将 Agent 构建中的模块化概念(如自然语言到工具调用、人机协作接口、错误自我修复)提取出来,以可控方式集成到现有产品中,而非全盘接受某个框架的预设架构。

关键原则详解

原则一:自然语言到工具调用(原子化转换)

这是 Agent 最基础也最核心的模式:将用户的自然语言请求转换为结构化的工具调用。关键在于原子化—— 每个转换应该是单一、明确的任务。

例如,将 "为 Terri 创建 750 美元的赞助付款链接" 转换为 Stripe API 调用:

{
  "function": {
    "name": "create_payment_link",
    "parameters": {
      "amount": 750,
      "customer": "cust_128934ddasf9",
      "memo": "二月 AI 爱好者聚会赞助费"
    }
  }
}

实施要点:LLM 只负责生成结构化意图,实际的 API 调用由确定性代码执行。这种分离让系统既保持灵活性(自然语言理解),又确保可靠性(确定性执行)。

原则七:通过工具调用联系人类

生产级 Agent 必须能够优雅地请求人类介入。12-Factor Agents 建议将 "联系人类" 也抽象为一种工具调用,而非在控制流中硬编码特殊逻辑。

class RequestHumanInput:
  intent: "request_human_input"
  question: str
  context: str
  options: {
    urgency: Literal["low", "medium", "high"],
    format: Literal["free_text", "yes_no", "multiple_choice"]
  }

这种模式的优势在于:

  • 清晰的指令:不同类型的联系人类工具可以携带特定的元数据
  • 支持外循环(Outer Loop):Agent 可以由定时任务或事件触发,主动发起人机交互
  • 多 Agent 协作:同样的抽象可扩展为 Agent 间通信

原则八:拥有你的控制流

这是生产级 Agent 与原型最关键的区别之一。拥有控制流意味着你可以在工具选择工具调用之间插入暂停点,实现人工审核、异步等待或自定义逻辑。

def handle_next_step(thread):
  while True:
    next_step = await determine_next_step(thread)
    
    if next_step.intent == 'request_clarification':
      await send_message_to_human(next_step)
      await db.save_thread(thread)
      break  # 暂停,等待 webhook 恢复
    
    elif next_step.intent == 'deploy_backend':
      await request_human_approval(next_step)  # 高风险操作需人工确认
      await db.save_thread(thread)
      break
    
    elif next_step.intent == 'fetch_open_issues':
      issues = await linear_client.issues()
      thread.events.append({"type": "fetch_result", "data": issues})
      continue  # 同步步骤,继续循环

关键能力:在工具选择和调用之间中断并恢复,这是实现人工审核、审批流程的基础。

原则九:将错误压缩到上下文窗口

Agent 的一大优势是 "自我修复"—— 当工具调用失败时,LLM 可以读取错误信息并在后续调用中调整。但需要注意防止 "错误螺旋"(反复犯同样错误)。

推荐实现模式:

consecutive_errors = 0

while True:
  next_step = await determine_next_step(thread)
  try:
    result = await handle_next_step(thread, next_step)
    consecutive_errors = 0  # 成功后重置计数器
  except Exception as e:
    consecutive_errors += 1
    if consecutive_errors < 3:
      thread.events.append({"type": "error", "data": format_error(e)})
      continue  # 将压缩后的错误加入上下文,尝试修复
    else:
      break  # 超过阈值,升级至人工处理

可落地参数:建议设置连续错误阈值(如 3 次),超过后触发人工介入或降级策略。

实施建议与检查清单

基于 12-Factor Agents 的原则,以下是构建生产级 LLM 应用的实用建议:

架构层面

  • 将 LLM 调用视为 "决策点" 而非 "执行引擎",确定性代码负责实际执行
  • 统一执行状态与业务状态,确保 Agent 可暂停、恢复、审计
  • 保持 Agent 无状态(stateless reducer),状态由外部存储管理

人机协作

  • 为高风险操作(如部署、支付、数据删除)设计强制人工审核节点
  • 支持多种人类交互模式(是 / 否、多选、自由文本)
  • 设计 "外循环" 场景:Agent 可由事件触发,主动向人类发起交互

错误处理

  • 实现带重试限制的自我修复机制(建议最大 3 次)
  • 错误信息需压缩后再加入上下文,避免占用过多 token
  • 定义明确的升级路径:当自动修复失败时如何转交人工

控制流

  • 在工具选择和调用之间预留扩展点,支持异步等待
  • 拥有提示词和上下文构建逻辑,不依赖框架的默认实现
  • 设计小而专注的 Agent,而非大而全的通用 Agent

总结

12-Factor Agents 并非要否定现有框架的价值,而是提供了一套从原型到生产的进化路径。其核心启示在于:真正可靠的 LLM 应用不是让模型承担更多责任,而是通过精心设计的架构让模型的能力在正确的地方发挥作用

正如项目作者 Dex 所言,"最快的路径是将 Agent 构建中的模块化概念提取出来,以可控方式集成到现有产品中"。对于正在从原型走向生产的团队而言,这 12 条原则提供了一份务实的检查清单,帮助避开 "框架陷阱",构建出真正可交付的 AI 系统。

参考资料

ai-systems

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com