​没吃透 Function Calling?难怪你不理解 AI Agent 为何非来不可!

如果说2023属于指尖流淌的提示词,2024 年是检索增强生成(RAG)的舞台,那么 2025 年无疑是 AI Agent 的天下。全球的公司都在摩拳擦掌,探索如何用这些智能代理改变我们的生活和工作。今天,我们就来聊聊 AI Agent 的不同类型,以及如何通过一个叫 Function Calling 的技术,让它们变得更聪明、更实用,并且知道他的局限性,为什么说今后是AI Agent的天下。


一、从大模型到 AI Agent:一场技术进化之旅

想象一下,大语言模型(LLM)就像一个超级聪明的图书管理员,能从海量的知识库里翻出各种信息,写出流畅的文章,甚至跟你聊得热火朝天。但它有个问题:它只会“说”,不会“做”。比如,你问它今天天气怎么样,它可能会凭着训练数据胡乱猜一通,却没法真的去查实时的天气预报。

为了解决这个问题,RAG 技术应运而生。它就像给图书管理员配了个搜索引擎,能从外部资料里捞出最新信息,让回答更靠谱。但即便如此,这种组合还是停留在“知识输出”的层面,缺乏主动性和行动力。

这时候,AI Agent 就像一位全能助手登场了。它不仅能“说”,还能“做”——设定目标、制定计划、与外部系统互动,甚至还能记住你之前说了什么。它不再是被动回答,而是能主动帮你解决问题。这就是 AI Agent 的魅力所在。


二、AI 应用的“三兄弟”:聊天机器人、AI 助手和 AI Agent

要搞清楚 AI Agent 的定位,我们得先认识一下 AI 应用家族的“三兄弟”:

  • 聊天机器人:这是最基础的角色,就像网站上的 FAQ 小助手,能回答一些简单问题,比如“你们营业时间是啥时候?”。有的靠预设脚本,有的借助大模型和 RAG 稍微聪明点,但一遇到复杂任务就露馅了。

  • AI 助手:比聊天机器人高级一些,像 Siri 或者 Alexa,能帮你查天气、设闹钟,甚至控制智能家居。它能听懂你的意图,还能记住一点上下文,但功能还是有限,离不开预设的指令。

  • AI Agent:这是“三兄弟”里最厉害的。它不仅会聊天,还能独立完成任务,比如帮你订机票、查库存,甚至代表你谈判。它有记忆,能规划,能和外部世界互动,简直像个虚拟员工。

举个例栗子:聊天机器人像是超市里的导购员,只能告诉你货架位置;AI 助手像是你的私人秘书,能帮你记事但不会主动出主意;而 AI Agent 更像是业务经理,能自己搞定一整套流程。


三、Function Calling:让 AI “动起来”的秘密武器

说到 AI Agent 的“动手能力”,就不得不提 Function Calling(函数调用)。简单来说,这项技术就像给 AI 配了一套工具箱,让它能调用外部函数,完成具体任务。

​没吃透 Function Calling?难怪你不理解 AI Agent 为何非来不可!

一个真实的案例:智能客服系统

假设你开了一家运动装备网店,用户经常问:“你们家卖什么球?”或者“足球有没有优惠?”。光靠大模型瞎猜可不行,得让 AI 去查库存和促销信息。这时候,Function Calling 就派上用场了。

我们来看看它是怎么实现的:

  1. 准备工具:先写一个函数,比如 query_by_product_name,能根据产品名查数据库,返回库存信息。

  2. 告诉 AI:用 JSON Schema 描述这个函数,告诉 AI 它能干什么、需要什么参数。比如,“输入‘球’,返回所有球类产品”。

  3. 用户提问:用户问:“你们家卖什么球?” AI 收到后,判断需要调用函数。

  4. 执行任务:AI 生成参数(比如 product_name: "球"),调用函数,拿到结果。

  5. 回答用户:AI 把结果整合成自然语言,比如“我们有足球、篮球和网球,你想要哪款?”

通过这个过程,AI 从一个只会聊天的“话痨”,变成了能查数据、干实事的“助手”。以下是一个简化的代码示例,展示如何让 AI 调用函数:

智能客服函数调用示例

