配套视频:https://www.bilibili.com/video/BV1n8BHBdETL/

基于 Dex Horthy (HumanLayer) 在技术大会上的演讲整理


引言:开发者的困境与觉醒

在AI智能体开发的浪潮中,许多开发者都经历过相似的旅程:兴奋地选择一个流行框架,快速搭建出一个看起来很酷的智能体原型,向CEO演示时获得热烈掌声,甚至因此获得更多资源和团队成员。

但很快,现实的墙壁就会出现。

当你的智能体达到70-80%的质量水平时,你会发现再也无法前进。想要突破这个瓶颈,你不得不深入调用栈,逆向分析每一个提示词是如何构建的,工具是如何传递的,数据从何而来。最终,你可能会做出两个选择之一:要么彻底抛弃框架从零重构,要么意识到这根本不是一个适合用智能体解决的问题。

Dex Horthy 分享了他的一个早期案例:他试图构建一个运维智能体来处理 Makefile 构建流程。经过两小时的提示词优化,他得到了一个详尽到每个步骤都精确排序的指令集。然后他意识到:"我本可以用90秒写一个 Bash 脚本完成这件事。"

这个故事揭示了一个关键问题:不是每个问题都需要智能体

从实践中提炼的智慧

在与上百位创始人、开发者和工程师交流后,Dex 开始发现一些规律。他发现大多数真正运行在生产环境中的智能体并不像学术论文或营销材料中描述的那样"完全自主"。它们本质上仍然是软件,但有一些核心模式让它们表现得异常出色。

更重要的是,这些模式并不需要深厚的AI背景。它们是软件工程的基础原则在新场景下的应用——就像10年前 Heroku 定义了"云原生应用"的构建方式一样,现在我们需要为AI智能体定义类似的原则。

于是,12-Factor Agents 诞生了。

这个项目在GitHub上发布后迅速引起轰动:

  • 1-2个月内获得近4000星标

  • 在 Hacker News 首页停留一整天

  • 社交媒体上获得20万次曝光

  • 吸引了14位活跃贡献者

显然,这些想法触及了开发者社区的痛点。

核心理念:回归第一性原理

在深入具体要素之前,我们需要建立三个基本认知:

1. 智能体就是软件

这听起来显而易见,但却常被忽视。智能体不是某种神秘的、需要特殊对待的实体。它是软件,应该用软件工程的方法来构建、测试、部署和维护。

你会写 if 语句吗?会写 switch 语句吗?那你就能构建智能体。

2. 大模型是纯函数

大语言模型本质上是一个纯函数:token in → token out。给定相同的输入(包括温度等参数),它会产生确定性的输出分布。

这意味着什么?你的智能体的可靠性完全取决于你输入的 token 质量。除了重新训练模型,唯一能改变输出的方法就是谨慎选择输入。

3. 回归基础,重新思考

忘掉你对"智能体框架"的所有认知。我们需要从第一性原理出发,重新思考如何将软件工程的最佳实践应用到这个新领域。

十二要素详解

让我们深入探讨这些让智能体真正可靠的核心要素。为了在有限的时间内覆盖最重要的内容,我们会将一些相关要素组合讨论。

要素一:结构化输出是一切的基础

大语言模型最神奇的能力不是循环、不是条件判断、不是工具调用,而是将自然语言转换为结构化的JSON

用户输入:"帮我预订明天下午3点的会议室"

模型输出:
{
  "action": "book_room",
  "date": "2024-12-23",
  "time": "15:00",
  "duration": 60
}

这是其他所有功能的基础。一旦你能可靠地获得结构化输出,你就可以将其传递给确定性代码执行任何操作。

所谓的"工具调用",本质上就是:

  1. 大模型输出 JSON

  2. 你的代码解析这个 JSON

  3. 执行相应的确定性操作

  4. 可能将结果返回给模型

没什么特别的,就是 JSON + 代码

要素四 & 八:掌控你的控制流

这是最关键也最容易被框架抽象掉的部分。

传统方法的局限

长期以来,我们习惯于两种编程范式:

1. 有向无环图(DAG)
传统代码本质上就是 DAG。每次写 if 语句,你就在构建一个有向图。像 Airflow、Prefect 这样的编排工具也基于这个概念,将任务拆分为节点,提供一定的可靠性保障。

