博主头像
Kurfuerst

ワクワク

Routine

总览

让 agent 在企业多工具、多步骤、强流程约束的环境里,执行得更稳定、更少出错。

通用模型在企业环境中常常缺少领域流程知识,会出现计划混乱、漏工具、工具选错、参数传递不稳等问题;而 Routine 的目标就是把原本模糊的“自然语言计划”变成一种更结构化、可执行、易于跟随的流程表示,提高流程稳定性。

主要分成四个部分:Planning、Execution、Tools、Memory。

Planning 模块输出结构化的 Routine;Execution 模块只负责严格按 Routine 一步一步调用工具;Tools 模块通过 MCP server 提供标准化工具接口;Memory 模块则用 Procedure Memory 和 Variable Memory 控制流程检索与参数传递。

主要解决以下问题:

  1. 面对很多工具时,能不能选对工具
  2. 多步任务里,能不能保持正确顺序,保证结构正确
  3. 遇到分支条件时,能不能走对流程
  4. 在长上下文下,能不能不幻觉、不漏步骤

传统 agent 往往把这些任务都给一个模型在线完成:既要理解用户任务,又要规划步骤,又要选工具,又要填参数,还要记住上下文。这对单个模型来说过于困难,所以需要先让规划模块把任务转写为一个结构化的 Routine,再让执行模块去执行。


Routine 是什么

Routine 是一个结构化 planning script,一个在规划模块和执行模块之间的中间表示。增强执行模型的 instruction-following 能力。

Routine 的组成元素可以包括:

  • Step Number:步骤编号
  • Step Name:步骤名称
  • Step Description:步骤描述,包含执行条件和目标
  • Input Description:输入参数说明,可选
  • Output Description:输出参数说明,可选
  • Step Tool:本步要调用的工具,可选但非常关键,而且每步只允许一个工具

Routine 为什么有效

Routine 的有效性来自于它对执行自由度的压缩。

不需要规划模块传递中间结果,不需要执行模块选择工具


Routine 的结构细节

线性步骤

最基础的 Routine 是线性的,类似:

  • Step 1:做 A,用 tool_X
  • Step 2:做 B,用 tool_Y
  • Step 3:做 C,用 tool_Z,并结束

这种结构已经能大幅降低模型在多工具、多步骤链路中的搜索空间。因为模型不需要自己决定完整路径,只需要执行给定路径。

分支步骤

Routine 支持 branch。其形式大致是:

  • Step X:进行分支判断
  • Branch X-1 Step 1:如果条件 1,做……
  • Branch X-1 Step 2:继续……
  • Branch X-2 Step 1:如果条件 2,做……
  • Step Y:后续统一流程
  • Step Z:结束流程

这里的编号方式也很重要。作者使用诸如 "Branch X-n Step i" 这样的标记,表示某个主步骤下第 n 个分支中的第 i 个步骤。这样执行模型能从编号里知道自己处在整个工作流的哪一个分支和哪一个位置。

结束条件

需要在 Routine 中显式写出 terminate the workflow,也就是某一步是否终止流程。很多 agent 的错误来自:

  • 不知道什么时候该停止
  • 继续多调用一步工具,导致结果出现偏差

Routine 通过把终止条件写入流程,减少了这类不必要的额外动作。


显式工具绑定

论文的消融实验表明,Routine 中显式写出 tool name 是最核心的机制之一。作者发现,一旦把工具名从 Routine 中拿掉,让模型仅根据 step description 自己推断工具,除了 GPT-4o 以外,大多数模型准确率都会显著下降,通常下降 5% 到 15%。

不确定是否会对最新的模型造成影响。


Routine 的实现

框架

Planning Module

输入用户任务或专家草稿,输出结构化 Routine。其核心职责不是执行,而是把一个任务转成可跟随的流程脚本。

Execution Module

接收 Routine,按步骤输出工具调用指令。不需要很强的推理能力,核心能力是 multi-step tool calling + instruction following,因此可以由较小的模型承担,从而节省成本。并且执行模型不直接生成最终自然语言答复,最终答复由最后一步的 summarization tool 来完成,避免 summarization prompt 与 tool-calling prompt 相互干扰。