import jsonimport requestsimport osfrom openai import OpenAIfrom dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())import sqlite3api_url = os.getenv('GUIJI_API_URL')token = os.getenv('GUIJI_API_KEY')client = OpenAI(    api_key=token, # 从 https://cloud.siliconflow.cn/i/nRDJFg4z 获取    base_url="https://api.siliconflow.cn/v1")def create_and_populate_database():    # 连接到本地数据库文件    conn = sqlite3.connect('SportsEquipment.db')  # 指定文件名来保存数据库    cursor = conn.cursor()    # 检查是否存在名为 'products' 的表,如果不存在则创建    cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='products';")    if cursor.fetchone() is None:        # 创建表        cursor.execute('''        CREATE TABLE products (            product_id TEXT,            product_name TEXT,            description TEXT,            specifications TEXT,            usage TEXT,            brand TEXT,            price REAL,            stock_quantity INTEGER        )        ''')        # 数据列表,用于插入表中        products = [            ('001''足球''高品质职业比赛用球,符合国际标准''圆形,直径22 cm''职业比赛、学校体育课''耐克'12050),            ('002''羽毛球拍''轻量级,适合初中级选手,提供优秀的击球感受''碳纤维材质,重量85 g''业余比赛、家庭娱乐''尤尼克斯'30030),            ('003''篮球''室内外可用,耐磨耐用,适合各种天气条件''皮质,标准7号球''学校、社区运动场''斯伯丁'20040),            ('004''跑步鞋''适合长距离跑步,舒适透气,提供良好的足弓支撑''多种尺码,透气网布''长跑、日常训练''阿迪达斯'50020),            ('005''瑜伽垫''防滑材料,厚度适中,易于携带和清洗''长180cm,宽60cm,厚5mm''瑜伽、普拉提''曼达卡'15025),            ('006''速干运动衫''吸汗快干,适合各种户外运动,持久舒适''S/M/L/XL,多色可选''运动、徒步、旅游''诺斯脸'18060),            ('007''电子计步器''精确计步,带心率监测功能,蓝牙连接手机应用''可充电,续航7天''日常健康管理、运动''Fitbit'25015),            ('008''乒乓球拍套装''包括两只拍子和三个球,适合家庭娱乐和业余训练''标准尺寸,拍面防滑处理''家庭、社区''双鱼'16035),            ('009''健身手套''抗滑耐磨,保护手部,适合各种健身活动''多种尺码,通风设计''健身房、户外运动''Under Armour'12050),            ('010''膝盖护具''减少运动伤害,提供良好的支撑和保护,适合篮球和足球运动''弹性织物,可调节紧度''篮球、足球及其他运动''麦克戴维'22040)        ]        # 插入数据到表中        cursor.executemany('''        INSERT INTO products (product_id, product_name, description, specifications, usage, brand, price, stock_quantity)        VALUES (?, ?, ?, ?, ?, ?, ?, ?)        ''', products)        # 提交更改以确保数据被保存在文件中        conn.commit()    # 检索并打印所有记录以验证插入    cursor.execute('SELECT * FROM products')    all_rows = cursor.fetchall()        conn.close()  # 关闭连接以释放资源    return all_rowsdef query_by_product_name(product_name):    """    根据产品名称查询产品信息。        该函数通过接收一个产品名称作为参数,然后连接到SQLite数据库,    执行SQL查询以查找名称中包含给定字符串的产品,最后返回所有匹配的产品记录。        参数:    product_name (str): 要查询的产品名称。        返回:    list: 匹配的产品记录列表。    """    # 连接 SQLite 数据库    conn = sqlite3.connect('SportsEquipment.db')    cursor = conn.cursor()    # 使用SQL查询按名称查找产品。'%'符号允许部分匹配。    cursor.execute("SELECT * FROM products WHERE product_name LIKE ?", ('%' + product_name + '%',))    # 获取所有查询到的数据    rows = cursor.fetchall()    # 关闭连接    conn.close()      return rows    def read_store_promotions(product_name):    # 指定优惠政策文档的文件路径    file_path = 'store_promotions.txt'        try:        # 打开文件并按行读取内容        with open(file_path, 'r', encoding='utf-8'as file:            promotions_content = file.readlines()                # 搜索包含产品名称的行        filtered_content = [line for line in promotions_content if product_name in line]                # 返回匹配的行,如果没有找到,返回一个默认消息        if filtered_content:            return ''.join(filtered_content)        else:            return "没有找到关于该产品的优惠政策。"    except FileNotFoundError:        # 文件不存在的错误处理        return "优惠政策文档未找到,请检查文件路径是否正确。"    except Exception as e:        # 其他潜在错误的处理        return f"读取优惠政策文档时发生错误: {str(e)}"def sale_function_call_mane_tool_test():    """    测试销售相关函数调用流程的演示函数。        该函数模拟用户与系统的交互过程,支持通过自然语言提问触发预定义函数调用。    实现流程:    1. 维护对话消息历史    2. 定义可调用工具集    3. 循环处理用户输入    4. 调用大模型进行意图识别    5. 处理函数调用请求    6. 生成最终响应        参数:无    返回值:无(直接通过控制台输出交互结果)    """    # 消息上下文存储器,用于维护对话历史记录    messages = []  # 存储对话历史的上下文信息列表    # 预定义工具集合,包含产品查询和促销读取两个核心功能    tools = [        {            "type""function",            "function": {                "name""query_by_product_name",                "description""查询数据库以获取与指定产品名称匹配或包含该名称的产品列表。此功能可用于通过在线平台或客户支持界面帮助客户按名称查找产品或销售的商品。",                "parameters": {                    "type""object",                    "properties": {                        "product_name": {                            "type""string",                            "description""要搜索的产品名称。该搜索不区分大小写,并支持部分匹配。"                        }                    },                    "required": ["product_name"]                }            }        },        {            "type""function",            "function": {                "name""read_store_promotions",                "description""读取门店促销文档以查询与指定产品名称相关的促销活动。本功能通过扫描文本文档,检索所有包含该产品名称的促销条目。",                "parameters": {                    "type""object",                    "properties": {                        "product_name": {                            "type""string",                            "description""要搜索的促销文档中的产品名称。如果找到匹配项,该函数将返回促销详情。"                        }                    },                    "required": ["product_name"]                }            }        }    ]    # 工具名称与实际函数的映射关系,用于动态调用本地实现    available_functions = {"query_by_product_name": query_by_product_name, "read_store_promotions":read_store_promotions}    # 主交互循环,持续处理用户输入直到收到退出指令    while True:        prompt = input('n提出一个问题: ')        if prompt.lower() == "退出":            break  # 如果输入的是"退出",则结束循环                # 将用户提问加入对话上下文        messages.append({'role''user''content': prompt})                # 调用大模型进行意图分析和函数调用决策        completion = client.chat.completions.create(            model="Qwen/Qwen3-32B"            messages=messages,            tools=tools,              parallel_tool_calls=False  # 这里需要格外注意        )                # 解析模型返回的响应内容        response = completion.choices[0].message        tool_calls = completion.choices[0].message.tool_calls                # 处理函数调用逻辑分支        if tool_calls:            # 提取函数调用参数并执行对应的本地函数            function_name = tool_calls[0].function.name            function_args = json.loads(tool_calls[0].function.arguments)                        # 执行实际函数并获取结果            function_response = available_functions[function_name](**function_args)                        # 将函数调用记录和结果加入对话上下文            messages.append(response)              messages.append(                    {                        "role""tool",                        "name": function_name,                        "content"str(function_response),                        "tool_call_id": tool_calls[0].id,                    }                )                          # 二次调用模型生成最终自然语言响应            second_response = client.chat.completions.create(                model="Qwen/Qwen3-32B"                messages=messages,            )              # 获取最终结果            final_response = second_response.choices[0].message.content            messages.append({'role''assistant''content': final_response})            print(final_response)        else:            # 直接输出模型生成的普通响应            print(response.content)            messages.append({'role''assistant''content': response.content})if __name__ == "__main__":      sale_function_call_mane_tool_test()#你家卖篮球吗?现在有什么优惠?
MCP原理与实战 高效AI Agent智能体开发 MCP技术原理与应用实战讲解书籍 AI初学者快速入门书 李艮" data-type="1">

四、单靠 Function Calling,它没法自己规划这个多步流程。

Function Calling 虽然强大,但它只是 AI Agent 拼图中的一块。比如上面的客服系统,依赖于大模型的原生意图识别能力以及单个、多个或并行函数的调用功能。然而,问题也很明显的显现出来了,就是当用户的单次请求中包含多个意图时。

例如,用户询问:“你家卖健身手套吗?现在有什么优惠?”

理想的处理流程应如下:

1. 首先调用一个工具查询数据库后台,确认是否有该商品。如果没有,直接回复用户。

2. 如果商品存在,根据第一个工具的查询结果,再调用第二个工具查询该商品的优惠信息,并计算后回复给用满意度。

但很明显,这种复杂需求仅靠Function Calling是无法实现的,这正是AI Agent应用领域发挥作用之处。真正的 AI Agent 还需要“规划”和“决策”的能力。比如,它得知道先查库存、有货后再查优惠,最后算出实付价格。这种能力往往需要更高级的框架,比如 ReAct(推理与行动),让 AI 像人一样思考和行动。


五、总结

从聊天机器人到 AI 助手,再到 AI Agent,我们见证了 AI 从“会说话”到“会做事”的飞跃。虽然Function Calling 就像一把钥匙,打开了 AI 与现实世界互动的大门。但是最终还是靠真正的 AI Agent ,因为AI Agent还需要“规划”和“决策”的能力。无论是帮网店客服查库存,还是未来帮你规划旅行,AI Agent 正在改变我们的生活。

你有没有想过,AI Agent 还能在哪些地方大显身手?欢迎留言分享你的想法!一起解锁 AI Agent 的更多可能性!

相关文章