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: ...
相关推荐
一座古城7 小时前
Claude Code 架构源码解析:AI 应用开发的范式跃迁
前端·后端
K哥爬虫7 小时前
【JS 逆向百例】Vaptcha V4 手势验证码逆向分析
前端·后端
用户921080262867 小时前
复盘 AI Coding 工作台的流式链路:从 Sender 输入到 SSE 分流,再到 BubbleList 和右侧预览
前端
了不起的小明7 小时前
SwiftMesh:本地 3D 模型查看器,加密交付 + 转盘录屏一站式搞定,开源免费
前端
默_笙7 小时前
👍 我的代码被 ESLint 抓包了:单引号、var、没分号——全被当场点名
前端·javascript
搞个锤子哟7 小时前
vue项目引入icon的问题
前端
树上有只程序猿7 小时前
当低代码遇上AI,一个开发者的真实感悟
前端
郭邯7 小时前
从零手写一个 UA 解析工具:我用 AI 辅助开发,踩了这些坑
前端
Heo7 小时前
怎么保证缓存和数据库一致性?
前端·后端·面试
摇曳的精灵8 小时前
前端渲染优化
前端·前端渲染优化