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 再次推理并融合工具结果

最终回答

  • 直接回答用户问题
  • 保留必要出处/单位/时间