Files
iAs/docs/TOOLKIT_WORKFLOW.md
T

12 KiB
Raw Blame History

TOOLKIT WORKFLOW — YAML 驱动的 HTTP 工具链引擎

概述

TOOLKIT WORKFLOW 让你通过编写 YAML 文件来定义 LLM 工具。一个 YAML 文件描述一个工具:它接受哪些参数、调用哪些 HTTP API、如何从响应中提取数据、以及最终返回什么给 LLM。

核心能力:

  • 一个 YAML 文件 = 一个完整的 LLM 工具,无需写代码
  • 支持多步 HTTP 请求链,步骤之间可以传递变量
  • 流程控制:next 跳转步骤、jump 降级到备源、abort 终止执行
  • 键级缓存:cache 缓存变量,同一调用中缺键自动重请求
  • 统一提取:extract 字段,语法自描述引擎(路径 / 正则)

YAML 顶层结构

一个工具 YAML 文件包含以下顶层字段:

字段 必填 类型 说明
name string 工具名,对应 LLM function.name
desc string 工具描述,对应 LLM function.description
params array LLM 可见的参数定义,映射为 function.parameters JSON Schema
env array[string] 该工具依赖的环境变量名列表,仅作文档和校验
steps array 请求步骤链,按顺序执行

params — 参数定义

定义 LLM 可以传入的参数,映射为 function calling 的 parameters schema。

字段 必填 类型 说明
name string 参数名,在模板中通过 ${param:key} 引用
type string 取值:string / number / integer / boolean
required boolean 是否必填
description string 参数说明,LLM 据此理解参数含义
default any 默认值,LLM 未传时自动使用

steps — 请求步骤

每个步骤定义一个 HTTP 请求及其后续处理。

步骤字段

字段 必填 类型 默认值 说明
url string 请求 URL,支持模板语法
method string GET HTTP 方法:GET / POST / PUT / DELETE / PATCH
headers map 请求头键值对,值支持模板语法
query array URL 查询参数,格式为 [{key, value}] 元组列表,值支持模板语法
body string 请求体,支持模板语法
timeout integer 30 超时时间(秒)
cache boolean false 是否对该步骤启用键级缓存
next integer 步骤成功后跳转到第几个步骤(0-based),不设则顺序执行下一步
var array 变量提取列表
result string 最终返回模板,有此字段则该步为终步

步骤示例

steps:
  - url: ${env:BASE_URL}/auth/token
    method: POST
    headers:
      Content-Type: application/json
    body: |
      {"client_id": "${env:CLIENT_ID}", "client_secret": "${env:CLIENT_SECRET}"}
    timeout: 15
    cache: true
    var:
      - name: token
        extract: access_token
        abort: true
    next: 1

  - url: ${env:BASE_URL}/orders/${param:order_id}
    method: GET
    headers:
      Authorization: Bearer ${step0:token}
    var:
      - name: status
        extract: data.status
      - name: amount
        extract: data.amount
    result: |
      订单号: ${param:order_id}
      状态: ${step1:status}
      金额: ${step1:amount}

var — 变量提取

每个步骤执行完 HTTP 请求后,按顺序处理 var 列表中的条目,从响应中提取命名变量。提取的变量通过 ${stepN:var_name} 在后续步骤中引用。

extract — 提取表达式

一个字段覆盖所有提取场景。值的语法决定使用的引擎:

语法 引擎 说明
不以 / 开头 路径引擎 对 JSON/YAML 响应执行结构化路径导航
/ 开头且以 / 结尾 正则引擎 对原始响应文本执行正则匹配,取捕获组 1

路径引擎:自动检测响应格式(先 JSON,失败则 YAML),然后按路径导航取值。

语法 含义 示例
key 访问对象字段 data.status
key[N] 访问数组第 N 个元素 items[0].name
key[] 遍历数组所有元素 books[]
key[].field 遍历数组,对每个元素取字段 books[].title

键名建议仅使用 [a-zA-Z0-9_],避免含 . [ ] 的特殊键名。

正则引擎/pattern/ 形式,对原始响应文本执行正则匹配,取第一个捕获组。

# 路径:从 JSON 响应中提取
var:
  - name: token
    extract: auth.access_token

# 正则:从任意文本中提取
var:
  - name: session
    extract: /session[= ]([a-f0-9]+)/

提取失败处理(每个条目最多选一种)

配置 提取成功 提取失败
不设任何失败处理 存入变量 存入空字符串 "",继续执行
default: "值" 存入变量 存入默认值,继续执行
abort: true 存入变量 终止整个工具,返回错误给 LLM
jump: N 存入变量 跳转到第 N 个步骤执行,N 从 0 开始

var 条目完整字段

字段 必填 类型 默认值 说明
name string 变量名,通过 ${stepN:name} 引用
extract string 提取表达式,语法自描述引擎(路径 / 正则)
default string 提取失败时的默认值
abort boolean false 提取失败时是否终止工具
jump integer 提取失败时跳转到第几个步骤(0-based)

流程控制

三种流程控制机制,覆盖顺序执行、条件跳转和异常终止。

next — 成功后跳转

  • 位置:步骤级别
  • 触发条件:步骤所有 var 都没有因 abort/jump 而失败
  • 效果:跳转到指定步骤号(0-based),不设则顺序执行下一步
  • 用途:跳过某些步骤、实现条件分支

