☰
AxonHub 多工具调用集成测试实践:基于 Anthropic Go SDK 的顺序、并行与强制工具选择
2026/10/13 9:29:16 网站建设 项目流程
  • AI 应用
  • API网关
  • LLM 网关
  • 后端
  • 前端

【免费下载链接】axonhub

⚡️ Open-source AI Gateway — Use any SDK to call 100+ LLMs. Built-in failover, load balancing, cost control & end-to-end tracing.

项目地址:https://gitcode.com/gh_mirrors/ax/axonhub
点击查看免费下载

本篇文章以 AxonHub 仓库中的 Anthropic 多工具集成测试 为脉络,完整讲解如何通过官方anthropic-sdk-go在一个请求中声明多个 function tool,并覆盖"顺序执行、并行执行、强制工具选择(tool choice)"三大经典场景。读完本文,你将掌握 Anthropic Messages API 多工具调用的完整请求-响应循环、工具结果回填的对话续写写法,以及如何在 AxonHub 网关上通过 集成测试 环境验证这套流程。

一、测试场景与定位

integration_test/anthropic/tool_multiple/目录专门用于验证"多个工具同时可用"时模型的行为,测试文件与说明文档如下:

  • README.md — 测试用例与工具定义说明;
  • tool_multiple_test.go — 全部测试的完整 Go 实现。

该目录是整个 Anthropic SDK 集成测试 体系的一部分,与 单工具测试(tool_single/)互补:单工具目录验证"一个工具"的基础调用闭环,本目录则聚焦"一次请求暴露多个工具"时模型的工具选择、多轮调用与结果合并。

测试的核心观察点是响应中的stop_reason是否为tool_use。当模型决定调用工具时,Anthropic 会在同一次响应中返回一个或多个tool_usecontent block;测试据此进入"解析工具参数 → 模拟执行 → 回填 tool_result → 追加对话"的循环。

二、测试环境准备

多工具测试依赖一套统一的测试基础设施,定义在 integration_test/anthropic/internal/testutil/ 中,其中 config.go 负责读取环境变量,helper.go 提供客户端与断言封装。

2.1 必需环境变量

测试启动时NewTestHelper会调用ValidateConfig,缺少 API Key 时直接t.Skipf跳过该用例。需要设置的关键变量如下:

环境变量作用默认值(以 config.go 为准)
TEST_AXONHUB_API_KEYAxonHub / Anthropic API 密钥,缺失则跳过测试无(必填)
TEST_ANTHROPIC_BASE_URL网关或上游地址http://localhost:8090/anthropic
TEST_MODEL测试所用模型deepseek-chat(注意:集成测试总览 文档中描述默认值为claude-3-5-sonnet-20241022,与源码默认值存在差异,实际行为以 config.go 源码为准)
TEST_TRACE_ID指定 trace ID未设置时自动生成trace-<random>
TEST_THREAD_ID指定 thread ID未设置时自动生成thread-<random>
TEST_DISABLE_TRACE置为true可关闭 trace 头false
TEST_DISABLE_THREAD置为true可关闭 thread 头false

一个典型的配置命令:

export TEST_AXONHUB_API_KEY="your-anthropic-api-key" export TEST_ANTHROPIC_BASE_URL="http://localhost:8090/anthropic" # 可选,默认即此值 export TEST_MODEL="claude-3-5-sonnet-20241022" # 可选 export TEST_TRACE_ID="test-trace-123" # 可选 export TEST_THREAD_ID="test-thread-456" # 可选

2.2 与 AxonHub 的链路对接

所有请求都会携带 AxonHub 规范的两个请求头(见 config.go):

  • AH-Trace-Id:请求追踪标识;
  • AH-Thread-Id:会话线程标识。

helper.CreateMessageWithHeaders(helper.go)通过option.WithHeader在调用点注入头部,从而让网关侧能够建立完整的请求追踪链路,这与 AxonHub 端到端追踪能力保持一致。

三、测试中的两个模拟工具

目录说明文档明确了两个被测试的工具(详见 README.md):

Weather Tool

  • 函数名:get_current_weather
  • 参数:location(string,必填)— 城市名
  • 模拟行为:按城市返回 mock 天气数据

Calculator Tool

  • 函数名:calculate
  • 参数:expression(string,必填)— 数学表达式
  • 模拟行为:对简单表达式求值

在 Go 代码中,二者通过anthropic.ToolParam声明为 JSON Schema 风格的定义,例如(节选自 tool_multiple_test.go):

