llm的system promts或者tools入参中,描述调用工具A的时机以及格式
以天气查询为例。系统提示词这么写:
如果用户有查询天气相关的请求,则需要使用<weather-tools>工具,请你先返回查询语句,格式如下。
LLM 意图识别成功后,将返回tools调用参数
比如也可以直接指定llm返回json格式:
{
"location": "北京",
"time": 98898312
}
后端解析llm返回的工具调用参数,调用api进行查询
用户输入 / 问题
例如:
- 明天北京天气?
- 帮我查下明天是否下雨
MCP 工具调用(高层流程)
- 客户端与 MCP 服务器建立会话(Stdio / WebSocket)
- 列出工具 listTools,选择合适工具
- 以 callTool 发送结构化参数
- 工具执行并可能以流式/分块返回结果
- 客户端整合并返回给 LLM/用户
关键要点(MCP)
- 请求/响应包裹 JSON-RPC 风格,含 id、method、params
- 能力:listTools、callTool、资源访问等
- 安全:工具白名单、沙箱、超时、参数校验
- 可观测:记录调用链路、错误、耗时
Go 片段:调用 MCP 工具(WebSocket 示例)
import (
"encoding/json"
"log"
"time"
"github.com/gorilla/websocket"
)
type Request struct {
JSONRPC string `json:"jsonrpc"`
ID int `json:"id"`
Method string `json:"method"`
Params interface{} `json:"params"`
}
func callMCP() error {
conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/mcp", nil)
if err != nil { return err }
defer conn.Close()
req := Request{
JSONRPC: "2.0",
ID: 1,
Method: "tools/call",
Params: map[string]any{
"name": "search",
"arguments": map[string]any{"q": "obsidian canvas 规范"},
},
}
if err := conn.WriteJSON(req); err != nil { return err }
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
var resp map[string]any
if err := conn.ReadJSON(&resp); err != nil { return err }
log.Println("MCP result:", resp)
return nil
}
错误与重试(要点)
- 参数 JSON Schema 校验失败 → 要求模型重试
- 工具超时/异常 → 降级回答或兜底提示
- 记录调用日志(prompt、args、latency)
Go 片段:OpenAI Function Calling(工具定义与解析)
import (
"context"
"encoding/json"
"os"
openai "github.com/sashabaranov/go-openai"
)
type WeatherArgs struct {
Location string `json:"location"`
Time int64 `json:"time,omitempty"`
}
func callWithTool() {
client := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
schema := map[string]any{
"type": "object",
"properties": map[string]any{
"location": map[string]any{"type":"string"},
"time": map[string]any{"type":"integer"},
},
"required": []string{"location"},
}
req := openai.ChatCompletionRequest{
Model: "gpt-4o-mini",
Messages: []openai.ChatCompletionMessage{
{Role: "system", Content: "你是天气助手"},
{Role: "user", Content: "明天北京天气怎么样?"},
},
Tools: []openai.Tool{
{Type: openai.ToolTypeFunction, Function: &openai.FunctionDefinition{
Name: "get_weather",
Description: "查询天气",
Parameters: schema,
}},
},
}
resp, _ := client.CreateChatCompletion(context.Background(), req)
for _, tc := range resp.Choices[0].Message.ToolCalls {
if tc.Function.Name == "get_weather" {
var args WeatherArgs
_ = json.Unmarshal([]byte(tc.Function.Arguments), &args)
// 调用你的后端/外部API...
// 然后将工具结果作为新消息反馈给模型
}
}
}
将工具结果反馈给 LLM
- 以 function_call 的 function result / tool result 形式返回给模型
- LLM 再次推理并融合工具结果
最终回答
- 直接回答用户问题
- 保留必要出处/单位/时间