ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Java SDK 工具调用(Tool Use)实战指南:从 BetaToolRunner 自动循环到 Anthropic 内置工具

Java SDK 工具调用(Tool Use)实战指南:从 BetaToolRunner 自动循环到 Anthropic 内置工具 人工智能大模型AI 应用移动开发交互助手【免费下载链接】rikkahubRikkaHub is an Android APP that supports for multiple LLM providers.项目地址https://gitcode.com/gh_mirrors/ri/rikkahub点击查看免费下载本篇技术指南以 Anthropic Java SDK 的 Tool Use 能力为主线系统讲解 Beta 工具运行器BetaToolRunner自动循环、注解类工具声明、内存工具后端、手写 JSON Schema、结构化输出以及 Web Search / Bash / 代码执行等 Anthropic 内置工具与 MCP 连接器的正确用法。文中除完整代码示例外还结合开源项目 RikkaHub 中 ClaudeProvider.kt 与 ClaudeServerToolTest.kt 的真实实现展示工具定义、tool_use/tool_result往返、pause_turn续跑等服务端工具协议在生产代码中的落地方式。读完本篇你将掌握在 Java 中构建可自动执行的工具调用链、结构化约束输出与 Anthropic 内置工具的完整方案。概念总览工具定义结构、工具选择策略、使用技巧请先参阅 tool-use-concepts.md本篇聚焦 Java 语言级实现。一、工具调用的两条实现路线在进入 Java 代码前先明确两条路线详见 tool-use-concepts.md 的 “Tool Runner vs Manual Loop”路线说明适用场景Tool Runner推荐BetaSDK 自动处理 agentic loop调用 API → 识别工具请求 → 执行你的工具函数 → 把结果回喂给 Claude → 重复直至模型不再调用工具常规工具编排Java/Python/TypeScript/Go/Ruby/PHP SDK 均可用Beta手动循环Manual Loop自行处理tool_use块、回传tool_result、循环至stop_reason end_turn需要细粒度控制自定义日志、条件执行、人工审批human-in-the-loop无论哪条路线tool_choice都控制 Claude 何时使用工具取值行为{type: auto}Claude 自行决定是否使用工具默认{type: any}Claude 至少必须使用一个工具{type: tool, name: ...}Claude 必须使用指定工具{type: none}Claude 不得使用工具任意tool_choice还可附加disable_parallel_tool_use: true强制每次响应最多调用一个工具默认情况下 Claude 允许在单次响应中发起多个工具调用。二、Beta 工具调用注解类 BetaToolRunner 自动循环Java SDK 以注解类支持 Beta 工具调用。工具类实现SupplierStringBetaToolRunner会自动执行import com.anthropic.models.beta.messages.MessageCreateParams; import com.anthropic.models.beta.messages.BetaMessage; import com.anthropic.helpers.BetaToolRunner; import com.fasterxml.jackson.annotation.JsonClassDescription; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import java.util.function.Supplier; JsonClassDescription(Get the weather in a given location) static class GetWeather implements SupplierString { JsonPropertyDescription(The city and state, e.g. San Francisco, CA) public String location; Override public String get() { return The weather in location is sunny and 72°F; } } BetaToolRunner toolRunner client.beta().messages().toolRunner( MessageCreateParams.builder() .model(claude-opus-4-8) .maxTokens(16000L) .putAdditionalHeader(anthropic-beta, structured-outputs-2025-11-13) .addTool(GetWeather.class) .addUserMessage(Whats the weather in San Francisco?) .build()); for (BetaMessage message : toolRunner) { System.out.println(message); }要点拆解JsonClassDescription/JsonPropertyDescription来自 Jackson 注解Tool Runner 会从类与字段上自动推导出工具名、描述与输入 JSON Schema无需手写 schema。SupplierString工具的返回值会作为tool_result的内容自动回传BetaToolRunner以可迭代方式返回每次模型响应直到循环自然结束。putAdditionalHeader(anthropic-beta, structured-outputs-2025-11-13)结构化输出Structured OutputsBeta 头配合类注解可获得带类型约束的工具参数校验。安全性提醒Tool Runner 会在 Claude 请求时自动执行你的工具函数。对于有副作用的工具发邮件、改数据库、金融交易必须在函数内校验输入必要时改用手动循环以引入人工确认见共享文档安全章节。三、内存工具Memory ToolBetaMemoryToolHandler后端内存工具让 Claude 能够跨会话在内存文件目录中存取信息支持view、create、str_replace、insert、delete、rename命令操作/memories目录下的文件。Java SDK 提供BetaMemoryToolHandler供实现存储后端BetaToolRunner会自动处理内存工具调用import com.anthropic.helpers.BetaMemoryToolHandler; import com.anthropic.helpers.BetaToolRunner; import com.anthropic.models.beta.messages.BetaMemoryTool20250818; import com.anthropic.models.beta.messages.BetaMessage; import com.anthropic.models.beta.messages.MessageCreateParams; import com.anthropic.models.beta.messages.ToolRunnerCreateParams; // Implement BetaMemoryToolHandler with your storage backend (e.g., filesystem) BetaMemoryToolHandler memoryHandler new FileSystemMemoryToolHandler(sandboxRoot); MessageCreateParams createParams MessageCreateParams.builder() .model(claude-opus-4-8) .maxTokens(4096L) .addTool(BetaMemoryTool20250818.builder().build()) .addUserMessage(Remember that my favorite color is blue) .build(); BetaToolRunner toolRunner client.beta().messages().toolRunner( ToolRunnerCreateParams.builder() .betaMemoryToolHandler(memoryHandler) .initialMessageParams(createParams) .build()); for (BetaMessage message : toolRunner) { System.out.println(message); }注意与普通的addTool(GetWeather.class)不同这里通过ToolRunnerCreateParams.betaMemoryToolHandler(...)注入后端处理器并用initialMessageParams(createParams)承载消息与BetaMemoryTool20250818工具声明。更完整的内存工具概念与安全指引见共享文档的 “Client-Side Tools: Memory” 章节——其中明确要求切勿在内存文件中存放 API Key、密码等机密参考实现没有内置访问控制多用户系统需实现按用户隔离的目录与认证。四、非 Beta 工具声明手写 JSON Schema非 Beta 路径client.messages()下Tool.InputSchema.Properties是自由形式的MapString, JsonValue包装——通过putAdditionalProperty构建属性 schematype: object为默认值。builder 提供直接.addTool(Tool)重载自动包装进ToolUnionimport com.anthropic.core.JsonValue; import com.anthropic.models.messages.Tool; Tool tool Tool.builder() .name(get_weather) .description(Get the current weather in a given location) .inputSchema(Tool.InputSchema.builder() .properties(Tool.InputSchema.Properties.builder() .putAdditionalProperty(location, JsonValue.from(Map.of(type, string))) .build()) .required(List.of(location)) .build()) .build(); MessageCreateParams params MessageCreateParams.builder() .model(Model.CLAUDE_SONNET_4_6) .maxTokens(16000L) .addTool(tool) .addUserMessage(Weather in Paris?) .build();该路径等价于 API 层的原始 JSON 定义namedescriptioninput_schema见共享文档首节的get_weather示例。工具定义的实践要点名称清晰具描述性get_weather优于weather描述要**规定“何时调用”**而非仅说明“做什么”——对调用更保守的新 Opus 模型在描述中写明触发条件可显著提升 should-call 率每个属性都要有描述取值固定时用enum真正必填的参数才列入required其余用默认值保持可选。若需要完全手动控制循环处理响应中的tool_use块 → 回传tool_result→ 循环至stop_reason end_turn且始终保留完整的response.content以保序还原tool_use块。五、消息往返用 Content Blocks 构建MessageParam工具结果回传MessageParam.Content是内部联合类string | list。构建工具结果消息时请使用 builder 的.contentOfBlockParams(ListContentBlockParam)别名——不存在独立的MessageParamContent类及静态ofBlockParams方法import com.anthropic.models.messages.MessageParam; import com.anthropic.models.messages.ContentBlockParam; import com.anthropic.models.messages.ToolResultBlockParam; ListContentBlockParam results List.of( ContentBlockParam.ofToolResult(ToolResultBlockParam.builder() .toolUseId(toolUseBlock.id()) .content(yourResultString) .build()) ); MessageParam toolResultMsg MessageParam.builder() .role(MessageParam.Role.USER) .contentOfBlockParams(results) // builder alias for Content.ofBlockParams(...) .build();关键约束每个tool_result必须携带与tool_use匹配的toolUseIdClaude 可能在单次响应中请求多个工具应全部处理完后再把结果放在同一个user消息中一次性回传。工具执行失败时在tool_result中设置is_error: true并给出信息量足够的错误文案Claude 会据此更换方案或请求澄清。RikkaHub 中的落地tool_use / tool_result 分块往返开源项目 RikkaHub 的 Claude 通道在 ClaudeProvider.kt 中实现了完全等价的消息构造逻辑将UIMessagePart.Tool输出为tool_use块含id、name、input见toToolUseBlock()紧随其后在同一 user 轮次输出tool_result块tool_use_id 内容块数组见toToolResultBlock()通过groupPartsByToolBoundary把 assistant 消息按 “内容 / 工具边界” 分组保证tool_use与其tool_result严格相邻成对输出见addAssistantMessage()。ClaudeServerToolTest.kt 中的server tool history should replay original Claude blocks with final input与parallel server tool history should replay all calls before results用例直接验证了多工具调用时 “先全部 calls、后全部 results” 以及顺序调用时保持交错块序的回放规则。六、结构化输出Structured Output类重载会自动从 POJO 推导 JSON Schema并返回带类型的.text()——无需手写 schema、无需手动解析import com.anthropic.models.messages.StructuredMessageCreateParams; record Book(String title, String author) {} record BookList(ListBook books) {} StructuredMessageCreateParamsBookList params MessageCreateParams.builder() .model(Model.CLAUDE_SONNET_4_6) .maxTokens(16000L) .outputConfig(BookList.class) // returns a typed builder .addUserMessage(List 3 classic novels) .build(); client.messages().create(params).content().stream() .flatMap(cb - cb.text().stream()) .forEach(typed - { // typed.text() returns BookList, not String for (Book b : typed.text().books()) System.out.println(b.title()); });支持 Jackson 注解JsonPropertyDescription、JsonIgnore、ArraySchema(minItems...)。手动 schema 路径OutputConfig.builder().format(JsonOutputFormat.builder().schema(...).build())。JSON Schema 能力边界来自共享文档结构化输出支持基础类型object/array/string/integer/number/boolean/null、enum、const、anyOf、allOf、$ref/$def、字符串格式date-time、time、date、duration、email、hostname、uri、ipv4、ipv6、uuid、且所有对象必须additionalProperties: false。不支持递归 schema、数值约束minimum/maximum/multipleOf、字符串长度约束minLength/maxLength、复杂数组约束、非false的additionalProperties。实践注意新 schema 首次请求有一次性的编译开销之后同一 schema 在 24 小时内命中缓存若stop_reason为refusal安全拒绝或max_tokens输出截断返回可能不符合 schema后者应增大max_tokens。结构化输出与 Citations、消息预填充prefilling不兼容但与 Batches API、流式、token 计数、扩展思考兼容。七、Anthropic 内置工具版本后缀类型name/type由 builder 自动设置。多数工具类型有直接的.addTool()重载缺失时较新或较少见的工具用联合类型的静态工厂包装.addTool(BetaToolUnion.ofToolName(builder…build()))。Web Search 与代码执行由服务端执行Bash 与文本编辑器由客户端执行你需在本地处理tool_use详见共享文档。import com.anthropic.models.messages.WebSearchTool20260209; import com.anthropic.models.messages.ToolBash20250124; import com.anthropic.models.messages.ToolTextEditor20250728; import com.anthropic.models.messages.CodeExecutionTool20260120; .addTool(WebSearchTool20260209.builder() .maxUses(5L) // optional .allowedDomains(List.of(example.com)) // optional .build()) .addTool(ToolBash20250124.builder().build()) .addTool(ToolTextEditor20250728.builder().build()) .addTool(CodeExecutionTool20260120.builder().build())还可用WebFetchTool20260209、MemoryTool20250818、ToolSearchToolBm25_20251119。顾问工具advisor tool使用 Beta 命名空间的BetaAdvisorTool20260301配合.addBeta(advisor-tool-2026-03-01)服务端执行advisor 模型能力须 ≥ executor 模型Beta builder 上没有直接的.addTool(BetaAdvisorTool20260301)重载——需经BetaToolUnion静态工厂按 advisor 类型包装若javac拒绝特定工厂方法名可用javap com.anthropic.models.beta.messages.BetaToolUnion | grep -i advisor查看准确签名。服务端工具与客户端工具的安全边界Bash 工具tool_use.input为{command: string}或{restart: true}——先检查restart重置会话并返回确认串否则执行command并合并返回 stdout stderr。命令是不可信的模型输出必须在隔离环境运行用可执行文件白名单并拒绝、|、;、反引号、$()等 shell 操作符设置超时与资源上限blocklist 不够。文本编辑器command支持view/create/str_replace/insert输入含path、view_range、file_text、old_str、new_str、insert_line等。path同样是不可信模型输出必须解析为规范路径并校验其仍位于项目根目录内拒绝..、符号链接、根外绝对路径与%2e%2e%2f编码穿越。出错时回传{type: tool_result, tool_use_id: ..., content: error text, is_error: true}以便 Claude 恢复。RikkaHub 中的内置工具声明RikkaHub 在 Model.kt 中以BuiltInTools密封类抽象内置工具Search、UrlContext、ImageGenerationClaude 通道将其映射为 Anthropic 托管搜索工具BuiltInTools.Search - add(buildJsonObject { put(type, web_search_20250305) put(name, web_search) })见 ClaudeProvider.kt。注意 RikkaHub 当前使用的是web_search_20250305版本不带动态过滤的既有版本文档示例中的WebSearchTool20260209是支持动态过滤dynamic filtering的最新变体适用于 Fable 5 / Opus 4.8 / Opus 4.7 / Opus 4.6 / Sonnet 4.6 等模型。测试 ClaudeServerToolTest.kt 中的Claude request should enable hosted web search用例直接断言了该声明的type与name。八、Beta 命名空间MCP 连接器与 compactionBeta 专属功能使用com.anthropic.models.beta.messages.*——类名带Beta前缀且位于 beta 包中。BetaMessageCreateParams.Builder同时提供直接的.addTool(BetaToolBash20250124)重载与.addMcpServer()import com.anthropic.models.beta.messages.MessageCreateParams; import com.anthropic.models.beta.messages.BetaToolBash20250124; import com.anthropic.models.beta.messages.BetaCodeExecutionTool20260120; import com.anthropic.models.beta.messages.BetaRequestMcpServerUrlDefinition; MessageCreateParams params MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_4_8) .maxTokens(16000L) .addBeta(mcp-client-2025-11-20) .addTool(BetaToolBash20250124.builder().build()) .addTool(BetaCodeExecutionTool20260120.builder().build()) .addMcpServer(BetaRequestMcpServerUrlDefinition.builder() .name(my-server) .url(https://example.com/mcp) .build()) .addUserMessage(...) .build(); client.beta().messages().create(params);重要约束BetaTool*类型与普通Tool*不可互换——每个请求只能选一个命名空间。MCP 连接器的核心配对规则见共享文档mcp_servers数组定义连接[{type: url, url: server URL, name: server-name, authorization_token: optional}]tools中必须包含引用该服务名的mcp_toolset条目[{type: mcp_toolset, mcp_server_name: server-name}]两者名称必须一致缺少 toolset 条目会被校验拒绝。可选字段default_config如{enabled: false}的 allowlist 模式与configs按工具名覆盖。读取服务端工具块ServerToolUseBlock与代码执行结果ServerToolUseBlock提供.id()、.name()枚举和._input()返回原始JsonValue没有类型化的.input()。代码执行结果需要解包两层for (ContentBlock block : response.content()) { block.serverToolUse().ifPresent(stu - { System.out.println(tool: stu.name() input: stu._input()); }); block.codeExecutionToolResult().ifPresent(r - { r.content().resultBlock().ifPresent(result - { System.out.println(stdout: result.stdout()); System.out.println(stderr: result.stderr()); System.out.println(exit: result.returnCode()); }); }); }RikkaHub 中的服务端工具协议解析RikkaHub 在 ClaudeProvider.kt 的parseMessage中完整实现了服务端工具块解析识别server_tool_use与任意tool_tool_use类型记录callIndex并置为IN_PROGRESS识别tool_tool_result类型tool_result本身除外见isClaudeServerToolResultType()按tool_use_id配对到同一条ServerTool部件通过endsWith(_error)判定FAILED状态回放历史时按callIndex/resultIndex还原原始块顺序无索引的旧消息回退为先 calls 后 results见serverToolContentBlocks()。测试侧ClaudeServerToolTest.kt 验证了非流式响应中server_tool_use与web_search_tool_result的配对及max_uses_exceeded错误导致FAILED状态L78-L117 则验证流式场景下input_json_delta增量输入与结果块合并为同一工具部件。九、stop_reason与pause_turn服务端工具循环的续跑使用服务端工具代码执行、Web 搜索等时API 会在服务端运行采样循环若达到默认的 10 次迭代上限响应会携带stop_reason: pause_turn。续跑规则见共享文档把用户消息与 assistant 响应原样重新发送再次发起 API 请求服务端会自动从断点继续——不要额外插入 “Continue.” 之类的用户消息建议设置max_continuations上限如 5防止无限循环。RikkaHub 的 pause_turn 实现RikkaHub 将该规则固化进了 Claude 通道generateClaudeWithPauseTurn()与非流式的streamClaudeWithPauseTurn()以MAX_PAUSE_TURN_CONTINUATIONS 5为上限循环重发由于每次响应的 content block index 只在单次响应内有效rebaseClaudeServerToolIndexes会把后续响应的 server tool index 偏移到同一序号空间从而把多次响应合并为一个逻辑 assistant turn见 ClaudeProvider.kt 相关注释与实现。测试用例non streaming pause turn should continue inside Claude provider与streaming pause turn should expose one logical streamClaudeServerToolTest.kt精确验证了第二轮请求仅包含USER, ASSISTANT两条消息、pause_turn块被原样回放、最终只暴露一次end_turn且多轮 usage 被正确累加合并。十、高效使用工具的建议与安全清单工具使用技巧来自共享文档提供详细描述——Claude 高度依赖描述判断何时用、怎么用使用具体工具名get_current_weather优于weather执行前总是校验工具输入优雅处理错误——返回信息量足够的错误信息让 Claude 能调整策略控制工具数量——工具过多会干扰模型保持集合聚焦测试工具交互——在不同场景下验证 Claude 是否正确地使用工具。安全清单Tool Runner 自动执行工具函数有副作用工具须内置输入校验破坏性操作需人工确认Bash 命令是不可信模型输出白名单 拒绝 shell 操作符 超时资源限制 全量日志文本编辑器的path必须解析规范路径并限定在项目根内防路径穿越内存工具不得存放 API Key 等机密多用户系统须做目录隔离与认证服务端工具代码执行返回的下载文件名须用basename清洗后再落盘。附快速定位与排查Java SDK 类型按包组织详见 java README.md 的 Package Reference 表com.anthropic.models.messages非 Beta 请求/响应类型如MessageCreateParams、Model、Tool*ToolBash20250124、ToolTextEditor20250728、StructuredMessage*com.anthropic.models.beta.messagesBeta 端点类型如BetaMessage、BetaTool*、BetaRequestMcpServerUrlDefinitioncom.anthropic.coreJsonValue、JsonField、StreamResponse等。client.messages()使用前者client.beta().messages()使用后者两个包都定义了MessageCreateParams请按实际调用的客户端路径导入对应版本。若某类或 builder 方法不在文档表格中jar tf anthropic-java-core jar | grep -i term或javap -classpath jar com.anthropic.models.…可快速定位成员名让编译器错误cannot find symbol指正写错的成员即可无需运行独立的反射枚举程序。赞分享人工智能大模型AI 应用移动开发交互助手【免费下载链接】rikkahubRikkaHub is an Android APP that supports for multiple LLM providers.项目地址https://gitcode.com/gh_mirrors/ri/rikkahub点击查看免费下载相关推荐Qwen-Agent Tool 体系实战指南从内置工具调用到自定义工具开发Qwen Agent Tool 体系实战指南从内置工具调用到自定义工具开发 Tool工具是 Qwen Agent 中连接 Agent 与大模型之外真实能力人工智能大模型AI AgentAgent 框架工具调用RAGClaude API 与 Agentic Awesome SkillsTypeScript SDK 工具调用Tool Use实战指南Claude API 与 Agentic Awesome SkillsTypeScript SDK 工具调用Tool Use实战指南 本篇指南以本仓库 cAI 技能AI 插件使用 Claude API Go SDK 构建 LLM 应用从消息请求到 BetaToolRunner 工具循环agentic-awesome-skills 实战指南使用 Claude API Go SDK 构建 LLM 应用从消息请求到 BetaToolRunner 工具循环agentic awesome skillsAI 技能AI 插件上一篇Kamailio SIP服务器项目推荐下一篇深入解析 eapache/queueCilium 仓库中的 Go 环形缓冲区队列实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表