2. 极简循环
智能体的承诺是:你不需要预先定义所有路径,只需告诉模型目标,它会自己找到路径。

while not task_complete:
    next_action = llm.decide(context)
    result = execute(next_action)
    context.append(result)

这种方法简单直接,但有个致命问题:上下文窗口会无限增长

是的,你可以向 Gemini 输入200万个 token,API 也会返回结果。但没人会否认,通过控制和限制上下文窗口中的 token 数量,你能获得更紧密、更优质、可靠性更高的结果。

智能体的本质构成

一个真正可控的智能体需要四个核心组件:

1. 提示词(Prompt)
指示模型如何选择下一步行动的指令。

2. Switch 语句
处理模型输出的 JSON 并执行相应操作的代码。

action = llm_output["action"]

match action:
    case "call_api":
        result = api_client.call(llm_output["params"])
    case "ask_user":
        result = await get_user_input(llm_output["question"])
    case "complete":
        return llm_output["response"]

3. 上下文构建器
决定在每次调用时将什么信息传递给模型。

4. 循环控制
决定何时继续、何时中断、何时退出。

灵活性的力量

当你掌控了控制流,你就能实现许多强大的功能:

  • 中断与恢复:将状态序列化到数据库,稍后恢复

  • 切换策略:根据情况改变智能体行为

  • 智能总结:在上下文过长时让模型总结历史

  • 条件退出:基于业务逻辑而非仅依赖模型判断

这些灵活操作是构建生产级智能体的关键。

要素五 & 九:状态管理是可靠性的基石

智能体需要管理两种状态:

执行状态(Execution State)

这是智能体运行时的技术状态:

  • 当前在哪一步?

  • 下一步是什么?

  • 已经重试了几次?

  • 上下文窗口包含什么?

这类似于 DAG 调度工具的概念,但需要你自己实现。

业务状态(Business State)

这是应用层面的状态:

  • 发生了哪些消息交互?

  • 当前等待什么审批?

  • 向用户展示了什么数据?

  • 工作流处于什么阶段?

标准化操作

你应该能够像操作其他软件一样操作智能体:

# 启动
agent_id = agent.start(initial_event)

# 暂停
agent.pause(agent_id)

# 恢复
agent.resume(agent_id, new_data)

实现长时任务的关键技巧:

  1. 将智能体放在 REST API 或 MCP 服务器后面

  2. 当需要调用长时任务时,将上下文序列化到数据库

  3. 返回一个状态 ID

  4. 长时任务完成后,通过回调带着状态 ID 和结果返回

  5. 从数据库加载状态,将结果追加到上下文

  6. 继续执行

对智能体来说,这个过程是透明的——它不知道后台发生了什么,只是继续处理下一步。

要素二:拥有你的提示词

这是大多数开发者最先意识到的问题。

为什么这么重要?

记住:大模型是纯函数,输出完全由输入决定

在不重新训练模型的情况下,提升智能体可靠性的唯一方法就是谨慎选择输入的每一个 token。

从生成到手工

一开始,你可以用大模型生成提示词:

"帮我生成一个客服智能体的提示词,要求专业、友好、能处理退款请求..."

这能给你一个不错的起点,就像你上过"提示工程学校"一样。

但是,一旦你想突破某个质量门槛,你必须逐字手动编写

优化策略

你需要关注每一个细节:

  • 密度:用最少的 token 传达最多的信息

  • 清晰度:确保模型准确理解你的意图

  • 结构:使用标准格式(如 OpenAI 消息格式)或自定义格式

  • 迭代:测试多种变体,评估效果

我不知道哪个提示词更好,但我知道:尝试的越多,测试的参数越多,你就越有可能找到真正出色的结果

上下文设计的艺术

智能体的核心在于上下文设计。你需要组合:

  • 提示词:核心指令

  • 记忆:历史交互

  • 检索增强(RAG):相关知识

  • 实时数据:当前状态

关键是:如何将正确的信息以正确的方式输入模型,从而得到正确的答案

要素三:上下文窗口管理的艺术

这个要素有点争议,但与其他要素结合时威力巨大。

