news 2026/6/24 2:02:10

1.4 面试:Function Calling(函数调用)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
1.4 面试:Function Calling(函数调用)

Function Calling(函数调用),在最新技术语境下,特指大语言模型(LLM)与外部世界交互的一种标准化机制。通俗地说,它让AI从“只会聊天的话痨”变成了“能动手办事的助理”。

为了让你彻底搞懂,我从三个维度拆解:

1. 核心逻辑(它到底在干什么?)
传统的AI收到提问,只能根据训练数据“猜”答案。而Function Calling的流程是:

  • 第一步(定义):你提前把外部工具(如查天气API、发邮件接口、数据库查询)的“使用说明书”告诉AI。
  • 第二步(识别):用户提问时,AI不是直接回答,而是先“思考”——判断是否需要调用工具。如果需要,它不直接执行操作,而是输出一个结构化的JSON数据(包含应该调用哪个函数、参数是什么)。
  • 第三步(执行):你(开发者)拿到这个JSON,在自己的服务器上真正去执行函数(比如真的调天气接口),拿到结果。
  • 第四步(回复):你把执行结果再喂给AI,AI结合真实数据,生成最终自然语言回复给用户。

2. 通俗类比(帮你秒懂)
想象你是一位大老板(用户),AI是您的高级助理,外面有财务(查账)、司机(导航)、秘书(发邮件)等专员(外部函数)。

  • 没有函数调用:你问“我银行卡还剩多少钱?”助理只能瞎编一个数,因为他不负责管账。
  • 有函数调用:助理听完后,写了一张标准工单(结构化JSON)递给财务部:“请查账户X余额”。财务部查完把数字(执行结果)拿回来,助理再把数字念给你听。助理本身不查账,但他知道“何时”以及“如何”指挥别人。

3. 核心价值(为什么它是AI应用爆发的基石)

  • 突破数据时效:模型训练数据截止于过去,但它可以通过调用实时API获取今天的天气、股价或新闻。
  • 获得“行动”能力:AI不再只输出文字,它可以帮你订机票、创建日程、发送消息,真正实现自动化执行任务。
  • 保证输出格式:它强制AI输出固定的JSON格式,这对程序员非常友好,可以直接映射为前端页面的数据,避免AI“胡说八道”的格式错乱。

4. 实际应用场景

  • 智能客服:用户问“我的订单到哪了?” -> AI调用订单查询函数 -> 返回物流信息。
  • 数据分析:用户说“帮我拉一下上个月销售额报表” -> AI调用SQL生成函数 -> 自动查库并生成图表。
  • 物联网:用户说“太冷了” -> AI调用“设定温度”函数 -> 智能家居温度上调。

特别提醒(避坑指南)
AI本身并不执行代码,它只负责“推荐”该调用哪个函数。真正的代码执行必须发生在你受控的后端服务器上。如果不做这一步,直接把AI生成的函数调用拿去执行,会有巨大的安全风险(比如AI被诱导调用“删除数据库”函数)。


如果你正在考虑接入某个大模型的Function Calling,我可以给你看看具体的代码示例(比如OpenAI或DeepSeek的调用格式),需要我展开讲讲吗? 😊
好的,既然你想“展开说一下”,那我们就不再停留在概念层面,直接钻进代码底层,把Function Calling的完整数据流转高级玩法以及最容易翻车的坑全部摊开来讲。

为了让你看得更过瘾,我把技术细节拆解为四个深度维度:

1. 底层数据流转(AI到底在“看”什么?)