weatherTool := anthropic.ToolParam{ Name: "get_current_weather", Description: anthropic.String("Get the current weather for a specified location"), InputSchema: anthropic.ToolInputSchemaParam{ Type: "object", Properties: map[string]interface{}{ "location": map[string]string{ "type": "string", }, }, Required: []string{"location"}, }, } calculatorTool := anthropic.ToolParam{ Name: "calculate", Description: anthropic.String("Perform mathematical calculations"), InputSchema: anthropic.ToolInputSchemaParam{ Type: "object", Properties: map[string]interface{}{ "expression": map[string]string{ "type": "string", }, }, Required: []string{"expression"}, }, } tools := []anthropic.ToolUnionParam{ {OfTool: &weatherTool}, {OfTool: &calculatorTool}, }

要点:ToolParam由Name、Description、InputSchema三部分组成;InputSchema遵循 JSON Schema 规范,Properties描述每个参数,Required声明必填参数。模型会依据 Description 判断何时使用该工具,因此描述写得越明确,工具路由越准确。若需补充参数描述,可在Properties的 value 中增加"description"字段(单工具测试 tool_single_test.go 展示了这一写法)。

四、测试用例详解

4.1 TestMultipleToolsSequential — 多工具顺序执行

该用例模拟"一次提问需要先后使用多个工具"的场景,提示词为:

Please use the available tools to: 1) Get the current weather in New York, and 2) Calculate 15 * 23. Provide both results.

请求构造(tool_multiple_test.go):

messages := []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(question)), } params := anthropic.MessageNewParams{ Model: helper.GetModel(), Messages: messages, Tools: tools, MaxTokens: 1024, }

执行流程:

  1. 发起首次请求:helper.CreateMessageWithHeaders(ctx, params)返回响应;
  2. 检测工具调用:判断response.StopReason == anthropic.StopReasonToolUse;
  3. 解析并模拟执行:遍历response.Content,用block.AsToolUse()取出tool_use块,json.Unmarshal解析Input中的参数,再按函数名分派到simulateWeatherFunction/simulateCalculatorFunction;
  4. 回填结果并续聊:将模型响应response.ToParam()追加进messages,然后为每个tool_use构造anthropic.NewToolResultBlock(toolUseBlock.ID, result, false),包装进anthropic.NewUserMessage后追加,最后用完整历史再次调用;
  5. 校验终答:验证 final response 非空,且内容综合了两个工具的信息。

这里的关键是tool_use 块必须按 ID 对应回填 tool_result,模型才能把结果关联到对应的调用。

4.2 TestMultipleToolsParallel — 并行工具执行

该用例一次请求同时需要多个独立信息,提示词为:

Please use the available tools to: 1) Get weather for New York, 2) Get weather for London, and 3) Calculate 100 / 4. I need all three results.

Anthropic Messages API 允许在单次响应中返回多个 tool_use 块。测试的续聊逻辑与顺序用例相同,但处理的是同一响应中的多个调用,并在最终校验中加入内容断言(tool_multiple_test.go):

if !strings.Contains(strings.ToLower(finalText), "weather") && !strings.Contains(strings.ToLower(finalText), "25") { t.Errorf("Expected response to contain weather or calculation info, got: %s", finalText) }

即最终回答必须包含来自天气工具与计算器工具的信息(100 / 4 = 25)。仓库中 Anthropic 协议侧的并行工具转换有对应的测试数据佐证,可参考 llm/transformer/anthropic/testdata/anthropic-parallel_multiple_tool.request.json 与 llm/transformer/anthropic/testdata/llm-parallel_multiple_tool.stream.jsonl,从中可见网关在协议转换层对并行工具调用(多个 tool_use 同时出现)的完整处理样本。

4.3 TestToolChoiceRequired — 强制工具选择

有些查询必须走指定工具,此时可通过ToolChoice强制模型调用特定函数。该用例的提示词为:

Please use the calculate tool to compute 50 * 30 and tell me the result.

请求构造(tool_multiple_test.go):

params := anthropic.MessageNewParams{ Model: helper.GetModel(), Messages: messages, Tools: tools, ToolChoice: anthropic.ToolChoiceUnionParam{ OfTool: &anthropic.ToolChoiceToolParam{ Name: "calculate", }, }, MaxTokens: 1024, }

测试首先断言响应一定是StopReasonToolUse(若模型直接回答则t.Fatalf),随后确认被调用的正是calculate函数(tool_multiple_test.go):

if toolUseBlock == nil { t.Fatal("Expected calculate function to be called") }

值得注意的细节:在续聊的第二轮请求前,需要清空 ToolChoice(tool_multiple_test.go):

params.Messages = messages params.ToolChoice = anthropic.ToolChoiceUnionParam{}

否则模型在拿到tool_result后仍可能被强制继续调用工具而无法给出最终文字回答。终答校验使用testutil.ContainsAnyCaseInsensitive(finalText, "1500", "1,500", "one thousand five hundred")(该工具函数定义在 helper.go),允许模型以不同格式呈现结果。

