第六阶段:AI项目实战与生产部署
构建可用于生产环境的LLM驱动软件的12个核心原则,专注于解决AI应用从原型到生产的关键工程挑战
12 Factor Agents - 构建可靠LLM应用的12个原则
概述
12 Factor Agents 是一套构建可用于生产环境的LLM驱动软件的原则方法论,由 Dex Horthy 和 HumanLayer 团队开发。
背景与动机
为什么需要这套原则?
作者在与100多位SaaS构建者(主要是技术创始人)交流后发现,大多数AI Agent开发都会遇到"70-80%质量瓶颈":
- 初期快速进展:使用现有框架快速达到70-80%的功能
- 质量瓶颈:发现80%对于面向客户的功能还不够好
- 框架限制:要突破80%需要逆向工程框架、提示词、流程等
- 从头开始:最终不得不抛弃框架重新开始
核心洞察
- 大多数成功的生产级"AI Agent"实际上并不那么"智能体化"
- 它们主要是精心设计的软件系统,在关键点巧妙地使用LLM
- 最快让客户使用高质量AI软件的方法是采用小而模块化的概念,并将其整合到现有产品中
12个核心原则
Factor 1: Natural Language to Tool Calls
自然语言转换为工具调用
LLM的核心超能力是将自然语言转换为结构化数据(JSON)。一切Agent操作都应该从这个基础转换开始。
// 核心模式
const response = await llm.generateToolCall(userMessage, availableTools);
// response 是结构化的 JSON,不是自由文本
Factor 2: Own your prompts
拥有你的提示词
将提示词视为关键的、版本控制的代码资产,而不是一次性输入。
- 在应用程序代码库中管理提示词
- 支持系统性测试、部署和回滚
- 确保一致性、可重现性和可控演进
Factor 3: Own your context window
拥有你的上下文窗口
主动并有意地管理LLM的上下文窗口。
- 确保上下文窗口只包含与当前任务直接相关的信息
- 修剪不必要的数据以防止"上下文漂移"
- 提高LLM性能,减少token使用
Factor 4: Tools are just structured outputs
工具就是结构化输出
将"工具"视为LLM输出的结构化JSON,并进行验证。
// 工具调用只是JSON schema验证
const toolCall = validateToolCall(llmOutput, toolSchema);
const result = await executeValidatedTool(toolCall);
Factor 5: Unify execution state and business state
统一执行状态和业务状态
确保LLM的内部"执行状态"与应用程序的实际"业务状态"保持一致。
- 防止LLM基于过时或错误信息操作
- 避免幻觉或无效操作
- 将执行状态持久化在业务状态旁边
Factor 6: Launch/Pause/Resume with simple APIs
通过简单API启动/暂停/恢复
设计具有清晰编程接口的LLM代理,支持生命周期管理。
interface AgentControl {
launch(config: AgentConfig): Promise<AgentInstance>;
pause(instanceId: string): Promise<void>;
resume(instanceId: string): Promise<void>;
}
Factor 7: Contact humans with tool calls
通过工具调用联系人类
将人类交互作为一等公民的工具调用来处理。
- 高风险步骤路由给人类审核
- 人类反馈作为结构化输入返回系统
- 无缝的人机协作流程
Factor 8: Own your control flow
拥有你的控制流
将控制流保持在普通代码或自己的工作流引擎中。
- 运行显式的OODA循环(观察-定向-决策-行动)
- 使用收敛启发式而不是嵌套提示
- 避免让LLM管理复杂的控制流
Factor 9: Compact Errors into Context Window
将错误压缩到上下文窗口
将错误信息压缩到下一个提示中以关闭反馈循环。
- 让LLM能够从错误中学习和恢复
- 提供结构化的错误信息
- 支持自我修复能力
Factor 10: Small, Focused Agents
小而专注的Agent
构建小型、单一用途的代理,而不是庞大的单体聊天机器人。
// 好的做法:专注的小Agent
class EmailSummaryAgent {
async summarize(email: Email): Promise<Summary> { /* ... */ }
}
class PriorityClassificationAgent {
async classify(email: Email): Promise<Priority> { /* ... */ }
}
Factor 11: Trigger from anywhere, meet users where they are
从任何地方触发,在用户所在的地方提供服务
从用户已经工作的地方触发代理:CLI、webhook、cron等。
- 集成到现有工作流程
- 多种触发机制
- 用户友好的访问点
Factor 12: Make your agent a stateless reducer
让你的Agent成为无状态的reducer
应用程序管理状态,Agent保持无状态。
// 无状态Agent模式
class StatelessAgent {
step(state: State): Promise<State> {
}
}
技术架构模式
核心循环简化
每个Agent本质上都归结为:
const prompt = "Instructions for next step selection";
const switchFunction = (json) => routeToFunction(json);
const context = manageWhatLLMSees();
const loop = whileNotDone();
与传统DAG的区别
- 传统DAG:软件工程师编码每个步骤和边缘情况
- Agent方法:给Agent一个目标和一组转换,让LLM实时决策路径
- 实际情况:最成功的实现是在更大的确定性DAG中巧妙地使用Agent模式
适用场景
最适合的场景
- 需要自然语言理解的结构化任务
- 需要人机协作的工作流程
- 复杂的多步骤业务流程
- 需要高可靠性的生产环境
不适合的场景
- 简单的确定性任务(直接写代码更好)
- 需要100%准确性的关键任务
- 资源极度受限的环境
实现建议
渐进式采用
- 从小处开始:选择一个与当前挑战相关的原则
- 实施并观察:看到改进效果
- 逐步添加:然后添加另一个原则
- 持续优化:不断完善和调整
技术栈推荐
- 语言:TypeScript(作者推荐,也支持Python等其他语言)
- 关键库:BAML(用于schema对齐解析)
- 部署:支持云原生和Kubernetes
相关资源
官方资源
扩展阅读
- Building Effective Agents (Anthropic)
- 12 Factor Apps原始方法论
- Function Calling vs Structured Outputs vs JSON Mode
总结
12 Factor Agents提供了一个系统性的方法来构建真正可用于生产环境的LLM应用。它强调的不是建立更神奇的框架,而是将更好的软件工程实践应用于LLM能力。记住核心理念:Agent就是软件,按软件来对待它们,它们会以可靠性、可维护性和竞争对手无法匹敌的能力回报你。