这道题问的是工具调用,其实本质就是问大模型怎么跟外界交互。模型本身是静态的,它不知道实时天气、不会查数据库、不能操作API,所以需要一种机制让模型能说“我需要用某个工具”,然后我们把结果喂回去让它继续推理。
实现路径主要有两种。一种是原生支持,像OpenAI、Claude这些模型在训练时就注入了工具调用能力,你只需要按格式传tools参数,它就会输出结构化的调用请求。另一种是提示工程,对通用模型在[[System Prompt]]里把工具描述、输出格式、流程都写清楚,让模型通过[[In-Context Learning]]模拟出来。两者的边界很清晰:原生支持准确率高、输出稳定,适合对可靠性要求高的场景,比如金融交易、自动化客服;提示工程灵活、不依赖特定模型,适合快速原型或模型不固定的情况。但真正落地时,我通常两种一起用,用原生支持的输出格式,但同时在System Prompt里写清楚边界条件和错误处理,相当于双保险。
具体说一下输入输出格式。工具描述一般用JSON Schema,包括名称、描述、参数类型和必填项,比如天气查询工具就需要城市名称和可选日期。模型输出分两种情况:要调用工具时,输出一个包含工具名和参数的结构化对象;不需要就直接返回答案。这个格式设计的关键是结构化输出,必须用[[Function Calling]]或JSON Mode约束解码,否则参数格式乱掉后续没法解析。
调用决策机制有两种。隐式决策是模型自己判断,通过训练内化了“什么时候该调工具”;显式决策是在输出里加一个action字段,比如"action": "call_tool"。我倾向于显式决策,因为可解释性强,调试时能清楚看到模型每一步的意图。
执行流程可以看成简化版的[[ReAct]]:用户输入后模型先决策,如果需要工具就生成调用参数,执行工具后把观察结果拼回上下文,模型再决策,直到不需要调用工具或达到最大迭代次数。举个例子,一个企业客服系统处理退款请求:用户说“我订单号12345,要退款”,模型先调用订单查询工具获取订单状态,发现已发货,再调用退款规则工具判断是否可退,最后生成最终答案。这个循环里有个常见失败场景:工具执行失败或返回空结果,模型可能陷入死循环或胡乱猜测。所以上线前我会特别关注错误处理,把工具返回的错误信息原样喂给模型,让它尝试修正参数重试,同时设置最大迭代次数防止无限循环。
还有一个有意思的点是并行调用,模型可以一次生成多个独立的工具调用,比如同时查天气和航班。这能提升效率,但前提是这些调用之间没有依赖关系,否则需要顺序执行。
所以我会把工具调用看成模型能力的延伸,而不是模型本身的功能。前提是工具描述要足够清晰,参数边界要严格,否则模型会乱调。如果工具描述模糊,比如只说“查询用户信息”但不说明需要什么权限,模型可能生成不合法的参数。更倾向的做法是:先做小范围压测,统计调用准确率和失败重试次数,再逐步开放。