五、工具执行模拟实现

测试不依赖真实第三方服务,而是通过本地 mock 函数模拟执行结果。

天气工具(tool_multiple_test.go)内置了四个城市的固定天气数据:

城市温度天气湿度
New York22°CPartly cloudy65%
London18°CRainy80%
Tokyo25°CSunny60%
Paris20°CClear55%
其他城市20°CSunny50%(默认)

城市名通过normalizeLocation(转小写)做简单归一化后查表。

计算器工具(tool_multiple_test.go)则直接对固定表达式返回预期值:

switch expression { case "15 * 23": return 345 case "100 / 4": return 25 case "50 * 30": return 1500 case "10 + 5": return 15 default: return 42 // Default answer }

需要说明:simulateCalculatorFunction是固定查表实现,并非真正解析任意表达式(源码注释也明确指出真实实现应使用数学库)。因此运行测试时应使用与用例提示词一致的表达式;这也是集成测试中"模拟工具(tool simulation)"的通用做法,即只验证协议闭环,不引入外部计算依赖。

六、运行测试

6.1 目录内直接运行

按 README.md 提供的命令,在integration_test/anthropic/tool_multiple目录下执行:

# 运行本目录全部多工具测试 go test -v . # 运行指定的单个用例 go test -v -run TestMultipleToolsSequential go test -v -run TestMultipleToolsParallel go test -v -run TestToolChoiceRequired

6.2 通过 Makefile 运行

integration_test/anthropic/Makefile 提供了test-tools目标,会同时跑单工具与多工具两组用例:

make test-tools

其等价命令为:

go test --count=1 -v ./tool_single go test --count=1 -v ./tool_multiple

使用--count=1可避免 Go 测试缓存在本地未变更代码时直接复用上次结果,保证每次都是真实调用。

6.3 运行前提

  • Go 版本与依赖:仓库 go.mod 声明go 1.25.2并依赖github.com/anthropics/anthropic-sdk-go v1.26.0,首次运行前执行go mod tidy;
  • API Key:必须设置TEST_AXONHUB_API_KEY,否则用例会被Skip跳过;
  • 网络可达:TEST_ANTHROPIC_BASE_URL默认指向http://localhost:8090/anthropic(即本地 AxonHub 网关的 Anthropic 协议入口),若直连 Anthropic 官方地址请显式覆盖;
  • 模型能力:多工具并行与强制 tool choice 依赖模型对 Anthropic 工具调用协议的支持,README 中亦提示"并行工具调用并非所有模型都支持"(见 README.md)。

6.4 常见失败排查

  • 测试被跳过:TEST_AXONHUB_API_KEY未设置或配置校验失败,用例以Skipf退出;
  • 未检测到工具调用:模型直接给出文本回答,此时用例走"直接响应"分支并校验文本非空。若希望模型必然调用工具,应使用ToolChoice强制指定;
  • 终答校验失败:TestMultipleToolsParallel要求回答包含 weather 信息或计算结果25;TestToolChoiceRequired要求出现1500。若模型回答表述偏差,可结合go test -v输出的t.Logf日志定位。

七、总结与扩展阅读

多工具集成测试覆盖了 Anthropic 工具调用协议的三个关键模式:多工具声明(Tools)、结果回填续聊(ToolResultBlock+response.ToParam())、强制路由(ToolChoice)。这套模式可直接复用到 Agent 应用开发中:任何需要"模型自主挑选多个函数并汇总结果"的场景(查天气 + 算账 + 搜资料等),都可以参照 tool_multiple_test.go 的循环结构实现。

如需继续深入,可参考仓库内以下资料:

  • 集成测试总览 — 全部 Anthropic 测试用例(QA、单工具、多轮对话、流式、追踪)索引;
  • 单工具测试说明 — 与多工具场景互补的基础调用示例;
  • 测试基础设施 — 环境变量与客户端配置的完整源码;
  • Makefile — 各测试套件的快捷运行目标;
  • llm/transformer/anthropic/ — 网关侧 Anthropic 协议转换实现,其中 testdata 目录存放了并行多工具请求/响应/流的转换样本,可作为理解网关如何处理多工具调用的源码级参考。
  • AI 应用
  • API网关
  • LLM 网关
  • 后端
  • 前端

【免费下载链接】axonhub

⚡️ Open-source AI Gateway — Use any SDK to call 100+ LLMs. Built-in failover, load balancing, cost control & end-to-end tracing.

项目地址:https://gitcode.com/gh_mirrors/ax/axonhub
点击查看免费下载

相关推荐

上一篇:革命性AI工具Paper2Slides:一键将论文转换为专业演示文稿
下一篇:从零到一:Bark文本转语音模型实战指南与性能优化技巧

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询