做 AI Agent 时,我终于搞懂了 Tracker 的真正作用

大家好,我是大煊,一个写了几年 Java,最近在啃 AI Agent 的后端。

相信很多朋友都听过 Memory、RAG,今天来聊聊 Tracker(追踪器)。它的作用也和"记忆"有关,但不是怎么让模型多记几句话,而是一个更工程化的场景:当 Agent 开始接业务任务时,怎么保存它执行到哪一步了?

记忆不是只有 Memory 和 RAG

我刚开始看 Agent 记忆这块,也有一个很自然的误解:

是不是加一个 Memory,把历史上下文存起来,就算 Agent 有记忆了?

再往后看 RAG,又会觉得:

那我把历史对话、用户资料、业务知识都丢进向量库,需要的时候检索一下,不就解决了吗?

后来按客服 Agent 的业务链路拆开看,才发现这事没那么简单。

Memory 更像"长期印象"。

RAG 更像"查资料"。

但 Tracker 解决的是另一件事:当前这件事进行到哪一步了。

所以这篇真正想聊的不是"怎么让模型多记几句话"。

而是:当 Agent 开始接业务任务时,系统里有没有一个地方,专门保存它执行到哪一步了?

这就是 DialogueStateTracker 的价值:它不是让模型更聪明,而是让系统自己别忘事。

我更愿意把它理解成:Agent 的运行时状态中心。

这张图是这篇的核心:LLM 不是状态中心,Tracker 才是。LLM 负责理解和表达,业务动作交给 Tool,状态交给 Tracker。

一个客服请求,背后其实是一串状态变化

拿"查订单"举例。

text 复制代码
用户:我要查订单
Agent:请提供订单号
用户:123456
Agent:您的订单已发货

但系统背后发生的是:

sequenceDiagram participant User as 用户 participant Agent as Agent Runtime participant Tracker as Tracker participant LLM as LLM participant Tool as 订单系统 User->>Agent: 我要查订单 Agent->>Tracker: 记录用户消息 Agent->>LLM: 判断意图 LLM-->>Agent: query_order Agent->>Tracker: 开启查订单流程 Agent-->>User: 请提供订单号 User->>Agent: 123456 Agent->>Tracker: 记录订单号 Agent->>Tool: 查询订单 Tool-->>Agent: 已发货 Agent->>Tracker: 写入订单状态 Agent-->>User: 您的订单已发货

这张图里,LLM 只负责理解和表达。

真正让系统跑起来的,是 Tracker 在旁边不断记录:

text 复制代码
当前意图是什么
当前流程是什么
哪些信息已经收集
哪个工具已经调用
工具结果是什么
下一步应该做什么

没有这些状态,Agent 就会变成一个"每轮都像第一次见你"的聊天窗口。

Tracker 到底存什么?

我现在会把 Tracker 拆成五类东西。

Tracker 里的东西 白话解释 客服例子
对话历史 用户和 Agent 说过什么 "我要查订单""请提供订单号"
槽位 Slots 业务字段 order_id=123456
流程 Flow 任务走到哪一步 正在查订单 / 正在退款
最近动作 上一步执行了什么 刚调用订单查询
序列化状态 能不能保存和恢复 服务重启后继续处理

Tracker 不像"记忆力",更像一个带生命周期的对话上下文。

Controller、Service、Action、LLM 不要各自记一份状态。

大家都读写同一个 Tracker。

这就是统一状态源的价值:别让每个模块各记各的,不然一复杂就会互相打架。

还有一个小点也挺关键:Tracker 不是把所有历史都塞给 LLM。

它可以保存完整状态,但真正喂给模型的,通常只是一部分对话历史和必要业务信息。剩下的槽位、工具结果、流程状态,更多是给程序自己判断下一步用的。

Slot(槽位):把聊天里的关键信息变成业务字段

客服 Agent 最怕一件事:

用户明明说了订单号,系统后面却用不上。

原因很简单:自然语言历史不是业务字段。

用户说:

text 复制代码
我的订单号是 123456

系统真正需要的是:

text 复制代码
order_id = 123456

这就是 Slot(槽位)。

Slot 有点像表单字段。

