首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Go 做 Function Calling 服务端:解析 tool_calls 与执行逻辑

Go 做 Function Calling 服务端:解析 tool_calls 与执行逻辑

作者头像
技术圈
发布2026-03-02 20:02:16
发布2026-03-02 20:02:16
210
举报

大模型支持「工具调用」后,对话里可以查天气、查库、调 API;模型会返回该调用哪个函数、传什么参数。服务端要做的,就是解析模型返回的 tool_calls、执行对应逻辑、把结果塞回对话。用 Go 实现,结构清晰、易维护。下面说清楚解析、执行与一整轮怎么串起来。


Function Calling 与 tool_calls 是什么?

Function Calling(Tool Use)指:你把可调用的函数列表以 JSON Schema 等形式传给大模型,模型在需要时会在回复里带 tool_calls,指明函数名和参数。服务端解析后执行真实逻辑,把结果再发给模型,由模型生成最终回答。

流程:用户发消息 → 带 tools 请求模型 → 模型可能返回 tool_calls(id、函数名、参数 JSON)→ 服务端解析并执行 → 把工具结果按约定格式追加到 messages → 再请求模型得到最终回复。


定义结构体与解析

OpenAI 兼容接口里,choices[0].message.tool_calls 里每个元素含 idfunction.namefunction.argumentsarguments 是 JSON 字符串)。Go 里定义结构体便于解析:

代码语言:javascript
复制
type ToolCall struct {
 ID       string       `json:"id"`
 Function FunctionCall `json:"function"`
}
type FunctionCall struct {
 Name      string `json:"name"`
 Arguments string `json:"arguments"`
}

从响应取出 message.ToolCalls,逐个把 Argumentsjson.Unmarshal 解成 map[string]interface{} 或具体类型,再交给执行层。


执行逻辑:注册表与统一分发

执行层做成「工具名 → 执行函数」的注册表,按 name 查找并执行:

代码语言:javascript
复制
type ToolFunc func(args string) (string, error)
type ToolRegistry struct { handlers map[string]ToolFunc }

func (r *ToolRegistry) Execute(name, args string) (string, error) {
 fn, ok := r.handlers[name]
 if !ok { return "", fmt.Errorf("unknown tool: %s", name) }
 return fn(args)
}

收到 tool_calls 后循环调用 Execute(tc.Function.Name, tc.Function.Arguments),把每个结果收集起来。


把工具结果塞回对话

模型要求工具结果以固定格式追加到 messages:role: "tool",并带上 tool_call_id

代码语言:javascript
复制
type ToolResultMessage struct {
 Role       string `json:"role"`
 Content    string `json:"content"`
 ToolCallID string `json:"tool_call_id"`
}

把本轮 assistant 消息和每条 tool 结果 append 到 messages,再发请求。若仍有 tool_calls,可循环「解析 → 执行 → 回写」直到没有或达到最大轮数。


一轮流程伪代码

代码语言:javascript
复制
msg := resp.Choices[0].Message
if len(msg.ToolCalls) == 0 { return msg.Content, nil }

var toolResults []ToolResultMessage
for _, tc := range msg.ToolCalls {
 result, _ := registry.Execute(tc.Function.Name, tc.Function.Arguments)
 toolResults = append(toolResults, ToolResultMessage{
  Role: "tool", Content: result, ToolCallID: tc.ID,
 })
}
// append 到 messages 后再次请求;有 tool_calls 则继续循环

注意事项

  • 安全:对参数校验、鉴权,避免误调危险接口。
  • 超时与错误:Execute 建议带 context/超时;失败时把错误信息写入 Content 返回给模型。
  • 轮数与 token:控制最大 tool 轮数和总 token。

写在最后

用 Go 做 Function Calling 服务端,核心三步:解析 tool_calls(含 arguments 的 JSON)、执行(注册表分发)、回写role: "tool" + tool_call_id 再请求)。定义好结构体、做一个 ToolRegistry,按上述消息格式塞回对话,即可完成一轮工具调用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术圈子 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Function Calling 与 tool_calls 是什么?
  • 定义结构体与解析
  • 执行逻辑:注册表与统一分发
  • 把工具结果塞回对话
  • 一轮流程伪代码
  • 注意事项
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档