RikkaHub 视角下的 Claude API Tool Use:C SDK 工具调用、回放循环与结构化输出实战指南
发布时间:2026/9/27 7:01:13来源:尧图网络
人工智能大模型AI 应用移动开发交互助手【免费下载链接】rikkahubRikkaHub is an Android APP that supports for multiple LLM providers.项目地址https://gitcode.com/gh_mirrors/ri/rikkahub点击查看免费下载本篇技术指南以 RikkaHub 仓库中沉淀的 Claude API Tool Use 文档.agents/skills/claude-api/csharp/claude-api/tool-use.md为核心骨架系统讲解在 .NET / C# 环境中如何用官方 Anthropic SDK 定义工具、驱动 Agent 工具调用循环、回放多轮 tool_use/tool_result 历史以及使用结构化输出、Anthropic 预置工具与 Beta Tool Runner。同时我们以 RikkaHub 的 Android 多 LLM 客户端为参照其 Claude 接入实现在 ClaudeProvider.kt从源码与测试层面印证同样的消息协议与循环模式在不同语言、不同端侧下的工程落地方式。读完本文你将能够在 C# 中完成一个可运行的 Claude 工具调用 Agent并理解多轮工具历史回放、pause_turn续跑、服务端工具等关键机制的底层原理。一、Tool Use 概念基础先理解协议再写代码工具调用Tool Use的本质是模型不直接执行外部动作而是在回复中输出结构化调用意图tool_use块由你的代码负责真正执行并把结果以tool_result块回传给模型模型再基于结果继续推理。C# 的 tool-use.md 文档开头便指向概念总纲文档 .agents/skills/claude-api/shared/tool-use-concepts.md其中给出了每个工具三要素的 JSON Schema 标准结构{ name: get_weather, description: Get current weather for a location, input_schema: { type: object, properties: { location: { type: string, description: City and state, e.g., San Francisco, CA }, unit: { type: string, enum: [celsius, fahrenheit], description: Temperature unit } }, required: [location] } }工具定义的最佳实践包括使用清晰、描述性的名称如get_weather、search_database、send_email描述要写明何时调用而不只是做什么——Claude 依据描述决定是否调用工具在近期 Opus 系列模型上触发条件写得越明确should-call 率提升越可测量为每个属性补充 description参数取值固定时使用enum真正必填的参数才放进required其余用默认值保持可选。1.1 tool_choice控制 Claude 何时用工具值行为{type: auto}Claude 自行决定是否使用工具默认{type: any}Claude 必须至少调用一个工具{type: tool, name: ...}Claude 必须调用指定工具{type: none}Claude 禁止使用工具任何tool_choice值都可附带disable_parallel_tool_use: true强制 Claude 每次回复最多调用一个工具默认情况下 Claude 可以在单次回复中请求多个并行工具调用。1.2 工具循环的两种驱动方式Tool Runner推荐SDK 自动完成调 API → 发现 tool_use → 执行你的工具函数 → 回传结果 → 再次调用的循环Python、TypeScript、Java、Go、Ruby、PHP 与 C# SDK 均提供Beta。手动 Agentic Loop当你需要细粒度控制自定义日志、条件执行、人工审批时使用。循环直到stop_reason end_turn始终原样追加完整的response.content以保留 tool_use 块并确保每个tool_result携带匹配的tool_use_id。安全提醒Tool Runner 会在 Claude 请求时自动执行你的工具函数。对有副作用的工具发邮件、改数据库、转账必须在工具函数内部校验输入对破坏性操作要求确认需要人工审批时改用手动循环。二、C# 中定义工具Tool 与 InputSchemaC# SDK 中定义工具使用Tool类型不是ToolParam搭配InputSchemarecord。关键点InputSchema.Type由构造函数自动设置为object不要手动设置ToolUnion提供来自Tool的隐式转换集合表达式[...]会自动触发因此无需显式包装。using System.Text.Json; using Anthropic.Models.Messages; var parameters new MessageCreateParams { Model Model.ClaudeSonnet4_6, MaxTokens 16000, Tools [ new Tool { Name get_weather, Description Get the current weather in a given location, InputSchema new() { Properties new Dictionarystring, JsonElement { [location] JsonSerializer.SerializeToElement( new { type string, description City name }), }, Required [location], }, }, ], Messages [new() { Role Role.User, Content Weather in Paris? }], };上述模式派生自anthropic-sdk-csharp/src/Anthropic/Models/Messages/Tool.cs与ToolUnion.cs:799隐式转换。C# 中ContentBlock是联合类型包装器用.Value解包出具体变体对象再用TryPick*或 LINQOfTypeT()过滤。这一结构在 RikkaHub 的 Android 端有直接对应物其通用工具抽象定义在 ai/src/main/java/me/rerere/ai/core/Tool.kt同样包含name、description、parameters惰性求值的InputSchema、systemPrompt、needsApproval审批钩子与execute挂起执行函数而InputSchema同样只有Obj一种形态且强制type objectSerializable data class Tool( val name: String, val description: String, val parameters: () - InputSchema? { null }, val systemPrompt: (model: Model, messages: ListUIMessage) - String { _, _ - }, val needsApproval: (JsonElement) - Boolean { false }, val execute: suspend (JsonElement) - ListUIMessagePart )三、把响应内容回放为后续 assistant 消息没有 .ToParam() 的逐块重建工具调用的多轮对话中你需要把 Claude 的上一轮响应可能包含 text、thinking、tool_use 等多种 content block原样回放到下一轮请求的 assistant 消息里。C# SDK 没有.ToParam()助手——必须手动把每个ContentBlock变体重建为对应的*Param类型。严禁使用new ContentBlockParam(block.Json)它能编译也能序列化但.Value始终为null导致TryPick*/Validate()失效退化为 JSON 直通而非类型化路径。using Anthropic.Models.Messages; Message response await client.Messages.Create(parameters); // No .ToParam() — reconstruct per variant. Implicit conversions from each // *Param type to ContentBlockParam mean no explicit wrapper. ListContentBlockParam assistantContent []; ListContentBlockParam toolResults []; foreach (ContentBlock block in response.Content) { if (block.TryPickText(out TextBlock? text)) { assistantContent.Add(new TextBlockParam { Text text.Text }); } else if (block.TryPickThinking(out ThinkingBlock? thinking)) { // Signature MUST be preserved — the API rejects tampering assistantContent.Add(new ThinkingBlockParam { Thinking thinking.Thinking, Signature thinking.Signature, }); } else if (block.TryPickRedactedThinking(out RedactedThinkingBlock? redacted)) { assistantContent.Add(new RedactedThinkingBlockParam { Data redacted.Data }); } else if (block.TryPickToolUse(out ToolUseBlock? toolUse)) { // ToolUseBlock has required Caller; ToolUseBlockParam.Caller is optional — dont copy it assistantContent.Add(new ToolUseBlockParam { ID toolUse.ID, Name toolUse.Name, Input toolUse.Input, }); // Execute the tool; collect ONE result per tool_use block — the API // rejects the follow-up if any tool_use ID lacks a matching tool_result. string result ExecuteYourTool(toolUse.Name, toolUse.Input); toolResults.Add(new ToolResultBlockParam { ToolUseID toolUse.ID, Content result, }); } } // Follow-up: prior messages assistant echo user tool_result(s) ListMessageParam followUpMessages [ .. parameters.Messages, new() { Role Role.Assistant, Content assistantContent }, new() { Role Role.User, Content toolResults }, ];几个易错点务必注意thinking 的Signature必须逐字保留——API 会校验签名完整性篡改或丢失都会导致请求被拒RikkaHub 在 ClaudeProvider.kt 的回放逻辑中同样将ClaudeReasoningMetadata.signature写回thinking块ToolUseBlock有必填的Caller而ToolUseBlockParam.Caller可选——不要拷贝它每个tool_use必须恰好有一个匹配的tool_result缺失会导致后续请求被 API 拒绝并行工具调用时把多个tool_result放进同一条 user 消息一次回传ToolResultBlockParam没有元组构造函数必须使用对象初始化器其Content是 string-or-list 联合类型普通string会隐式转换。3.1 消息序列的协议约束从协议层面看assistant 的tool_use块必须紧跟一条 user 消息内的tool_result。RikkaHub 的 ProviderMessageUtils.kt 用groupPartsByToolBoundary把消息 parts 按工具边界分组确保tool_use/functionCall之后紧跟tool_result/functionResponseaddAssistantMessage则在遇到工具组时先输出带tool_use的 assistant 消息、紧接着输出带tool_result的 user 消息见 ClaudeProvider.kt。对应的单测 ClaudeRequestMessageTest.kt 断言多轮工具调用会产生assistant[tool_use] → user[tool_result]的交替结构并行工具调用则要求 3 个tool_use与 3 个tool_result分别处于同一条消息内同文件 L357-L423。这些测试正是 C# 回放循环中逐块重建规则的工程镜像。四、结构化输出OutputConfig JsonOutputFormat当你想让 Claude 的回复严格遵循某个 JSON Schema保证可解析、可校验时使用结构化输出。它不是独立工具而是增强 Messages API 的响应格式与工具参数校验。C# 中的写法OutputConfig new OutputConfig { Format new JsonOutputFormat { Schema new Dictionarystring, JsonElement { [type] JsonSerializer.SerializeToElement(object), [properties] JsonSerializer.SerializeToElement( new { name new { type string } }), [required] JsonSerializer.SerializeToElement(new[] { name }), }, }, },要点JsonOutputFormat.Type由构造函数自动设置为json_schemaSchema为必填JSON Schema 支持object/array/string/integer/number/boolean/null 基础类型enum、const、anyOf、allOf、$ref/$def以及date-time、email、uri、uuid等字符串格式所有对象必须设置additionalProperties: false不支持递归 schema、数值约束minimum/maximum/multipleOf、字符串约束minLength/maxLength、复杂数组约束新 schema 首次请求有一次编译成本同一 schema 后续请求命中 24 小时缓存若stop_reason为refusal输出可能不符合 schema若为max_tokens输出可能不完整应调大max_tokens与 citations返回 400、消息预填充不兼容与 Batches、流式、token 计数、扩展思考兼容。在 RikkaHub 的 Claude 接入中output_config.effort被用于控制 adaptive thinking 的强度见 ClaudeProvider.ktReasoningLevel关闭时发送thinking: {type: disabled}AUTO 及更高档位发送{type: adaptive, display: summarized}并叠加output_config.effort——这与 C# 中OutputConfig new OutputConfig { Effort Effort.High }取值Low/Medium/High/Max是同一套请求字段的两端实现。五、Anthropic-Defined Tools内置 schema 的预置工具Web search、bash、text editor、code execution 是 Anthropic 预置工具schema 内建于模型。其中web search 与 code execution 由服务端执行bash 与 text editor 由客户端执行模型返回tool_use块后由你的代码在本地执行并把结果作为tool_result回传。类型名带版本后缀构造函数会自动设置name/type。注意C# 中每个都必须显式包一层new ToolUnion(...)Tools [ new ToolUnion(new WebSearchTool20260209()), new ToolUnion(new ToolBash20250124()), new ToolUnion(new ToolTextEditor20250728()), new ToolUnion(new CodeExecutionTool20260120()), ],另有new ToolUnion(new WebFetchTool20260209())与new ToolUnion(new MemoryTool20250818())。WebSearchTool20260209的可选参数包括AllowedDomains、BlockedDomains、MaxUses、UserLocation。5.1 服务端工具与客户端工具的差异服务端工具web search / code execution只需声明工具Anthropic 基础设施负责执行。服务端会运行采样循环若达到默认 10 次迭代上限响应会带有stop_reason: pause_turn。继续方式重新发送原 user 消息与 assistant 响应再做一次请求服务端会自动恢复——不要额外插入 Continue 之类的 user 消息API 检测到末尾的server_tool_use块会自动续跑。同时应设置max_continuations如 5防止死循环。客户端工具bash / text editorClaude 返回tool_use块后由你的代码执行。bash 的tool_use.input是{command: ...}或{restart: true}——先检查restart否则执行command并返回合并后的 stdoutstderr。text editor 的command有viewpath 可选view_range、createpathfile_text、str_replacepathold_strnew_str恰好匹配一处0 或 1 处报错、insertpathinsert_lineinsert_text。安全红线bash 命令是不可信的模型输出。必须在隔离环境容器/VM/受限用户运行用白名单限定可执行程序拒绝 shell 运算符、|、;、反引号、$()设置超时与资源限制并记录每条命令——黑名单不足以防御。text editor 的path同样是不可信输入执行前必须解析为规范路径并校验其仍处于项目根目录内拒绝..、符号链接、根目录外的绝对路径、%2e%2e%2f之类的 URL 编码穿越工具出错时返回{type: tool_result, tool_use_id: …, content: error text, is_error: true}以便 Claude 恢复。5.2 RikkaHub 的服务端工具落地内置 web_searchRikkaHub 把内置工具抽象为BuiltInToolsSearch、UrlContext、ImageGeneration 等在请求构建阶段将BuiltInTools.Search映射为托管 web search 工具声明见 ClaudeProvider.kt{ type: web_search_20250305, name: web_search }单测 ClaudeServerToolTest.kt 验证了该声明的 wire 格式。而parseMessage对响应中server_tool_use/{toolName}_tool_result等块类型的识别逻辑ClaudeProvider.kt与概念文档响应由 text、server_tool_use、*_tool_result交错组成的描述一一对应——isClaudeServerToolUseType()判断server_tool_use或以_tool_use结尾的类型isClaudeServerToolResultType()判断以_tool_result结尾排除普通tool_result错误结果*_error类型则标记为ServerToolStatus.FAILEDClaudeServerToolTest.kt。5.3 pause_turnRikkaHub 的服务端续跑实现概念文档强调 pause_turn 续跑时原样回放 assistant 响应、不插话。RikkaHub 在 Kotlin 端实现了完整的自动续跑generateClaudeWithPauseTurn/streamClaudeWithPauseTurnClaudeProvider.kt把多次服务端响应合并为一个逻辑 assistant turn最多续跑MAX_PAUSE_TURN_CONTINUATIONS 5次同文件 L84并对跨响应的server_tool_usecontent block 索引做 rebaserebaseClaudeServerToolIndexesL183-L209保证合并后的 tool 顺序正确。测试 ClaudeServerToolTest.kt 覆盖了非流式与流式两种 pause_turn 场景断言第二次请求的消息序列为[USER, ASSISTANT]回放内容含server_tool_use、最终stop_reason为end_turn、usage 为两轮之和——这正是概念文档max_continuations建议的工程化形态。六、Tool RunnerBeta自动工具执行循环C# SDK 提供BetaToolRunner自动完成API 调用 → 工具执行 → 结果回传的循环。使用Anthropic.Models.Beta.Messages命名空间以原始 JSON schema定义工具runner 会处理循环细节using Anthropic.Models.Beta.Messages; // Define tools and create params as shown in the Tool Use section above, // but using the beta namespace types (BetaToolUnion, etc.) var runner client.Beta.Messages.ToolRunner(betaParams); await foreach (BetaMessage message in runner) { foreach (var block in message.Content) { if (block.TryPickText(out var text)) { Console.WriteLine(text.Text); } } }工具循环的决策建议优先使用 Tool Runner自动循环最适合标准工具集概念文档还提到 Python SDK 提供 MCP 转换助手可将 MCP 工具、提示词与资源接入 runner手动 Agentic Loop 用于需要精细控制的场景自定义日志、条件执行、人工审批human-in-the-loop——循环条件以stop_reason end_turn为出口始终追加完整response.content控制工具数量工具过多会干扰模型判断保持集合聚焦用概念文档中的 6 条 Tips 自检——提供详细描述、使用具体名称、执行前校验输入、优雅处理错误、控制工具数量、测试工具交互。七、实战清单与仓库导航一个完整的 C# Claude 工具调用 Agent 需要串起以下步骤用ToolInputSchema定义工具第 2 节或声明 Anthropic 预置工具第 5 节创建MessageCreateParams发起请求按需设置tool_choice第 1.1 节与OutputConfig第 4 节收到响应后逐块重建assistant 内容并执行工具第 3 节保留 thinking 签名、为每个tool_use生成匹配的tool_result把历史消息 assistant 回放 tool_result拼成下一轮请求循环直至end_turn遇到pause_turn时原样重发续跑第 5.3 节涉及 bash / text editor / 文件写入时严格执行路径与命令安全校验第 5.1 节。继续深入当前仓库的推荐路径概念总纲.agents/skills/claude-api/shared/tool-use-concepts.mdtool_choice 表、pause_turn、服务端/客户端工具全解C# SDK 入门与命名空间参考.agents/skills/claude-api/csharp/claude-api/README.md含client.Messages.*与client.Beta.Messages.*两套类型的选型表C# 流式与批处理.agents/skills/claude-api/csharp/claude-api/streaming.md、.agents/skills/claude-api/csharp/claude-api/batches.md长时 Agent 的工具取舍与上下文管理.agents/skills/claude-api/shared/agent-design.mdAndroid 端同协议的完整实现ai/src/main/java/me/rerere/ai/provider/providers/claude/ClaudeProvider.kt 与测试 ai/src/test/java/me/rerere/ai/provider/providers/claude/ClaudeRequestMessageTest.kt、ai/src/test/java/me/rerere/ai/provider/providers/claude/ClaudeServerToolTest.kt。无论你使用 C# SDK 构建 .NET 服务还是像 RikkaHub 一样在 Android 端直接组装 Anthropic Messages 协议工具调用的核心纪律是一致的定义清晰的 schema、原样回放历史、严格配对 tool_result、安全执行模型输出。掌握本文的循环模式后你便可以在任意语言中复现这套可靠的 Agent 工具机制。赞分享人工智能大模型AI 应用移动开发交互助手【免费下载链接】rikkahubRikkaHub is an Android APP that supports for multiple LLM providers.项目地址https://gitcode.com/gh_mirrors/ri/rikkahub点击查看免费下载相关推荐AAS 仓库实战Claude API Python SDK 工具调用Tool Use完整指南——从 Tool Runner 到结构化输出AAS 仓库实战Claude API Python SDK 工具调用Tool Use完整指南——从 Tool Runner 到结构化输出 导读 本文是围绕AI 技能AI 插件Claude API Tool Use 概念与实战指南工具定义、Agentic Loop、服务端工具与结构化输出Claude API Tool Use 概念与实战指南工具定义、Agentic Loop、服务端工具与结构化输出 本文基于 agentic awesome sAI 技能AI 插件Claude API 与 Agentic Awesome SkillsTypeScript SDK 工具调用Tool Use实战指南Claude API 与 Agentic Awesome SkillsTypeScript SDK 工具调用Tool Use实战指南 本篇指南以本仓库 cAI 技能AI 插件上一篇【亲测免费】 TuneLab 使用教程下一篇PostgreSQL-HLL终极指南如何用1%内存统计十亿级数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网