基于状态机的简约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

微信公众号 秋水东行

相关推荐
AwhiteV25 分钟前
利用图数据库高效解决 Text2sql 任务中表结构复杂时占用过多大模型上下文的问题
数据库·人工智能·自然语言处理·oracle·大模型·text2sql
Black_Rock_br41 分钟前
AI on Mac, Your Way!全本地化智能代理,隐私与性能兼得
人工智能·macos
墨风如雪1 小时前
拆解Seed-OSS-36B:不只是参数怪兽,更是优雅的控制大师
aigc
☺����1 小时前
实现自己的AI视频监控系统-第一章-视频拉流与解码2
开发语言·人工智能·python·音视频
fsnine2 小时前
机器学习——数据清洗
人工智能·机器学习
小猿姐2 小时前
KubeBlocks AI:AI时代的云原生数据库运维探索
数据库·人工智能·云原生·kubeblocks
算法_小学生2 小时前
循环神经网络(RNN, Recurrent Neural Network)
人工智能·rnn·深度学习
吱吱企业安全通讯软件3 小时前
吱吱企业通讯软件保证内部通讯安全,搭建数字安全体系
大数据·网络·人工智能·安全·信息与通信·吱吱办公通讯
盲盒Q3 小时前
《频率之光:共振之战》
人工智能·硬件架构·量子计算
飞哥数智坊3 小时前
DeepSeek V3.1 发布:我们等的 R2 去哪了?
人工智能·deepseek