🚀 AI Agent 核心技能:Function Calling (函数调用) 基础与面试通关指南

在 AI Agent(智能体)的开发中,如果你只让大模型陪你聊天,那它只是一个“聪明的复读机”。但如果你想让大模型帮你查实时天气、订机票、查数据库、甚至操控智能家居,你就必须掌握一项核心技能:Function Calling(函数调用)

这篇文章将用最通俗的大白话,带你彻底搞懂 Function Calling 的底层原理、面试高频踩坑点,并附上一段极其详细的保姆级实战代码,直接帮你拿下大厂 Agent 岗位的基本盘!


💡 一、 什么是 Function Calling?(大白话秒懂)

通俗概念
大模型(LLM)就像是一个被关在小黑屋里的“绝顶聪明的军师”,它上知天文下知地理,但唯独没有手,也连不上网

  • 当你问它“唐朝的建立者是谁?”它靠脑子里的记忆就能回答你。
  • 但当你问它“北京今天多少度?”或者“帮我把数据库里张三的工资改一下”,它就懵了,因为这需要连接外部世界。

Function Calling 就是给大模型递工具!
你提前把一些工具(比如:查天气的函数、操作数据库的函数)的说明书写好,连同问题一起扔给大模型。大模型看完说明书后,如果觉得需要用工具,它就会严格按照说明书的格式,输出一段参数(比如:{"location": "Beijing"})。然后你拿到参数,帮它执行,再把结果告诉它。


⚙️ 二、 Function Calling 的完整工作流(面试必背 5 步)

面试官极大概率会让你在白板上画出(或口述)Function Calling 的执行流程。请务必牢记这标准的 5 步闭环:

  1. 告知工具(Schema 定义):开发者定义好本地函数的说明(包含函数名、功能描述、需要传入什么参数),发给大模型。
  2. 大模型决策与参数提取:大模型根据用户的提问,判断“需不需要调用函数?”。如果需要,它会提取用户话语中的关键信息,拼装成标准的 JSON 参数返回给你。
  3. 本地执行(最关键的认知):大模型绝对不会自己去跑代码!它只是把参数给你,由你本地的 Python/Java 后端去执行真实的函数代码。
  4. 回传结果:你把本地函数执行完得到的结果(比如天气是 25 度),作为“工具的反馈”,再次发给大模型。
  5. 生成最终回答:大模型结合刚才收到的工具结果,用人类听得懂的自然语言生成最终回答(“北京今天天气晴朗,气温 25 度~”)。

🎯 三、 高频面试 Q&A 实战演练

Q1:大模型是怎么“执行”本地函数的?它有运行环境吗?

标准答案(防坑题)
大模型根本没有执行代码!大模型的本质只是一个文本生成器。它做的仅仅是根据你提供的 JSON Schema(函数说明书),做了一次意图识别和参数提取,然后把参数用 JSON 格式输出给我们。真实的执行动作完全是由我们自己的业务服务器(后端代码)完成的。

Q2:在 Prompt 里直接让大模型输出 JSON 也能提取参数,为什么要专门搞一个 Function Calling 功能?

标准答案

  1. 准确性更高:传统的 Prompt 工程让大模型输出 JSON 极不稳定,容易漏掉括号或者加一些废话(比如“好的,这是你的 JSON…”)。而支持 Function Calling 的模型是在预训练/微调阶段专门针对结构化输出训练过的,JSON 格式极其稳定且遵循 Schema
  2. 更完善的 API 交互:各大厂商(如 OpenAI)在 API 层面原生提供了 toolstool_calls 字段,使得工具交互的逻辑更加清晰,无需用晦涩的正则去解析文本。

Q3:如果用户的问题需要调用多个函数怎么办?

标准答案
现代的大模型(如 GPT-4)支持并行函数调用(Parallel Function Calling)。比如用户问“北京和上海今天的天气怎么样?”,模型会在一次响应中,同时返回两个函数调用的指令及参数,我们可以用并发编程在本地同时执行,然后再把两个结果一起传给模型。


在这里插入图片描述

💻 四、 面试加分代码:手写一个查天气的 Function Calling

在面试中,能写出这段基于 OpenAI 官方风格的代码架构,并能说清楚里面的每一步注释,你的工程能力就稳了!

# 运行前需安装: pip install openai
import json
import openai

# 假设你已经配置好了 API KEY
client = openai.OpenAI(api_key="sk-xxxx")

# ==========================================
# 1. 定义本地真实执行的函数 (业务逻辑)
# ==========================================
def get_current_weather(location: str) -> str:
    """
    这是一个模拟的本地天气查询函数。
    真实场景下,这里应该发起一个 HTTP 请求去调用中国气象局或心知天气的 API。
    """
    print(f"🔧 [本地执行中] 正在查询 {location} 的天气...")
    # 假装我们去数据库查了
    weather_info = {
        "location": location,
        "temperature": "26",
        "condition": "晴朗"
    }
    # 工具的返回结果通常需要转成字符串发给大模型
    return json.dumps(weather_info)

# ==========================================
# 2. 定义函数的“说明书” (Schema)
# 这一步极其重要:大模型就是看这段描述来明白工具是干嘛的!
# ==========================================
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "获取指定城市的当前实时天气信息。",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,例如:北京、上海、广州",
                    }
                },
                "required": ["location"], # 声明 location 是必填参数
            },
        }
    }
]

# ==========================================
# 3. 核心执行流演示

# ==========================================
def run_conversation(user_message: str):
    # 第一步:把用户的问题,连同工具说明书一起发给大模型
    messages = [{"role": "user", "content": user_message}]
    
    print("🤖 [大模型思考中] 正在判断是否需要调用工具...")
    response = client.chat.completions.create(
        model="gpt-4o-mini", # 支持函数调用的模型
        messages=messages,
        tools=tools,         # 把我们准备好的工具箱塞进去
        tool_choice="auto"   # 让模型自己决定用不用工具
    )
    
    response_message = response.choices[0].message
    
    # 检查大模型是不是决定调用工具了?
    if response_message.tool_calls:
        # 把大模型的这一次回复(包含要求调用工具的指令)先加到历史记录里
        messages.append(response_message)
        
        # 遍历大模型要求调用的所有工具 (支持一次调用多个)
        for tool_call in response_message.tool_calls:
            # 拿到大模型想调用的函数名
            function_name = tool_call.function.name
            
            # 解析大模型替我们提取出来的参数 (JSON 字符串转 Python 字典)
            function_args = json.loads(tool_call.function.arguments)
            
            # 第二步:在我们本地真实执行这个函数!
            if function_name == "get_current_weather":
                # 提取 location 参数并执行
                function_response = get_current_weather(
                    location=function_args.get("location")
                )
                
                # 第三步:把本地执行出来的真实结果,打包成 tool 角色,回传给大模型
                messages.append(
                    {
                        "tool_call_id": tool_call.id,
                        "role": "tool",
                        "name": function_name,
                        "content": function_response,
                    }
                )
        
        # 第四步:模型拿到真实天气数据后,生成给用户的最终回答
        print("🤖 [大模型总结中] 拿到了工具数据,正在组织语言...")
        second_response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages
        )
        return second_response.choices[0].message.content
    else:
        # 如果模型认为不需要调工具(比如你问的是“你好”),就直接返回文本
        return response_message.content

# ==========================================
# 测试运行
# ==========================================
if __name__ == "__main__":
    user_query = "请问北京今天天气怎么样?"
    print(f"👤 用户:{user_query}")
    final_answer = run_conversation(user_query)
    print(f"💡 最终回答:\n{final_answer}")
Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