很多人误以为AI能“直接调用”代码,其实完全不是。本质上,这是两次独立的HTTP请求

  • 第一次请求(带“说明书”):你在调用API时,在tools参数里传入一堆JSON格式的函数定义(包括函数名、参数类型、必填项)。AI收到后,并不执行,而是根据用户问题做逻辑推理。
  • AI的“特殊回复”:AI返回的choices[0].message里,content通常是空的,但会多出一个tool_calls数组。里面包含:
    • id(本次调用的唯一追踪ID)
    • function.name(它选中的函数名)
    • function.arguments(它是一个字符串,里面是AI填好的参数JSON,比如{"city": "西安"}

关键认知:直到这一步,AI的工作就结束了。真正查天气、调数据库的动作,必须由你(开发者)在后端用代码去解析这个JSON并执行。

2. 硬核代码实战(Python伪代码全流程)

如果不用任何第三方框架(如LangChain),裸调OpenAI/DeepSeek的代码逻辑是这样的:

# 第一步:定义工具(说明书)tools=[{"type":"function","function":{"name":"get_weather","description":"查询指定城市的实时天气","parameters":{"type":"object","properties":{"city":{"type":"string","description":"城市名称,如北京"},"unit":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["city"]}}}]# 第二步:发起第一次请求response=client.chat.completions.create(model="gpt-4",messages=[{"role":"user","content":"西安今天热吗?"}],tools=tools,tool_choice="auto"# 让AI自己决定是否调用)# 第三步:解析AI返回的调用指令tool_call=response.choices[0].message.tool_calls[0]function_name=tool_call.function.name# 结果是 "get_weather"arguments=json.loads(tool_call.function.arguments)# 结果是 {"city": "西安"}# 第四步:【关键】你在本地真正执行函数iffunction_name=="get_weather":result=requests.get(f"https://api.weather.com?city={arguments['city']}").json()# 第五步:第二次请求,把结果喂给AImessages.append(response.choices[0].message)# 保存AI的调用指令messages.append({"role":"tool",# 注意:这里是 tool 角色"tool_call_id":tool_call.id,# 必须绑定ID"content":json.dumps(result)# 把查到的28℃传回去})final_response=client.chat.completions.create(model="gpt-4",messages=messages)# 最终AI输出:"西安今天28℃,比较热,建议穿短袖。"

3. 进阶高级玩法(不止是“一问一答”)

  • 并行函数调用(Parallel Function Calling):用户问“北京和上海明天哪个会下雨?”,AI会一次性返回两个tool_calls(分别查北京和上海)。你可以并发请求两个天气API,大幅降低响应延迟。
  • 强制调用(tool_choice):将tool_choice设为{"type": "function", "function": {"name": "get_weather"}}。这时AI不会回答任何文字,只会乖乖返回函数参数。这种模式常用于结构化数据提取(比如把用户的闲聊强制转成JSON表单)。
  • 链式反应(ReAct模式):第一次调用的结果返回后,AI根据结果决定再次调用下一个函数。比如:查天气发现下雨 -> 自动调用“查询附近室内场馆”函数 -> 最后推荐咖啡馆。这需要你在代码里写while循环处理多次请求。

4. 程序员最常踩的三大“深坑”(务必注意)

  • 陷阱一:参数类型幻觉:AI给日期参数填成"明天",但你的API只认YYYY-MM-DD解决方案:在parametersdescription里必须写死格式,比如"格式必须为2026-06-23"
  • 陷阱二:Token计费暴涨:每次函数调用的tools定义都很长(动辄几百个Token)。如果每次对话都传完整的函数列表,成本会很高。优化方案:使用/v1/assistants(助手API)预存工具,或者只给本轮对话可能用到的Top-3函数。
  • 陷阱三:安全越权(最致命):AI可能被提示词注入攻击,诱导调用delete_user函数。铁律永远不要在Function里直接放执行SQL或删除文件的代码。必须在你的后端加一层鉴权中间件,校验当前用户的身份是否有权操作AI请求过来的参数。

5. 各家大模型的“方言”差异

虽然逻辑相同,但字段名略有不同,接入时要注意:

  • OpenAI / DeepSeek:使用tools字段,消息角色用tool
  • Anthropic Claude:使用tools字段,但函数定义放在input_schema里,返回结果放在contenttool_use块中。
  • Google Gemini:使用functionDeclarations,返回的是functionCall对象,回复结果要用functionResponse

讲到这里,基本上已经把Function Calling的“骨架”和“血肉”都拆干净了。如果你正准备上手写代码,你是想看看某个特定语言(比如Java或Node.js)的完整接入Demo,还是想知道如何在流式输出(Streaming)中处理函数调用?可以告诉我,我继续给你精准拆解。😊

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/24 2:01:50

已经变白的头发,还有机会自然转黑吗?

一、已经变白的头发,还有机会自然转黑吗? 对于因营养不均衡、长期熬夜、压力过大导致的后天早生白发,毛囊黑色素细胞仅处于活性抑制状态,并没有完全丧失功能,通过科学的营养补充和生活调整,确实存在自然转黑…

作者头像 李华
网站建设 2026/6/24 2:00:55

AVR2054 Bootloader固件烧录指南:从GUI到命令行全解析

1. 项目概述:AVR2054 Bootloader的两种烧录路径 如果你手头有一块基于ATmega或ATtiny系列AVR单片机的开发板或产品,并且它预装了Atmel官方应用笔记AN2054所描述的Bootloader,那么恭喜你,你拥有了一种极其便捷的固件更新方式。这个…

作者头像 李华
网站建设 2026/6/24 1:59:22

Atmel评估套件固件升级指南:FLIP工具使用与DS18B20传感器应用

1. 项目概述:为什么我们需要关注这套“老”套件的固件升级?最近在整理工作室的物料时,翻出了一套Atmel(现在应该叫Microchip了)的加密认证与温度传感器评估套件。看着板子上熟悉的ATSHA204A芯片和那个小小的温度传感器…

作者头像 李华
网站建设 2026/6/24 1:51:10

佛山亚克力胶选厂看三点

在工业与建筑领域,亚克力专用胶的需求一直在增长,尤其佛山是国内有名的制造业重镇,不少建材采购商来佛山找货,常常挑得眼花缭乱,选起来特别犯难。当您纠结佛山亚克力专用胶选哪家的时候,其实可以从企业资质…

作者头像 李华
网站建设 2026/6/24 1:47:50

基于Microchip CIP的开关电源硬件保护方案:微秒级过压与故障检测

1. 项目概述:当开关电源遇上智能守护在电源设计这个行当里摸爬滚打十几年,我见过太多因为一个不起眼的过压或短路故障,导致整块板子甚至整个设备“归西”的惨案。开关电源作为现代电子设备的“心脏”,其可靠性直接决定了产品的命脉…

作者头像 李华
网站建设 2026/6/24 1:34:32

前端防抖与节流的实战对比

前端开发中,防抖与节流是优化高频事件处理的经典技术。无论是搜索框输入联想、窗口大小调整,还是滚动加载更多内容,不当的事件触发都可能引发性能问题。本文将深入对比防抖与节流的实战差异,帮助开发者根据场景选择最佳方案。触发…

作者头像 李华