与btm_agent现有流程相符。

Tools Module

论文中使用 MCP server 作为 Tool Module。执行模块只需要决定“调用哪个工具”和“传什么参数”,而不必管理工具实现细节。

langraph tool可能相近

将现有node封装为tool,由executor_node决定是否调用

Memory Module

包括:

  • Procedure Memory:存储 Routine 库,按查询与 Routine 描述的相似度检索出最相关的流程
  • Variable Memory:把过长的中间参数存成键值映射,让模型只传 key,不传长文本本身

Planning Module

草稿 + AI 优化

流程是:

  1. 领域专家先给一个简要流程草稿
  2. 再用一个带专门 prompt template 的模型,对草稿进行:
  3. 分解成更细的子步骤
  4. 把子步骤映射到现有工具
  5. 输出结构化、完整、易于执行模块跟随的自然语言 Routine

可能可以定义一个结构化的数据结构,而不是用纯自然语言

Routine validation

校验步骤是否存在,tool是否存在

是否存在死循环

输入是否能从state中获取

是否有多个end或不可达步骤


Procedure Memory

企业场景里往往有很多流程,不可能把所有 Routine 全部塞进系统 prompt。

需要一个 Routine memory base:

  • 预部署阶段,把各类 Routine 写入 memory
  • 运行时,根据用户任务与 Routine 描述的相似度,检索出最相关的 Routine 给执行模型

这一步的意义在于:

  • 避免 prompt 太长
  • 减少无关流程干扰

Procedure Memory 的检索质量非常关键,因为一旦同时召回多个相似但不匹配的 Routine,会引入干扰。

class RoutineTemplate(BaseModel):
    routine_id: str
    name: str
    description: str
    scenario_tags: list[str]
    trigger_examples: list[str]
    plan_template: RoutinePlan

通过向量数据库存储description、scenario_tags,流程开始前召回


Variable Memory

多步 tool calling 时,中间结果经常很长,比如:

  • 某个文档全文
  • 查询结果列表
  • 长 JSON
  • 长自然语言参数

如果每一步都把这些长结果直接拼进上下文,会带来:

  • context window 压力变大
  • token 消耗上升
  • 小模型更容易在引号、括号、转义字符上犯错
  • 幻觉

解决办法是:

  1. 某工具返回特别长的参数值时,系统自动把它存到 variable memory
  2. 模型后续只需要在工具参数里填这个变量的 key
  3. 在真正调用工具前,Memory Module 再自动把 key 映射回真实值

这等价于给 agent 提供了一个非持久化局部变量表

类似langraph的state(?)


Execution Prompt

论文附录里给了执行模块 system prompt 模板,包括:

  • 角色定义
  • 任务和行为规则
  • system parameters
  • <routines> ... </routines>:当前要跟随的 Routine
  • <variables> ... </variables>:当前任务的variable memory
  • <tools> ... </tools>:可调用工具列表
  • 输出要求:每次只输出一个 <tool_call> JSON 对象 (防止跳步骤/并行调用导致输入输出接不上)

LangGraph 中只有一个 routine_executor_node

每次执行一个step

执行后更新 current_step_id

再走回自身,直到 end

可以先固定dag 外加 planner,只在某些步骤上执行


实验

场景

实验场景是一个大型企业中的 HR agent,企业规模超过 8000 人。这个场景共有 7 个子场景,对应 7 个人工标注的 Routine,每个 Routine 有 4–7 步 tool calls,每个工具需要 1–3 个输入参数,总共有 25 个不同功能工具,其中包括数据查询、权限验证、模型生成等。7 个 Routine 中有 3 个带分支逻辑;如果拆开分支,可看成 10 个非分支 Routine。


评测方法

作者采用 BFCL 的 Function Calling 模式和 AST 评估框架,把错误分成三类:

  • Structural Error:JSON 格式错,括号、标点等导致无法解析
  • Tool Selection Error:没用工具、工具数不对、用错工具、用了不存在的工具
  • Parameter Error:参数值不对、参数幻觉、缺关键参数

Overall Accuracy:结构、工具、参数全部正确才算对