错误处理的陷阱

你遇到过这种情况吗?

智能体调用了一个错误的 API,或者 API 宕机了。你将错误信息放入上下文让它重试。然后它又失败了。你再次将错误放入上下文。如此循环...

最终,智能体要么"失控发疯",完全失去上下文,要么卡住不动。

正确的做法

不要盲目堆叠错误信息

当出错时,你应该:

  1. 清除所有待处理的错误

  2. 将错误汇总成简洁的描述

  3. 明确告诉模型当前状态和期望行为

# 错误的做法
context.append(f"Error: {error1}")
context.append(f"Error: {error2}")
context.append(f"Error: {error3}")

# 正确的做法
error_summary = summarize_errors([error1, error2, error3])
context = clean_context(context)
context.append(f"Previous attempts failed: {error_summary}. Please try a different approach.")

最佳实践

  • 梳理上下文,明确想告诉模型什么

  • 控制 token 数量以提升可靠性

  • 优化信息密度

  • 在关键时刻进行总结

记住:更长的上下文不等于更好的结果

要素六:人机协同的力量

这是一个微妙但强大的概念。

工具即通信渠道

传统上,我们认为"工具"是让智能体与外部世界交互的方式——调用 API、查询数据库等。

但还有一种工具常被忽视:联系人类

你可以将"与人沟通"作为一种工具,在自然语言层面表达意图:

{
  "action": "ask_human",
  "intent": "need_clarification",
  "question": "用户想要的是退款还是换货?",
  "context": {...}
}

这比简单的"调用工具或回复用户"二元选择要丰富得多。模型可以选择:

  • "我弄明白了,继续执行"

  • "需要澄清这个细节"

  • "这超出了我的权限,需要找经理"

  • "让我先确认一下用户的意图"

外循环智能体

将这个概念扩展,你可以构建"外循环智能体":

人们不想打开七个不同的 ChatGPT 风格的标签页。他们想在自己的工作场景中与智能体交互:

  • 邮件:智能体可以发送邮件询问,等待回复后继续

  • Slack/Discord:在团队协作工具中自然对话

  • 短信:在移动场景中快速交互

  • 工单系统:在现有流程中嵌入智能决策

关键是:从任意触发点连接用户,精准触达其所在场景

实际应用

HumanLayer 正在开发一个叫 a2h(agent-to-human)的协议来标准化这种交互。这让智能体能够:

  1. 在需要时暂停工作流

  2. 通过用户偏好的渠道联系人类

  3. 等待人类响应

  4. 将响应整合回工作流

  5. 继续执行

这种人机协同模式正在迅速普及,是构建真正有用的智能体的关键。

要素七 & 十:小型专注的智能体

我们已经讨论过为什么长循环智能体不可行。那么什么才有效?

微代理架构

真正在生产环境表现良好的是微代理(Micro-agents)

  • 高度确定性的 DAG 作为主干

  • 在关键决策点嵌入 3-10 步的小型智能体循环

  • 每个智能体有明确、专注的职责

实战案例:部署机器人

让我们看一个真实的例子——HumanLayer 的部署机器人:

第一阶段:确定性流程

GitHub PR 合并 → 触发 CI → 运行测试 → 测试通过

这部分完全是传统的 CI/CD 代码,确定性、可靠、快速。

第二阶段:智能决策

测试在开发环境通过后,系统将控制权交给智能体:

智能体收到事件:
{
  "type": "tests_passed",
  "pr": "#1234",
  "changes": ["frontend", "backend"]
}

智能体分析并提议:
{
  "action": "propose_deployment",
  "order": ["backend", "frontend"],
  "reasoning": "后端有 API 变更,需要先部署"
}

第三阶段:人工审批

提议发送到 Slack 频道,工程师可以:

  • 批准

  • 修改顺序

  • 取消

这是将自然语言转为 JSON 的过程:

工程师回复:"不,先部署前端"

转换为:
{
  "approved": true,
  "modified_order": ["frontend", "backend"]
}

第四阶段:执行与监控

智能体根据批准的方案执行部署,完成后回到确定性代码:

部署完成 → 运行端到端测试 → 测试通过 → 完成
                              ↓ 测试失败
                         触发回滚智能体