jump — 提取失败时降级

  • 位置:var 条目级别
  • 触发条件:该条目的提取失败且未设置 default
  • 效果:跳转到指定步骤号(0-based),当前步骤剩余 var 不再执行
  • 用途:主数据源失败时自动切换到备数据源

abort — 提取失败时终止

  • 位置:var 条目级别
  • 触发条件:该条目的提取失败
  • 效果:终止整个工具执行,返回错误信息给 LLM
  • 用途:关键变量(如认证 token)获取失败时立即报错

cache — 键级缓存

当步骤设置 cache: true 时,该步骤提取的所有变量会被缓存。

缓存行为:

  • 命中:缓存中存在该步骤所有 var.name → 跳过 HTTP 请求,直接返回缓存值
  • 未命中:任意一个 var.name 缺失 → 发起 HTTP 请求,提取所有变量,全部存入缓存
  • 生命周期:单次工具调用期间(内存级),工具返回后释放
  • 缓存键:由步骤的 url + method + headers + body 模板展开后的哈希确定

典型用法:第一步获取认证 token 并缓存,后续多步复用 token 时不会重复请求认证接口。


模板语法

以下字段支持模板语法:urlheaders 的值、bodyresult

三种引用

语法 来源 示例
${param:key} LLM 传入的工具参数 ${param:city}${param:order_id}
${env:VAR} 系统环境变量 ${env:API_KEY}${env:BASE_URL}
${stepN:var_name} 第 N 个步骤提取的变量,N 从 0 开始 ${step0:token}${step1:status}

约束

  1. 禁止嵌套引用:${step0:${env:KEY}} 不允许
  2. 禁止原始步骤引用:${step:0} 不允许,必须先通过 var 提取为命名变量

result — 最终返回

步骤的 result 字段定义该工具最终返回给 LLM 的内容。

  • 如果某步设置了 result,该步即为终步,执行后不再继续后续步骤
  • 如果所有步骤都未设置 result,默认返回最后一步的原始响应体
  • result 支持模板语法,可以拼接多个变量和文字
# 返回单个变量
result: ${step1:status}

# 多行模板拼接
result: |
  订单号: ${param:order_id}
  状态: ${step1:status}
  金额: ${step1:amount}

执行流程

1. 加载 YAML → 解析为 YamlToolDef
2. 解析 LLM 参数 → params HashMap
3. 加载 env 声明的环境变量 → env HashMap
4. 初始化 cache = {}

5. step_idx = 0
   while step_idx < steps.len():

   ┌─ 当前步骤执行 ──────────────────────────────┐
   │                                              │
   │  [cache: true?]                              │
   │    ├─ 缓存命中(所有 var 键都存在)→ 跳过HTTP  │
   │    └─ 缓存未命中 → 继续                       │
   │                                              │
   │  展开 url/headers/body 中的模板               │
   │    ${param:key} → params["key"]              │
   │    ${env:VAR}    → env["VAR"]                │
   │    ${stepN:var}  → ctx.vars[(N, var)]        │
   │                                              │
   │  HttpRequest 执行 → HttpResponse             │
   │    保存到 ctx.steps[step_num]                 │
   │                                              │
   │  for each var:                               │
   │    extract 语法分发:                          │
   │    ├─ /.../ → 正则引擎,取捕获组1             │
   │    └─ 其他  → 路径引擎(JSON→YAML 自动检测)  │
   │    ├─ 成功 → 存入 ctx.vars + step_vars       │
   │    └─ 失败 →                                  │
   │        ├─ abort:true  → 终止,返回错误        │
   │        ├─ default:x   → 使用默认值            │
   │        ├─ jump:N      → step_idx = N, break  │
   │        └─ (无)        → 空字符串              │
   │                                              │
   │  [cache: true?] → 将 step_vars 存入 cache     │
   │                                              │
   │  [result 存在?]                               │
   │    └─ 展开 result 模板 → 返回给 LLM → 结束    │
   │                                              │
   │  [next 存在?]                                 │
   │    ├─ next:N  → step_idx = N                 │
   │    └─ (无)    → step_idx += 1                │
   │                                              │
   └──────────────────────────────────────────────┘

6. 循环结束 → 返回最后一步原始响应体

错误处理

场景 处理方式
YAML 文件格式错误 启动时打印警告,跳过该文件
模板引用了未定义的参数 替换为空字符串,记录警告日志
环境变量未设置 替换为空字符串,记录警告日志
HTTP 请求失败(连接/超时) 返回错误详情给 LLM
var.abort: true 且提取失败 终止,返回 "变量 xxx 提取失败"
var.jump: N 且提取失败 跳转到第 N 个步骤,N 从 0 开始,不报错
var.default 且提取失败 使用默认值,不报错
路径语法错误(空段、非法索引) 返回错误给 LLM,附带路径表达式
路径键不存在 / 索引越界 提取失败,触发 default/abort/jump
正则语法错误 返回错误给 LLM,附带正则表达式
正则无匹配 提取失败,触发 default/abort/jump
响应体非 JSON 也非 YAML(路径引擎) 返回错误给 LLM
next / jump 目标步骤不存在 终止,返回配置错误

扩展预留

以下字段预留供后续版本实现:

字段 位置 用途
retry steps[] 失败重试次数与退避策略
cache.ttl steps[] 缓存有效期(秒)
validate params[] 参数级正则校验
sensitive env[] 标记敏感环境变量,日志脱敏
loop steps[] 条件循环(分页自动翻页)
export steps[] 将变量导出为环境变量供子进程使用
pre_request 顶层 工具级别的前置请求(全局认证)