这道题其实是在问,大模型怎么从单纯的文本生成器,升级成一个能调用外部工具的决策中枢。[[Function Calling]]本质上不是让模型去执行函数,而是让模型输出一个结构化的调用意图,包括函数名和参数,真正的执行由外部系统来做。这个边界一定要清楚,模型不负责执行,只负责决策。
和相邻方案比,它的适用场景很明确。如果模型只是需要补充知识,比如回答一个事实性问题,那用[[RAG]]去检索文档库就够。但如果模型需要完成一个动作,比如查天气、订票、操作数据库,那就必须靠Function Calling。[[Agent]]系统里它又是核心,因为Agent需要感知外部世界、执行行动、做复杂规划。但真正落地的时候,往往不是单一方案,比如智能客服,既需要RAG查知识库答复客户,又需要Function Calling去查物流、取消订单,两者配合。
具体说一下工作机制,是个四步闭环。第一步声明阶段,系统向模型注册可用工具,包括函数名、描述、参数Schema。第二步识别阶段,模型分析用户意图,判断需不需要调用工具。第三步生成阶段,如果需要,模型输出一个tool_calls的JSON,里面有调用ID、函数名、参数。第四步执行阶段,外部系统解析这个JSON,执行真实函数,把结果以tool角色回传给模型。举个例子,用户问“北京天气怎么样”,系统注册了get_weather函数,参数是城市。模型识别到需要调用,就输出{"role": "assistant", "tool_calls": [{"id": "call_123", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"北京\"}"}}]}。外部执行后回传{"role": "tool", "tool_call_id": "call_123", "content": "{\"temperature\": 25}"}。模型拿到结果再生成自然语言回复。
真实业务场景,比如智能客服处理订单取消。用户说“帮我查下订单12345的物流,如果明天到不了就取消”。模型需要先调用query_order(12345)获取订单信息,再调用get_logistics(order_id)查物流,得到预计后天到达,于是决定调用cancel_order(12345),最后生成确认话术。这里的关键是链式调用,模型根据前一步的结果决定下一步动作。
落地的时候有几个风险点我必须特别关注。首先是Schema设计,参数描述要清晰,必填可选要明确,不然模型容易[[幻觉]]参数,比如把城市名写成“BeiJing”而不是“北京”。其次是错误处理,工具执行失败时,要把错误信息回传给模型,让它重试或调整策略,不能直接崩掉。还有就是安全隔离,模型只生成调用意图,实际执行要在沙箱环境,防止Prompt注入攻击。如果不满足这些前提,上线后很常见的情况是模型生成错误的参数导致调用失败,或者被用户恶意利用。
还有一个延伸点值得注意,就是并行调用。单次请求可以返回多个tool_calls,比如同时查天气和查新闻,模型会自己判断哪些调用可以并行。这在效率提升上很有价值,但也增加了复杂度,模型可能会生成互相依赖的调用顺序。
所以我会把Function Calling看成模型和外部世界之间的翻译层,它的价值在于让模型的动作意图变得可执行、可验证。我更倾向于设计时把工具粒度做细,参数Schema做严格,同时做好错误回退,这样Agent才能稳定跑起来。