优势总结

这种架构的优势:

  • 可控的上下文:每个智能体循环只处理 3-10 步

  • 明确的职责:每个智能体知道自己该做什么

  • 可靠性高:确定性代码处理大部分流程

  • 灵活性强:在需要时引入人工判断

  • 可扩展:可以有 100 个工具,20 个步骤,轻松搞定

正如 Dex 在演讲中展示的,这个系统在他们的 Slack 频道中实际运行,效果非常好。

战略思考:如何找到你的优势

渐进式演进

不要试图一次性构建完美的智能体。采用渐进式方法:

第一步:从确定性工作流开始

用户请求 → 验证 → 处理 → 返回结果

第二步:在关键点引入大模型

用户请求 → [LLM: 理解意图] → 验证 → 处理 → 返回结果

第三步:逐步扩展智能能力

用户请求 → [LLM: 理解意图] → [LLM: 选择策略] → 处理 → [LLM: 生成响应]

第四步:随时间推移处理更复杂任务

最终,某些完整的 API 端点或流水线可能完全由智能体自动运行。

但关键是:你仍然需要知道如何优化这些设计以获得最佳效果

寻找前沿领域

Notebook LM 团队的成功给了我们一个启示:

他们找到了一些恰好处于模型可靠能力边界的任务——模型不能每次都做对,但如果你能找到让它做对的方法,并将可靠性融入系统,你就能创造出神奇的产品。

这就是你的机会所在:

  1. 找到模型的能力边界:什么任务它能做但不稳定?

  2. 深入优化:通过精心设计提示词、上下文、控制流

  3. 建立可靠性:让不稳定的能力变得稳定

  4. 创造价值:做出超越他人的产品

这需要你掌控模型的输入与输出,这也是为什么你需要拥有自己的控制流、提示词和上下文管理。

无状态设计原则

智能体应该是无状态的,类似于 reducer 或 transformer 模式:

def agent(state, event):
    """
    纯函数:给定状态和事件,返回新状态和动作
    """
    context = build_context(state, event)
    llm_output = llm.generate(context)
    new_state = update_state(state, llm_output)
    actions = extract_actions(llm_output)
    return new_state, actions

这种设计让你能够:

  • 轻松测试和调试

  • 序列化和恢复状态

  • 水平扩展

  • 时间旅行调试

工具与框架:正确的视角

这不是反框架的演讲

Dex 明确表示,他不是来抨击框架的。相反,12-Factor Agents 应该被视为:

  • 功能需求清单:框架应该满足这些需求

  • 愿望清单:如何让框架更好地服务开发者

  • 评估标准:选择工具时的参考

工具的正确角色

许多框架试图移除 AI 的复杂性,让你可以"不懂 AI 也能用"。

Dex 认为应该恰恰相反:

我们使用的工具应该消除其他难点,让我们能把所有时间都用在攻克 AI 难题上。

你应该专注于:

  • 优化提示词

  • 确保控制流正确

  • 精心设计上下文

  • 选择正确的 token

工具应该帮你处理:

  • 状态持久化

  • API 管理

  • 日志和监控

  • 部署和扩展

Create-12 项目

基于这个理念,HumanLayer 正在开发 Create-12 项目。

它不是一个框架,而是像 shadcn 那样的脚手架

npx create-12-agent my-agent

这会生成:

  • 基础项目结构

  • 示例代码

  • 最佳实践模板

然后,代码完全属于你。你可以随意修改、优化、重构。

这才是智能体开发真正需要的:不是抽象掉复杂性,而是给你一个好的起点,让你掌控一切。

关键洞察:那些容易被忽视的真相

"工具"的真正含义

当我们谈论"工具调用"时,很容易被营销话术迷惑,以为这是某种神奇的能力。

实际上:

  1. 大模型输出 JSON

  2. 你的代码解析 JSON

  3. 执行确定性操作

  4. 可能将结果返回

就这么简单。JSON + 代码,没什么特别的。

理解这一点很重要,因为它让你意识到:你不需要依赖框架的"工具系统",你可以自己实现,并且完全按照你的需求定制。

不是所有问题都需要智能体

记住 Dex 的 Makefile 故事吗?

