基于状态机的简约Agent架构

Agent ≠ 魔法,告别框架黑箱,拥抱状态机

你是否也走过这样一条路?

  1. 你想做一个 Agent,解决一个具体问题。
  2. 你兴奋地规划产品,设计交互,满怀期待。
  3. 为了"快",你一把抄起市面上最火的 Agent 框架,pip install,然后闷头"构建"。
  4. 你很快做出了一个看起来还不错的 Demo,达到了 70-80 分。
  5. 但当你尝试把产品推向真实用户时,才发现这 80 分远远不够。那剩下的 20 分,像一道天堑。
  6. 为了跨过这道天堑,你开始疯狂调试,逆向工程框架的 prompt、深入它复杂的调用链,试图搞懂它到底在"黑箱"里做了什么。
  7. 最后,在某个深夜,你精疲力尽,决定从头再来。

我已经对那些动辄上万行代码的框架失去了兴趣。本文试着基于软件的本质--状态机,构建一个极简但是有效的Agent架构。

LLM 是无状态函数

让我们先放下所有复杂的框架和概念,回到原点,凝视我们的核心"组件"------那个大语言模型(LLM)。

它到底是什么?

LLM 是无状态函数。 LLMs are stateless functions

什么意思?它就像一个记忆力只有七秒的、拥有超级大脑的天才。你每次调用它,都是一次全新的开始。它不记得你上一秒说了什么。我们之所以感觉它有记忆,是因为我们调用LLM API时候,将整个聊天历史又重新发给了它一遍。

如果 LLM 本身是无状态的,那么状态(State)就必须由我们自己来管理 。如果 LLM 的所有决策都只依赖于它在调用瞬间所看到的"世界",那么构建这个世界(Context Engineering)就成了我们唯一能做的事情

Context is everything

上下文,就是你唯一能够撬动 LLM 能力的那个支点。我们所有的工程努力,都应该围绕着如何为 LLM 精心构建每一次交互的上下文展开。

一个常规的context包含下面部分:

  • 指令:你要它扮演什么角色,遵守什么规则,目标任务是什么。常规prompt。
  • 外部信息 :背景信息或者要求LLM参考的信息
  • 工具调用:告诉它哪些外部工具可以使用,以及工具使用的结果
  • 相关记忆 (Memory):之前聊天的对话历史(短期记忆)。用户的长期偏好、要求被记住的事实和观点等(长期记忆)
  • 输出要求:限制输出范围,例如输出的格式要求、字数要求、语言风格等

context是LLM看到的全部世界。context是否清晰、准确、信息充沛决定了LLM返回的质量。Garbage in, garbage out.

在你觉得AI反馈不好的时候,你需要先考虑在当前上下文情况下,AI是否有可能完成任务?

这里还有一些我在实践中发现的小技巧:

其一,用 XML/YAML 代替 JSON,跟模型说"人话"

我们工程师很喜欢 JSON,但 LLM 未必。那些大括号、引号、逗号对它来说,其实是一种很"重"的认知负担。

我发现,在很多场景下,用更接近自然语言的XML格式,效果出奇地好。

xml 复制代码
  <function_call>
    <tool_name>check_availability</tool_name>
	    <parameters>
		      <room>观星阁</room>
		      <time>15:00</time>
	    </parameters>
  </function_call>

为什么这样更好?

  1. 对注意力机制更友好 (Attention-Friendly): 清晰的 XML 标签就像文章的标题,能天然地引导 LLM 的注意力,让它更容易抓住关键信息。(注意力引导非常重要,attention是LLM的底层机制)
  2. 容错性更高: 相比 JSON 那种"少一个逗号就全盘崩溃"的严格语法,这类格式的容错性要好得多。
  3. Token 更省: 通常比带有很多引号和括号的 JSON 更紧凑。

其二,打破 user/assistant/tool 的枷锁 别被传统的 user/assistant/tool 消息格式束缚。 上下文窗口是 LLM 的全部世界,你怎么"排版"这个世界,至关重要。不要让LLM在一堆散乱的 user/assistant 消息里费力地寻找线索。 你可以大胆地用 XML 标签、YAML、或者任何你自定义的格式来组织对话记录、工具调用,让信息密度更高,对模型更友好。你也不需要局限在OpenAI提供的标准function call格式里面,你可以参考Claude的system prompt的设计,很轻松实现更为简约有效的function call机制。

总之,核心要旨是:组织一个对LLM来说,更清晰、明确、容易理解的上下文。

状态机

软件的本质是状态机 。程序运行,是从一个确定的状态,通过一个明确的动作,迁移到下一个状态的过程。

这个软件哲学,在 Agent 时代,依然是我们手中最可靠的工具。 我们可以用它来清晰地定义一个 Agent 的核心循环:

当前状态 (State) -> 上下文构建 (Context) -> LLM 决策 (LLM) -> 动作执行 (Action) -> 新状态 (New State) 我们来分解这个循环的每一个阶段:

  1. State (状态): 系统的状态,由一个事件列表 (Event Stream) 来表示。这是一个简洁的列表,记录了从交互开始到现在的所有事件,例如用户的请求、工具的调用结果、Agent 自己的思考......State 就是所有这些事件的集合。

  2. Context (上下文构建): 在调用 LLM 之前,一个 ContextBuilder 函数会介入。它的唯一职责是:读取当前的 State (事件列表),构建一个完善的上下文,作为 LLM 的输入。这份上下文包含了指令、相关历史、可用的工具、输出格式要求等。这是我们唯一可以控制 LLM 输入的地方。

  3. LLM (决策): 我们将精心构建的 Context 提交给 LLM。LLM 的任务不是直接生成最终回复,而是决策出下一步,比如"调用某个工具"或"回复用户"。

  4. Action (执行): 我们的代码拿到LLM的反馈,执行相应的、确定性的逻辑。调用 API、查询数据库、返回消息给用户......这些都是我们 100% 可控的。

  5. New State (状态更新): Action 执行后会产生一个结果。这个结果被包装成一个新的"事件"对象,并追加到事件列表的末尾。这样,系统就从 State 迁移到了 New State

在这个架构里,LLM 的角色被严格限定在其最擅长的领域:基于上下文进行推理和决策。而系统的其他部分------状态管理、业务逻辑执行------则完全由我们自己的、可预测的代码来控制。

传统的编程,状态转移的逻辑是我们手写的;而在这个模型里,状态转移的决策逻辑,被外包给了 LLM。 这是最核心的变化。

模块化扩展:工具与记忆

当你拥有了上面那个坚实的状态机"底盘"后,扩展 Agent 的能力就变得非常清晰。

需要 Agent 调用外部 API?那就为它设计一个"工具 (Tool)"模块。

需要 Agent 记住长期的对话上下文?那就为它实现一个"记忆 (Memory)"模块。

这两个模块,不再是独立于系统之外的黑箱,而是这个状态机架构下的标准化组件。

  • 工具箱的设计与实现:它需要一套标准的接口,能让 Agent 在"上下文构建"阶段,向 LLM 声明其能力。它的调用和返回结果,都以标准化的"事件"形式,融入到我们的主循环中。

  • 记忆模块的实现 :它负责在"上下文构建"阶段,根据当前情境,从完整的历史记录中提取最相关的部分。一个好的记忆模块,可以借鉴生物大脑的设计,将其划分为处理当前对话的短期记忆 ,和存储核心事实与用户偏好的长期记忆

尾声:凝视未来

我们今天所讨论的这套架构,它的哲学是清晰的:人驾驭 AI

我们用我们最熟悉的、确定性的软件工程框架,为 LLM 这个强大的不确定性引擎,套上了一个可靠的"缰绳",划定了一个清晰的"围栏"。方向盘和刹车,始终牢牢掌握在我们自己手里。

这是一种务实且安全的路径。但,它会是唯一的终局吗?

我们可以预见,还存在着另一条截然不同的路径:AI 作为平台

在这条路径上,当未来的模型足够强大和可靠时,我们可能不再需要自己去维护那个精巧的状态机。LLM 内核本身就拥有了管理自身状态、规划复杂任务、甚至自我认知优化的能力。

那时,我们工程师的角色,可能会从今天的"系统建筑师",转变为纯粹的"工具匠"。我们的核心工作,不再是编排复杂的业务逻辑,而是为这个 AI 平台,打造一套精良的、原子化的、高可用的工具集(APIs)。我们提供工具和说明书,AI 自己决定何时、何地、如何使用它们来达成我们设定的高层目标。

那将是一个彻底解放生产力的世界,也是"AI失控"最不确定的时代。只是回到今天,构建一个自己的Agent没那么困难,希望本文能给你一个参考。

参考文献:

langchain 上下文工程兴起

《12 Factor Agents》

状态机的思维学习自JYY老师《操作系统》课程 (感谢JYY老师的启蒙)

本文GitHub仓库:simple_agent

微信公众号 秋水东行

相关推荐
Sherlock Ma几秒前
字节跳动GR-3:可泛化、支持长序列复杂操作任务的机器人操作大模型(技术报告解读)
人工智能·计算机视觉·语言模型·机器人·大模型·aigc·具身智能
蚝油菜花2 分钟前
将GLM 4.5接入Claude Code,打造最具性价比的AI工程师
人工智能·ai编程·claude
字节跳动数据平台13 分钟前
企业落地 Data Agent,一共需要几步?
大数据·agent
涛思数据(TDengine)30 分钟前
时序数据库厂商 TDengine 发布 AI 原生的工业数据管理平台 IDMP,“无问智推”改变数据消费范式
大数据·运维·数据库·人工智能·tdengine
那年一路北35 分钟前
Deforum Stable Diffusion,轻松实现AI视频生成自由!
人工智能·stable diffusion·音视频
正经教主39 分钟前
【n8n】如何跟着AI学习n8n【02.5】:第一部分总练习
人工智能·学习·教程·n8n
sky丶Mamba1 小时前
LangChain和LangGraph 里面的 `create_react_agent`有什么不同
langchain·agent·langgraph
CV工程师丁Sir1 小时前
Vibe Coding vs 规范驱动开发:AI 时代编程范式的冲突与融合
人工智能·驱动开发
移远通信1 小时前
不止 “听懂”,更能 “感知”!移远通信全新AI 音频模组 重新定义智能家居“听觉”逻辑
人工智能·音视频·智能家居
掘金酱1 小时前
🎆仲夏掘金赛:码上争锋,金石成川 | 8月金石计划
前端·人工智能·后端