原生 Function Calling 与结构化输出
Agent 与工具一章的 ReAct 模式依靠提示词驱动模型输出"行动指令"再自行解析。现代模型提供了原生的工具调用能力(Function Calling / Tool Use):工具声明随请求发送,模型以结构化字段返回调用意图,无需脆弱的文本解析。langchaingo 通过 llms.WithTools 暴露该能力。
定义工具
工具以 llms.Tool 声明,参数用 JSON Schema 描述:
Description 与参数描述直接决定模型选择工具、填充参数的准确度,应使用模型易于理解的自然语言,并明确取值格式。FunctionDefinition.Strict 可启用部分供应商支持的结构化输出严格模式。
工具调用循环
完整流程分四步:发送请求 → 执行模型选择的工具 → 将结果回传 → 获取最终回答。关键在于维护完整的消息历史:
核心类型一览:
OpenAI 兼容接口要求 ToolCallResponse.ToolCallID 与 tc.ID 一一对应,缺失或错配会导致 400 错误。Arguments 是 JSON 字符串而非结构体,必须反序列化后再使用,且对解析失败保持容错。
生产实现建议将工具注册表抽象为 map[string]func(ctx, args string) (string, error),用统一分发器替代 switch,新增工具只需注册。
与 ReAct Agent 的取舍
简单工具场景优先原生调用;需要复杂推理链、多工具编排时用 Agent,或在两者之上自建循环。
JSON Mode:可靠的结构化输出
要求模型输出 JSON 时,开启 llms.WithJSONMode() 强制响应格式,再配合 JSON 解析:
JSON Mode 只是"保证输出是合法 JSON",不校验 schema。要求字段精确匹配时,可将 JSON Schema 作为参数定义传给 WithTools 并将 ToolChoice 强制指向它(供应商支持时),或使用支持 Structured Outputs 的模型参数。
在 HTTP 服务中的整合
工具调用循环耗时不可控,接入工作池与超时控制可保障服务稳定性:
小结
llms.WithTools+ JSON Schema 参数定义实现原生工具调用,输出为结构化的ToolCall。- 工具调用必须维护完整消息历史,工具结果以
ChatMessageTypeTool角色 +ToolCallResponse回传。 - JSON Mode(
WithJSONMode)保证合法 JSON 输出;schema 级校验需供应商的 Structured Outputs 支持。 - 简单场景原生调用更可靠,复杂推理链用 Agent;两者都应置于超时与限流保护之下。