ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

agno 工具调用轨迹数据生成实战:从真实工具 Schema 到多轮轨迹的 SFT 数据流水线

agno 工具调用轨迹数据生成实战:从真实工具 Schema 到多轮轨迹的 SFT 数据流水线 agno 工具调用轨迹数据生成实战从真实工具 Schema 到多轮轨迹的 SFT 数据流水线【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno本文围绕 agno 仓库中cookbook/data_labeling/_25_tool_call_trajectories目录展开讲解如何让框架自己生成函数调用function-calling的 SFT 训练数据先用真实的 agno 工具 JSON Schema 生成并纯代码校验单轮(query, tool call)对再通过模拟用户与真实执行工具的助手对话产出多轮轨迹最后由 temperature0 的评判模型把关只保留验证成功的轨迹。读完本文你将掌握一条完整、可复现、无需外部标注的「自产自销」式工具调用数据流水线并了解其与拒绝采样、数据集精炼等章节的衔接关系。目录概览三个脚本组成的一条流水线cookbook/data_labeling/_25_tool_call_trajectories目录包含三个 Python 脚本与配套文档分别对应数据生产的三个阶段basic.py从 agno 真实工具CalculatorTools、DuckDuckGoTools提取 JSON Schema让生成器 Agent 写出 8 个候选(query, tool call)对再用纯代码逐条对照真实 Schema 校验只保留通过的行multi_turn_simulation.py两个「人设」用户模拟 Agentdinner_host与math_student各自在最多 3 轮对话中分步完成一个多步计算目标与一个真实执行CalculatorTools调用的助手对话每条对话产出一行轨迹judge_filter.py从multi_turn_simulation.py导入PERSONAS、render_transcript、run_conversation重新跑一遍模拟再用 temperature0 的评判 Agent 依据TrajectoryVerdict结构校验每条轨迹是否达成目标只把验证通过的 rollouts 写入结果文件。该目录对应的 README.md 明确了设计动机框架生成自己的训练数据——单轮对按 Agent 运行时真正使用的 JSON Schema 做纯代码验证多轮轨迹来自模拟用户与真实执行工具调用的助手之间的对话执行过的调用名称、参数、结果从RunOutput提取并由评判模型决定哪些 rollout 值得保留。流水线第一段basic.py生成 Schema 验证的单轮工具调用对单轮对是训练模型「对固定 Schema 发出格式正确调用」的基础素材。basic.py的实现分为三个环节提取真实 Schema → 生成候选对 → 纯代码校验。从 agno 工具包提取真实 JSON Schema关键函数toolkit_schemas()遍历工具包的functions字典对每个函数调用fn.process_entrypoint()后取出description与parametersdef toolkit_schemas(toolkit: Any, source: str) - Dict[str, dict]: schemas {} for name, fn in toolkit.functions.items(): fn.process_entrypoint() # populates fn.parameters from the signature and docstring schemas[name] { name: name, description: fn.description, parameters: fn.parameters, source: source, } return schemas这里的process_entrypoint()是 agno 工具函数核心实现 中用于「处理入口函数并使其可供 Agent 使用」的方法它会从函数签名与 docstring 推导出参数 JSON Schema含properties、required等字段并缓存推导结果。也就是说脚本拿到的 Schema 与 Agent 运行时真正发给模型的工具定义是同一份保证了「校验用的 Schema」与「推理用的 Schema」严格一致。脚本构建的SCHEMAS字典合并了两个工具包CalculatorTools()来自 agno 内置计算器工具包共 8 个函数add、subtract、multiply、divide、exponentiate、factorial、is_prime、square_root统一以 JSON 字符串返回{operation: ..., result: ...}或错误对象DuckDuckGoTools()仅用于提供 Schema脚本中永远不会真正调用它下文会说明这样设计的用意。合计 10 个函数的 Schema 被打包进提示词交给生成器 Agent。生成器 Agent 与候选对结构生成器是一个配置了output_schemaToolCallPairs的 agno Agent使用google:gemini-3.5-flash模型。指令要求它产出「恰好一次调用即可回答」的自然用户查询与对应的调用且参数必须严格满足 Schema必需参数齐全、无多余参数、原始类型正确、查询中要放具体数值。输出由两个 Pydantic 模型约束class ToolCallPair(BaseModel): query: str # 一次调用即可回答的真实用户请求 tool_name: str # 与 Schema 列表中完全同名的工具 arguments_json: str # JSON 对象字符串如 {a: 2, b: 3} class ToolCallPairs(BaseModel): pairs: list[ToolCallPair]build_prompt()将 10 个 Schema名称、描述、参数序列化成 JSON 附加到指令中并要求「覆盖至少 5 个不同工具」。运行后从run.content.pairs中截取前N_PAIRS 8个候选进入校验阶段。纯代码校验器只留 Schema 严格匹配的行与「让模型自评」不同basic.py的校验完全用标准库实现保证可复现、无额外 API 开销。核心逻辑在json_type_matches()与validate_pair()见 basic.py工具已知tool_name必须存在于SCHEMAS否则判为unknown tool参数可解析arguments_json必须能被json.loads解析且顶层为 JSON 对象必需参数齐全Schema 中required列表里的每个参数都必须出现在参数中无未知参数参数中的每个键都必须存在于 Schema 的properties原始类型匹配json_type_matches()严格区分string/integer且排除布尔值避免 Python 中bool是int子类的坑/numberint或float且非布尔/boolean/array/object。validate_pair()返回(arguments, reason)校验失败时返回None与原因并打印dropped (reason)通过的行写入data/generated/tool_call_sft.jsonl同时带上schema_source溯源字段值为agno.tools.calculator或agno.tools.duckduckgo。测试日志TEST_LOG.md记录的真实运行结果摘要行输出wrote 8 rows ... kept 8, dropped 08 个候选全部通过校验——模型在简单 Schema 上能稳定产出 Schema 精确的参数数字以 JSON number 输出、factorial/is_prime用整数、仅当查询要求时才带可选的max_results。日志同时提醒校验器并非每次都触发kept/dropped 会随运行波动这正是校验器存在的意义。流水线第二段multi_turn_simulation.py多轮轨迹模拟多轮轨迹用于训练「多步工具使用 真实执行结果进入上下文」的能力。脚本用两个「人设」用户模拟 Agent 各跑一段对话与一个真实执行工具调用的助手交互。人设与模拟规则PERSONAS定义了两种典型多步计算目标见 multi_turn_simulation.pydinner_host组织朋友聚餐分三步——① 4 个披萨每个 18.50 的总价② 加上 12.75 配送费③ 5 人平分math_student检查作业分两步——① 判断 97 是否为质数② 计算 12! / 10!。SIM_RULES约束用户模拟 Agent一次只问一步、绝不自算数学、用一两句话自然回应、所有步骤完成后以单词DONE结尾。两个用户模拟 Agent 与带tools[CalculatorTools()]的助手均为google:gemini-3.5-flash助手被指令要求「每个算术步骤都用工具而非心算回复一两句短句并给出数值结果」。模拟循环与执行轨迹提取run_conversation()multi_turn_simulation.py是核心循环用户模拟 Agent 根据「对话历史 写你的下一条用户消息」生成下一条用户消息若消息以DONE结尾剥离该标记后再追加进messages因此导出的 JSONL 中看不到DONE目标完成状态对外不可观测助手 Agent 基于完整对话历史运行assistant.run()返回的RunOutput中assistant_run.tools保存了真实执行过的工具调用列表遍历该列表把每条调用转成{tool_name, arguments, result}三元组追加进tool_callsturns计数收到DONE或达到MAX_TURNS 3硬性轮数上限即结束。RunOutput.tools的底层类型是ToolExecution见 agno 运行输出定义 与 ToolExecution 数据结构其中tool_name、tool_args、result正是脚本提取的字段——也就是说轨迹里的「执行结果」是CalculatorTools真正运算后返回的 JSON 字符串而不是模型声称的结果。每人设产出一行JSONL 到data/generated/multi_turn_trajectories.jsonl字段为persona、messages、tool_calls、turns。测试日志记录的真实运行摘要行wrote 2 rows ... total 6 turns, 8 executed tool callsdinner_host 3 轮 / 3 次调用math_student 3 轮 / 5 次调用。dinner_host 依次执行了multiply(4, 18.5) - 74.0、add(74, 12.75) - 86.75、divide(86.75, 5) - 17.35全部正确math_student 执行了is_prime(97)、factorial(12)、factorial(10)、除法得 132.0外加一次验证性的multiply(12, 11)。日志还记录了运行间波动早前一次运行总调用数为 7助手有时用更少的调用完成 12!/10!。受 3 轮硬上限约束dinner_host 的轨迹在「最后一个问题仍在作答」时结束——这正是多步目标在硬轮数上限下的预期形态。流水线第三段judge_filter.py用评判模型把关轨迹质量轨迹本身「执行了」不等于「达成了目标」。judge_filter.py引入第三个 Agenttemperature0 的评判器Gemini(idgemini-3.5-flash, temperature0)用结构化输出约束其裁决。TrajectoryVerdict 结构化裁决评判器的输出由 TrajectoryVerdict 约束success为布尔值仅当用户目标的每一步都借助已执行工具调用正确回答时才为 Truereason为一两句引用具体调用/回答的判据说明。评判指令强调数字错误、跳过步骤、最终答案没有已执行调用支撑一律视为失败。评判输入与 keep/drop 决策build_judge_prompt()把三部分拼进提示词见 judge_filter.py人设对应的用户目标从PERSONAS取回、完整对话记录、以及tool_calls的 JSON 序列化。评判器据此判断目标是否达成。successTrue的行在provenance字段写入{judge: gemini-3.5-flash, reason: ...}后进入data/generated/verified_trajectories.jsonl失败的行打印dropped persona: reason。由于脚本从multi_turn_simulation.py导入并重跑模拟它不依赖任何预先存在的 JSONL可独立执行。测试日志记录的真实运行摘要行wrote 2 rows ... kept 2, dropped 0两条轨迹均通过。日志还记录了值得注意的现象该次运行中助手把 12!/10! 简化成单次multiply(12, 11)math_student 仅 2 次已执行调用而非早前运行的 4~5 次评判器正确接受了这种简化理由是「12! / 10! 简化为 12 × 11 …… 得到正确结果 132」——说明评判器校验的是最终结果正确性而非固定调用序列。由于当日未出现失败案例drop 分支仅通过代码审查验证在上下文算术正确的前提下助手很少在这些小目标上失败。输出数据格式与运行方式JSONL 行示例来自真实运行摘自 README单轮对basic.py{query: Calculate the sum of 124.5 and 89.2, tool_name: add, arguments: {a: 124.5, b: 89.2}, schema_source: agno.tools.calculator}多轮轨迹multi_turn_simulation.py / judge_filter.py节选{persona: dinner_host, messages: [{role: user, content: Hey! Im planning a dinner with some friends ...}, ...], tool_calls: [{tool_name: multiply, arguments: {b: 18.5, a: 4}, result: {\operation\: \multiplication\, \result\: 74.0}}, ...], turns: 3} {persona: math_student, messages: [...], tool_calls: [...], turns: 3, provenance: {judge: gemini-3.5-flash, reason: The assistant correctly checked if 97 is prime using the is_prime tool and computed 12 factorial divided by 10 factorial ... obtaining the correct result of 132.}}注意result字段是真实执行后返回的 JSON 字符串provenance记录了数据来源schema_source或judge保证训练数据的可审计性。运行命令与依赖三个脚本按顺序独立执行每个脚本各自负责自己的输出文件python cookbook/data_labeling/_25_tool_call_trajectories/basic.py python cookbook/data_labeling/_25_tool_call_trajectories/multi_turn_simulation.py python cookbook/data_labeling/_25_tool_call_trajectories/judge_filter.py前提条件需要GOOGLE_API_KEY三个脚本的生成器/助手/评判器均使用gemini-3.5-flashjudge_filter.py通过Gemini(id..., temperature0)显式设置零温度输出写入各脚本同级data/generated/目录已被 gitignore需运行脚本重新生成除模型 API 外不需要网络演示刻意把执行限制在离线的CalculatorTools工具包内DuckDuckGoTools在basic.py中仅以 Schema 形式出现而从不调用因此工具侧行为确定。测试日志标注的验证环境为gemini-3.5-flash模型、agno 2.7.4 版本测试日期 2026-07-18。何时使用这套方案README 明确给出了适用场景判断单轮对需要教模型针对固定 Schema 发出格式良好的调用时多轮轨迹需要教模型「多步工具使用 真实执行结果进入上下文」时评判过滤只有验证成功的 rollout 才能进入训练集时。这套「只保留通过项」的形状与 cookbook/data_labeling/_21_rejection_sampling 一脉相承——区别在于这里的「样本」是整条轨迹而非单条回复需要在大规模上对保留行做去重、过滤与混合时可进一步衔接 cookbook/data_labeling/_22_dataset_curation。设计要点与限制小结Schema 一致性通过Function.process_entrypoint()直接复用运行时工具定义保证「校验 Schema 推理 Schema」且校验完全基于标准库无模型自评偏差执行真实性多轮轨迹中的tool_calls来自RunOutput.toolsToolExecution的tool_name/tool_args/result记录的是真实计算结果而非模型声称的结果可复现性与隔离性工具执行限定在离线计算器内运行只依赖模型 APIDONE标记在导出前剥离因此 JSONL 中观察不到目标完成信号多步目标在硬轮数上限下的截断形态属于预期行为运行间波动kept/dropped 数量与工具调用次数会随模型输出波动日志记录到 7~8 次调用的差异评判器对「等价但不同的调用路径」保持容忍这是设计使然而非缺陷失败路径覆盖有限在上下文算术正确的前提下助手很少失败drop 分支的实战覆盖主要依赖代码审查生产使用时可人为注入错误场景以强化负样本。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表