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: ...
相关推荐
计算机魔术师4 小时前
管谷歌的不是Pichai一个人,是一整层AI智能体
前端
米米商聊4 小时前
图标能点,按钮就可用了吗?键盘、名称与收藏状态
前端·javascript
Younglina4 小时前
三个晚上,我和 WorkBuddy 做了个生图网站
前端·后端·ai编程
xy34535 小时前
Axure 9.0 内联框架加载方式
前端·ui·html·axure·原型·产品设计
陈随易6 小时前
副业搞钱点子之收入查看器
前端·后端
Profile排查笔记6 小时前
浏览器指纹逆向怎么分析:从网络请求追踪到 JavaScript 采集链
前端·人工智能·后端·自动化
hudie7656 小时前
LikeShop 二开最常改的 5 个文件(附改前改后对比)
前端·uni-app·php·个人开发
qetfw6 小时前
Bash 函数与流程控制:read、if、for、case 验证
linux·前端·javascript·bash
鬼手点金7 小时前
从 API 消息到模型 Token:Chat Template
java·前端·javascript·数据库·人工智能·深度学习·1024程序员节
Shadow(⊙o⊙)7 小时前
LangChain 自定义工具全解析:从 @tool 到 bind_tools 的完整调用链路
java·服务器·前端·1024程序员节