退款要订单号,改地址要新地址,贷款要金额,人工转接要问题类型。

这些都应该从聊天里沉淀成结构化字段。

但这里有个边界很重要:

信息来源 谁来写入 例子
用户说出来的信息 LLM 可以提取 订单号、地址、退款原因
系统查出来的信息 Action 写入 订单状态、退款结果、会员等级

这件事不能混。

LLM 可以帮你理解"用户说了什么",但不要让它凭感觉决定"订单是否发货"。

订单状态必须来自订单系统。

这张图的重点是边界:理解归 LLM,事实归业务系统。

到这里,Tracker 已经不只是"聊天记录"了。它开始变成当前任务状态的容器。

Tracker 和 Memory 不是一回事

前面已经说了 Memory / RAG / Tracker 的区别,这里再从生命周期看一眼。

模块 解决的问题 例子
Tracker 当前这件事做到哪了 正在退款,已收集订单号
Memory 这个用户长期是什么样 喜欢中文、偏好某品牌
Knowledge Base 企业知道什么 退款规则、商品说明

这三类东西生命周期完全不同。

Tracker 里的"当前退款到确认金额"可能 10 分钟后就没用了。

Memory 里的"用户喜欢中文回复"可能几个月后还有效。

Knowledge Base 里的"退款政策"属于企业公共知识,不应该混进某个用户会话。

边界不清,Agent 项目越做越乱。

这张图我会贴在所有 Agent 状态设计文档最前面:生命周期不同,存储位置就不该一样。

Tracker 解决的三个生产问题

第一个:上下文丢失

用户说完订单号后,Agent 要知道这个数字属于刚才的"查订单任务"。

这靠的不是模型玄学,而是 Tracker 记录:

text 复制代码
active_flow = query_order
order_id = 123456

第二个:任务无法恢复

用户退款到一半,页面关了。

下次回来,系统要知道:

text 复制代码
退款流程已经走到确认金额
订单号已经收集
身份已经验证

如果 Tracker 能序列化,就可以保存到 Redis 或数据库里,后面再恢复。

sequenceDiagram participant Agent as Agent participant Tracker as Tracker participant Storage as 状态存储 Agent->>Tracker: 更新退款流程状态 Tracker->>Storage: 保存状态快照 Note over Agent: 服务重启 / 用户离开 Agent->>Storage: 读取状态快照 Storage-->>Tracker: 恢复 Tracker Agent-->>Agent: 从上次步骤继续

第三个:多模块状态不一致

没有统一 Tracker 时,很容易出现:

text 复制代码
LLM 以为在退款
Action 以为在查订单
前端显示人工接管
数据库里还是旧状态

这就是状态中心的价值。

不是为了"架构好看",而是为了避免业务系统各说各话。

一个系统越像"能办事的人",越要有清楚的状态中心。

这次对我最大的提醒是:看 Agent 架构时,不要只问"模型能不能理解",还要问"系统有没有地方保存当前任务状态"。

如果这个问题没想清楚,后面接多少 Memory、RAG、Tool,都会越做越乱。

相关推荐
禅思院2 小时前
AI对话前端从入门到崩溃:一个长对话引发的五层优化战争【四】
前端·架构·前端框架
2601_959982212 小时前
从单体架构到微服务,再到云原生:现代软件架构的发展趋势
微服务·云原生·架构
AI-好学者2 小时前
Redis高可用与分布式架构
redis·分布式·缓存·架构
alxraves12 小时前
医用超声远程会诊系统:会诊平台的核心架构与功能解析
java·人工智能·架构
幻风_huanfeng14 小时前
软考:高级软件架构师学习笔记----软件架构设计
架构·系统架构·软考·高级系统架构师
OCR_1337162127515 小时前
技术拆解:国产GPU两大核心路线GPGPU与NPU的架构差异与落地现状
架构
跨境数据猎手16 小时前
反向海淘实战|独立站搭建+国内电商API对接
开发语言·爬虫·架构
xfhuangfu16 小时前
19c CDB架构下的数据库启动和停止
数据库·架构
爱折腾的小黑牛17 小时前
小程序云开发数据模型设计:礼账系统的三表结构
数据库·架构