同时他们对自由文本参数采用 approximate matching,而不是严格逐字匹配,理由是有些自然语言参数语义相同但表述略有差别,如果强行精确匹配会低估模型真实能力。

测试数据由 200 条多步 query 分解为 1148 个 step-level test samples。每个 sample 都保留其之前的执行历史以及当前步的 system prompt 状态,保证评测环境与真实连续执行一致。

作者还随机打乱工具列表顺序,避免模型利用位置偏差。


实验结果

Routine 本身的效果

No-Routine 条件下,所有 baseline 模型 overall accuracy 都低于 50%,说明即使是强模型,在复杂企业多步任务里完全依赖自主规划也很不稳定。作者指出,超过 85% 的错误来自 tool selection,说明最大难点不是格式,而是从 25 个工具里正确选出一条执行链。

引入 Routine 后,准确率大幅提升。例如:

  • GPT-4o:41.1% → 96.3%
  • Qwen3-14B:32.6% → 83.3%
  • GPT-4-Turbo:43.5% → 99.0%
  • Claude-3.7-Sonnet:43.9% → 99.3%

这说明 Routine 的主要价值,是通过步骤分解和显式工具提示,大幅提高了 tool selection accuracy,从而带动 overall accuracy 上升。结构错误和参数错误也减少了,但它们原本就不是最大瓶颈。


分支对性能的影响

同样给 Routine 时,无分支 的表现通常比 有分支 更高。对顶级模型,差距不大;对中等能力模型,分支会更明显地拉低准确率。作者据此认为:branching logic 只有在模型本身已有较强 tool calling 基础时,才不会带来明显性能损失。


Routine-following 训练的效果

使用 4209 条通用 Routine-following 数据微调后,模型在“有 Routine”的条件下表现进一步提升。例如:

  • Qwen3-14B:从 83.3% 提升到 88.2%(with branch)
  • 无分支时达到 92.7%

但论文也发现一个 trade-off:这种训练会让模型更像“执行者”,而不是“自主规划者”。因此在 No-Routine 条件下,这些模型反而可能比原始模型更差。


Routine 组件消融

加 I/O 描述

输入输出描述的效果总体是正向的,尤其帮助弱模型。例如:

  • GPT-3.5-Turbo:52.7 → 61.1
  • Qwen2.5-7B:49.7 → 60.6
  • Qwen2.5-14B:79.1 → 84.2

但是对于性能较好的模型可能有反向作用

去掉 tool name

几乎所有模型都会明显变差。例如:

  • Qwen2.5-14B:79.1 → 69.5
  • Qwen3-14B:83.3 → 71.9
  • GPT-3.5-Turbo:52.7 → 42.8

一个高质量 Routine 应该同时包含显式工具名和足够的说明信息,才能最大化稳定性。


AI 优化 Routine 的效果

作者比较了三种 Routine 生成方式:

  • User Draft:用户草稿
  • AI Optimization:GPT-4o 优化后的 Routine
  • Human Annotation:专家精标 Routine

结果:

  • 低质量草稿就已经比完全自主 tool calling 好
  • AI 优化能带来普遍而显著的提升
  • 对高性能模型,人工标注仍是最优
  • 但对一些模型,AI 优化版甚至比人工版更容易理解

例如:

  • GPT-4o:71.2 → 90.9 → 96.3
  • Qwen2.5-14B:61.7 → 82.3 → 79.1
  • Qwen3-14B:70.9 → 76.7 → 83.3

可以ai优化后人工审核


局限性

系统高度依赖:

  • 领域专家先写 draft
  • 出现新工具和流程变化时可能需要重新适配
  • 新流程、新工具引入时泛化能力仍有限
  • Procedure Memory 的召回精度会直接影响整体稳定性
  • branch 场景对中等能力模型仍然偏难,对模型性能有一定要求
  • 本质还是固定流程 + 动态执行,还不是能自我学习的 agent

考虑结合 RL 和 multi-agent 框架来进一步提升规划与适应能力。

Routine
http://blog.kurfuerst.online/index.php/archives/46/
本文作者 Großer Kurfürst
发布时间 2026-03-17
许可协议 CC BY-NC-SA 4.0
发表新评论