一句话总结:LedgerAgent 的洞察很简单——把 Agent 需要遵守的约束从「放在 Prompt 里希望它记住」变成「存在外部结构里每次调用前强制检查」。这个改变小,但对策略遵从问题效果显著。
论文背景
论文标题:LedgerAgent: Structured State for Policy-Adherent Tool-Calling Agents
作者:Md Nayem Uddin, Amir Saeidi, Eduardo Blanco, Chitta Baral(Arizona State University / University of Arizona)
发表日期:2026-06-19(arXiv cs.CL / cs.AI)
评测基准:τ²-bench(tau2-bench)和 τ-Trait(tau-Trait)
客服 AI 是工具调用 Agent 最典型的应用场景之一:用户发起对话,Agent 通过调用工具(查询订单、修改数据库、触发退款流程)来完成请求,同时需要遵守一系列业务规则(退款仅限 30 天内、VIP 用户可享受豁免、库存不足时不能承诺发货等)。
这个场景乍看简单,但对 Agent 能力的要求实际上很高:它需要在跨越多轮对话的过程中,同时追踪用户目标、当前数据库状态、已执行的操作以及适用的策略约束——任何一个遗漏都可能导致错误的决策。
现有方法的根本缺陷
在标准工具调用 Agent 中(无论是 ReAct 还是 Function Calling),状态管理依赖 LLM 的上下文窗口。这带来了几个结构性问题:
策略约束的「稀释」:随着对话轮次增加,早期对话中建立的约束信息被后续内容稀释。LLM 更倾向于关注最近的上下文,可能在第 10 轮对话中「忘记」第 2 轮确认的限制条件。
工具调用结果的积累混乱:多次工具调用的结果以对话消息形式堆积在上下文中,模型需要在这些非结构化记录中提取当前系统状态,这既费上下文,也容易出错。
策略与任务的混淆:Policy 文档(规定了什么可以做、什么不能做)和任务状态(用户想做什么、当前进展如何)被混在一起,模型在推理时需要同时处理两个维度,认知负担高。
LedgerAgent 的核心假设是:状态管理是一个确定性问题,不应该依赖概率性的 LLM 上下文记忆。
Ledger:显式结构化状态
Ledger 是 LedgerAgent 的核心数据结构,是独立于 LLM 上下文的持久化对象。
Ledger 的结构
# 简化的 Ledger 结构
@dataclass
class Ledger:
# 观察到的事实(通过工具调用获取)
facts: dict[str, Any]
# e.g., {"user_id": "U123", "order_status": "delivered",
# "order_date": "2026-05-20", "user_tier": "standard"}
# 从策略文档提取的约束条件
constraints: list[Constraint]
# e.g., [Constraint("return_within_30_days",
# condition="order_date within 30 days of today")]
# 条件满足状态(已验证/未验证/不满足)
condition_status: dict[str, ConditionStatus]
# e.g., {"return_within_30_days": SATISFIED,
# "product_unopened": UNVERIFIED}
# 本次会话的操作日志
action_log: list[ToolCall]
Ledger 的生命周期
初始化:会话开始时,Ledger 从两个来源初始化:
- 业务策略文档(Policy):结构化提取适用于当前会话的约束条件
- 用户请求:提取用户的核心目标
更新:每次工具调用执行后,工具返回的结果直接写入 facts 字典,相关的 condition_status 同步更新。这是确定性操作,不经过 LLM。
决策检查:每次 LLM 提议执行一个工具调用前,系统检查 Ledger:
- 该操作是否与任何
VIOLATED约束冲突? - 是否还有
UNVERIFIED的必要条件未验证?
如果存在冲突或未验证条件,系统会拦截 LLM 的提议,强制要求先解决问题。
策略提取:从文档到结构
把非结构化策略文档转化为 Ledger 约束是系统的关键步骤。论文使用一次性的 LLM 提取(在会话开始时,不在每轮调用时),把策略文档解析为结构化约束:
输入: "退款政策:用户须在收到商品后 30 天内提出申请。商品须未开封。VIP 用户退款期延长至 60 天。"
输出: [
Constraint(name="return_period",
standard="order_date + 30 days >= today",
vip_override="order_date + 60 days >= today"),
Constraint(name="product_condition",
requirement="product_status == 'unopened'")
]
这个提取步骤只在策略文档变更时重新执行,不是每次会话的额外开销。
推理流程:Ledger-Guided Tool Selection
LedgerAgent 的推理循环与标准 ReAct 有一个关键差异:
标准 ReAct:
LLM → 推理 → 决定工具调用 → 执行 → 观察 → 循环
LedgerAgent:
LLM → 推理 → 提议工具调用 → Ledger 检查 →
[通过] → 执行 → 更新 Ledger → 循环
[拦截] → 将冲突信息加入上下文 → LLM 重新推理
Ledger 检查是确定性的(查表,不调用 LLM),因此不增加延迟。拦截时注入的冲突信息帮助 LLM 理解为什么当前提议不可行,而不是简单地报错。
实验设置与结果
评测基准
tau2-bench:由 AI 研究者构建的客服 Agent 基准,包含航空、电商、保险等多个领域的任务,每个任务包含用户目标、初始数据库状态、业务策略和工具集。评测指标:任务完成率(Task Success Rate)和策略遵从率(Policy Adherence Rate)。
tau-Trait:更细粒度地评测 Agent 在各类策略约束下的行为,包含约束感知(是否知道约束存在)、约束遵从(是否按约束行动)和约束解释(能否向用户解释约束原因)三个维度。
主要结果
| 方法 | 任务完成率 | 策略遵从率 |
|---|---|---|
| 基于提示的工具调用 baseline | 62.3% | 71.5% |
| ReAct + 策略摘要 | 65.1% | 74.8% |
| LedgerAgent | 74.8% | 89.3% |
策略遵从率的提升(+17.8 个百分点)比任务完成率的提升(+12.5 个百分点)更显著,符合 Ledger 的设计目标——主要提升策略遵从,顺带改善任务完成。
分析:提升在策略复杂度高(多条件、有例外情况)的任务上最显著。在策略简单(单一条件)的任务上,LedgerAgent 与 baseline 差距较小——这验证了 Ledger 的价值主要在处理复杂约束交互时。
工程层面的实现考虑
将 LedgerAgent 的思路应用到实际系统需要解决几个工程问题:
策略提取的鲁棒性:真实业务的策略文档往往更复杂、更模糊,LLM 的一次性提取可能有遗漏或误读。建议在首次提取后加入人工验证环节,把提取结果当成配置来管理(版本控制、变更审计)。
Ledger 的序列化与持久化:在生产级多轮对话服务中,Ledger 需要在请求之间持久化(Redis、数据库),确保会话中断后可以恢复。
与现有工具调用框架集成:LedgerAgent 可以在现有 Function Calling 框架(如 LangChain、LlamaIndex)的基础上加入 Ledger 作为一个中间件层,不需要重写整个 Agent 架构。
适用场景的延伸
论文聚焦于客服 AI,但 Ledger 的思路可以推广到更广泛的场景:
医疗 Agent:追踪患者过敏史、药物禁忌、诊断标准等约束,确保 AI 辅助问诊不违反医疗规范。
金融合规 Agent:实时追踪合规规则(KYC 状态、交易限额、风险评级),在 Agent 建议操作前确保合规检查通过。
代码 Agent 的架构约束:类似 LedgerAgent 对策略约束的显式追踪,代码 Agent 可以用 Ledger 追踪代码库的架构规范(如「服务间通信必须通过 API Gateway」、「数据库访问仅限 Repository 层」),在生成代码前做确定性检查。
局限
策略提取质量:Ledger 的质量取决于初始策略提取的质量。如果提取漏掉了某个约束,Ledger 无法检测到违反该约束的工具调用——这是「垃圾进,垃圾出」问题。
动态策略:当前实现假设策略在会话中是静态的。实际业务中,策略可能在会话中间变更(如在线促销突然结束),需要额外的机制处理策略的动态更新。
增加的系统复杂度:引入 Ledger 意味着增加一个额外的持久化组件和策略提取步骤,对于策略简单的应用场景,这个复杂度不一定值得。
结语
LedgerAgent 的贡献不在于提出了复杂的新架构,而在于识别了一个具体的、被常规方法忽视的问题:在多轮工具调用 Agent 中,策略约束不应该依赖 LLM 的上下文记忆。
把状态管理从概率性的 LLM 记忆转移到确定性的结构化存储,是一个符合软件工程直觉的设计决策——我们不会把数据库的事务状态放在自然语言文本里靠 AI 记忆,那为什么要把 Agent 的约束状态放在 Prompt 里靠 LLM 记忆?
对于正在构建需要策略遵从能力的 Agent 系统的工程团队,这篇论文提供了一个清晰、可实现的架构参考。