经过两小时的提示词优化,他得到了一个完美的构建流程智能体。然后他意识到:这本可以用 90 秒写一个 Bash 脚本完成。

判断标准:

适合用智能体:

  • 需要理解自然语言

  • 决策路径不确定

  • 需要处理边缘情况

  • 涉及人机交互

不适合用智能体:

  • 流程完全确定

  • 可以用简单脚本实现

  • 不需要语言理解

  • 性能要求极高

不要为了用 AI 而用 AI。

质量门槛的真相

有一个残酷的真相:

从 0 到 70% 很容易,从 70% 到 90% 需要 10 倍努力,从 90% 到 99% 需要 100 倍努力。

当你想突破某个质量门槛时:

  • 每个 token 都要关注

  • 每个提示词都要手工优化

  • 每个边缘情况都要处理

  • 每个假设都要测试

这就是为什么你需要完全掌控你的智能体。框架可以帮你快速到达 70%,但剩下的 30% 需要你自己动手。

实践建议:立即可行的行动

核心原则回顾

让我们回顾一下最重要的原则:

  1. 智能体就是软件

  • 用软件工程方法构建

  • 不要被"AI"吓到

  • 你已经有需要的技能

  1. 大模型是无状态函数

  • 输入决定输出

  • 关注上下文质量

  • 每个 token 都重要

  1. 掌控状态与流程

  • 不要依赖黑盒

  • 自己管理状态

  • 灵活性是关键

  1. 找到前沿领域

  • 寻找模型能力边界

  • 通过优化超越他人

  • 创造独特价值

  1. 智能体与人协作

  • 不要追求完全自主

  • 在关键点引入人工

  • 设计好交互界面

  1. 自己动手

  • 至少目前需要这样

  • 理解每个细节

  • 不断迭代优化

行动清单

如果你准备开始构建可靠的智能体,这里是你的行动清单:

📚 学习资源

🛠️ 技术准备

  • 评估你当前的智能体架构

  • 识别哪些部分需要更多控制

  • 开始手动编写关键提示词

  • 实现状态管理系统

🤝 社区参与

  • 加入 HumanLayer 社区

  • 探索 a2h(agent-to-human)协议

  • 分享你的实践经验

  • 贡献到 12-Factor Agents 项目

🚀 实践项目

  • 选择一个小型、专注的用例

  • 从确定性工作流开始

  • 在关键点引入智能决策

  • 迭代优化,测量改进

📊 持续改进

  • 建立评估指标

  • A/B 测试不同提示词

  • 收集用户反馈

  • 优化上下文设计

结语:软件工程的新前沿

在演讲的最后,Dex 说了一段让人印象深刻的话:

"智能体就是软件,你们都能开发软件。有人写过 switch 语句吗?很好,这些我们都能实现。大模型是无状态函数,只需确保将正确的内容放入上下文中,你将获得最佳效果。掌控状态与流程,找到前沿领域,通过精心优化超越他人。"

这段话概括了整个演讲的精髓:回归软件工程基础,掌控每个细节,构建真正可靠的智能体应用。

AI 智能体不是魔法,不是黑盒,不是需要特殊技能的神秘领域。它是软件工程的新前沿,需要我们将已有的知识和技能应用到新的场景中。

10 年前,Heroku 定义了云原生应用的 12 要素。今天,我们正在定义 AI 智能体的 12 要素。这不是终点,而是起点。

随着更多开发者的实践和贡献,这些原则会不断演进和完善。但核心理念不会变:掌控你的代码,理解你的系统,构建可靠的软件。

现在,轮到你了。

去构建吧。去实验吧。去突破那些质量门槛吧。

然后,分享你的经验,帮助这个社区成长。

因为最终,我们都在一起推动这个领域向前发展


附录:资源链接


本文基于 Dex Horthy 在技术大会上的演讲整理,完整视频请查看原始字幕文件。

如果这篇文章对你有帮助,请考虑为 12-Factor Agents 项目点个星,并分享给更多开发者。


#AI编程 #VibeCoding #智能体 #ClaudeCode #独立开发者 #AI创业 #一人公司 #程序员 #软件工程师 #软件工程


Work Less, Earn More, Enjoy Life.