function Calling工具系统怎么实现

模型怎么调用工具

模型不能直接执行命令,不能直接访问文件系统;模型不能直接操作任何东西,只能输出文案(模型底层生成 Token 序列,但模型 API 可以按照协议把生成结果解释和暴露为文本、工具调用、结构化数据或其他类型的输出);那么模型怎么动手,它会输出一个协作协议,叫function Calling,也叫tool Use;整个流程分四步

  1. 告诉模型有哪些工具

    • 模型要调用工具需要先知道有哪些工具可以调用
    json 复制代码
    ​{​"tools": [{​
        "name": "ReadFile",​
            "description": "读取指定路径的文件内容。返回带行号的文件文本。路径必须是绝对路径。",
            ​"input_schema": {
                ​"type": "object",
                ​"properties": {
                ​"path": {
                    ​"type": "string",
                    ​"description": "文件的绝对路径"
                  ​}
                ​},
            ​"required": ["path"]
          ​}
        ​}]
    ​}

    注意:工具描述是整个工具系统里最重要的部分,直接决定了模型的工具使用行为,包括了什么时候调,调哪个,参数怎么传

    工具接口 复制代码
    {  
        ​name() -> string​
        description() -> string
        ​inputSchema() -> JSON Schema
        ​execute(context, input) -> ToolResult
        ​isReadOnly() -> boolean
        ​isDestructive() -> boolean
        ​isConcurrencySafe(input) -> boolean
        ​category() -> string
        ​validateInput(input) -> error or null
    ​}
  2. 模型决定调用工具

    • 当模型认为需要调用某个工具时,会在回复里发起一个结构化请求, 这一步还没有开始执行工具,只是发起调用请求
    json 复制代码
    {
        "role": "assistant",
        "content": [{
            "type": "text",
            "text": "让我读取这个文件的内容。"
            },{
            "type": "tool_use",
            "id": "toolu_abc123",
            "name": "ReadFile",
            "input": {"path": "/home/user/project/main.py"}
           }
         ]
    }

3.agent执行工具,把结果告诉模型

  • 拿到模型的tool_use请求后,执行对应的操作,比如执行某个命令,把结果作为tool_result发回给模型
swift 复制代码
{
    "role": "user",
    "content": [{
        "type": "tool_result",
        "tool_use_id": "toolu_abc123",  // 和上面发起调用请求的id对应,模型才指定是哪个工具的结果
        "content": "1\tdef main():\n2\t print('hello')\n3\t"
      }]
}

注意: tool_result是user侧发送的请求,因为在对话的角度看,模型只负责思考决策,不负责执行,执行是用户的操作,所以执行结果是用户反馈给模型的

4.模型继续

  • 模型拿到工具结果后做出下一步决策,看是否需要调用下一个工具还是直接给出答案

一个工具的全生命周期

  • 六个内置核心工具
    • ReadFile
    • WriteFile
    • EditFile
    • Bash (bash命令 最强大 最危险)
    • Glob (找文件)
    • Grep (找内容)

mcp工具生命周期

mcp和普通工具都实现一样的Tool接口,包装成普通工具注册到字典,调用和内置工具一个流程;mcp只是对工具集的拓展,调用还是和functionCalling一样

python 复制代码
class Tool(ABC):
    name: str
    description: str
    params_model: type[BaseModel]
    category: ToolCategory = "read"
    is_concurrency_safe: bool = False
    is_system_tool: bool = False
    should_defer: bool = False

    @property
    def is_read_only(self) -> bool:
        return self.category == "read"

    def get_schema(self) -> dict[str, Any]:
        schema = self.params_model.model_json_schema()
        schema.pop("title", None)

        return {
            "name": self.name,
            "description": self.description,
            "input_schema": schema,
        }

    @abstractmethod
    async def execute(self, params: BaseModel) -> ToolResult: ...
相关推荐
Jul1en_1 小时前
【Claude Code Compact】源码级别的学习上下文压缩
java·前端·学习·github·ai编程
windliang2 小时前
Claude Code 源码分析(五):一次 Tool 调用怎样通过权限检查
前端·人工智能·面试
fengci.2 小时前
Microweber CMS 未授权路径穿越漏洞(CVE-2026-65694)
android·开发语言·前端·学习·php
Deryck_德瑞克2 小时前
【Nginx】配置差异分析
服务器·前端·nginx
前端 贾公子2 小时前
第06章:结构化输出 (上)
java·服务器·前端
北斗落凡尘2 小时前
React面试题
前端
一棵白菜2 小时前
mac 部署 n8n
前端
学高数就犯困2 小时前
React:常见的性能优化手段
前端·react.js
天天码行空2 小时前
vkeyboardhand:零依赖虚拟键盘指法组件
前端·javascript·vue.js