1. 标题 (Title)

  • 从函数调用到自动化执行:解锁AI Agent的“工具使用”超能力
  • 揭秘AI Agent Tool Use:让大模型从“能说”到“会做”的完整路径
  • AI Agent实战指南:从理解Function Calling到构建自动化任务执行系统
  • 告别“纸上谈兵”:如何让AI Agent通过Tool Use实现真实世界的自动化?

2. 引言 (Introduction)

2.1 痛点引入 (Hook)

你是否有过这样的经历:当你问GPT-4“今天北京的天气怎么样?”,它会遗憾地告诉你“我无法获取实时数据”;当你让它“帮我把这份Excel里的销售数据做成图表并发送给同事”,它只能给你一段Python代码示例,却无法直接帮你完成操作。

早期的大语言模型(LLM)就像一位“知识渊博但手脚受限”的顾问——它们能回答问题、编写代码、生成文案,但一旦涉及获取实时信息操作外部系统执行多步骤任务,就会显得力不从心。

这一切的转折点,就是AI Agent的Tool Use(工具使用)能力

2.2 文章内容概述 (What)

本文将带你从0到1揭秘AI Agent的Tool Use能力:

  • 我们会从最基础的**Function Calling(函数调用)**讲起,理解它是如何让LLM“学会”使用外部工具的;
  • 接着,我们会探讨如何从单次函数调用进化到多工具、自动化的任务执行
  • 我们会用真实的代码示例(基于Python和OpenAI API),带你构建一个能获取天气、查询数据库、发送邮件的简单AI Agent;
  • 最后,我们会聊聊Tool Use的最佳实践、安全挑战,以及行业未来的发展趋势。

2.3 读者收益 (Why)

读完本文,你将:

  • 彻底理解AI Agent Tool Use的核心原理,不再被“Agent”、“Function Calling”这些概念迷惑;
  • 能够独立编写代码,让LLM调用你定义的外部函数或API;
  • 掌握构建简单自动化AI Agent的方法,能解决“获取实时数据”、“多步骤任务执行”等实际问题;
  • 了解Tool Use的边界和安全注意事项,避免踩坑。

3. 准备工作 (Prerequisites)

在开始之前,你需要具备以下基础:

3.1 技术栈/知识

  • 基础Python编程能力:了解函数、变量、API调用等基本概念;
  • 对大语言模型(LLM)的基本认知:知道GPT-4、Claude等模型的作用,了解Prompt Engineering的基本思路;
  • 基础API概念:理解什么是REST API,如何发送HTTP请求。

3.2 环境/工具

  • Python 3.8+:建议使用最新的稳定版本;
  • OpenAI API Key:因为本文会使用OpenAI的Function Calling功能(当然,你也可以替换为Claude、Llama等支持Tool Use的模型);
  • 必要的Python库:我们会用到openairequests等库,后续会有安装步骤。

4. 核心内容:手把手实战 (Step-by-Step Tutorial)


步骤一:概念扫盲——什么是AI Agent?什么是Tool Use?

在开始写代码之前,我们必须先把核心概念搞清楚。这是后续所有实战的基础。

4.1.1 核心概念:AI Agent

简单来说,AI Agent是一个能感知环境、做出决策并执行动作的“智能体”

如果把LLM比作Agent的“大脑”,那么:

  • 感知(Perception):Agent获取信息的方式(比如读取用户输入、获取API返回结果、读取文件);
  • 决策(Decision-Making):Agent根据感知到的信息,决定下一步做什么(这部分通常由LLM完成);
  • 动作(Action):Agent执行决策的方式——而Tool Use,就是Agent最重要的动作能力之一

一个经典的AI Agent工作流程是这样的:

用户输入 → Agent感知 → LLM决策(是否需要用工具?用哪个工具?) → 执行工具 → 获取工具结果 → LLM总结结果 → 返回给用户

4.1.2 核心概念:Tool Use(工具使用)

Tool Use是指AI Agent根据任务需求,自主选择并调用外部工具(如API、函数、数据库、搜索引擎等)来完成任务的能力

为什么Tool Use如此重要?因为它解决了LLM的三大核心痛点:

  1. 知识截止日期限制:LLM的训练数据是有截止日期的,Tool Use让它能获取实时信息(如天气、新闻);
  2. 缺乏执行能力:LLM只能生成文本,Tool Use让它能操作外部系统(如发送邮件、修改文件);
  3. 专业知识不足:对于特定领域的任务(如复杂数学计算、化学分子分析),LLM可以调用专业工具来解决。

4.1.3 概念结构与核心要素组成

我们可以把AI Agent的Tool Use系统拆解为以下几个核心要素:

核心要素 定义 作用
工具库(Tool Registry) 存储Agent可用工具的集合 告诉Agent“你可以用哪些工具”
工具描述(Tool Description) 对工具功能、参数、返回值的自然语言/结构化描述 帮助LLM理解“这个工具是做什么的,怎么用”
意图识别(Intent Recognition) LLM分析用户需求,判断是否需要使用工具 决定“什么时候用工具”
工具选择(Tool Selection) LLM从工具库中选择合适的工具 决定“用哪个工具”
参数生成(Parameter Generation) LLM根据用户需求生成工具所需的参数 决定“怎么用这个工具”
工具执行(Tool Execution) 实际调用工具的代码逻辑 执行工具,获取结果
结果整合(Result Integration) LLM将工具返回的结果整合为自然语言回答 把工具结果转化为用户能理解的内容

4.1.4 概念之间的关系:交互关系图

为了更直观地理解这些要素的关系,我们来看一个mermaid交互关系图:

不需要工具

需要工具

提供工具信息

提供可执行工具

用户输入

意图识别/LLM决策

直接生成回答

工具选择

参数生成

工具执行
(从工具库调用)

工具返回结果

结果整合/LLM总结

返回给用户

工具库


步骤二:从0到1理解Function Calling——Tool Use的基础

现在我们知道了Tool Use的重要性,那么它是如何实现的呢?Function Calling(函数调用)是目前LLM实现Tool Use的最主流方式

4.2.1 问题背景:LLM本来只会“生成文本”,怎么调用函数?

早期的LLM只能生成文本。如果想让它调用函数,我们只能用“Prompt Engineering”的方式:

请你判断用户的问题是否需要获取天气。如果需要,请生成如下格式的JSON:{“tool”: “get_weather”, “params”: {“city”: “北京”}}。我会根据这个JSON调用工具,然后把结果给你。

这种方式有两个大问题:

  1. 不稳定:LLM经常生成不符合格式的JSON,或者忘记生成JSON;
  2. 开发成本高:你需要写很多Prompt来约束LLM的输出,还要自己解析输出、处理错误。

为了解决这个问题,OpenAI在2023年6月推出了Function Calling功能——它本质上是把“生成工具调用JSON”这个过程,封装成了模型的一个原生能力。

4.2.2 核心概念:Function Calling

Function Calling是指LLM在接收到用户输入后,根据你提供的“函数定义”,自动生成一个结构化的函数调用请求(通常是JSON格式),而不是直接返回自然语言回答

注意:LLM本身不会执行函数——它只是“决定调用哪个函数、生成什么参数”。真正执行函数的,是你写的代码。

4.2.3 Function Calling的工作流程

我们用一个mermaid流程图来描述Function Calling的完整流程:

开始

定义函数
并告诉LLM

发送用户输入+函数定义
给LLM

LLM判断
是否需要调用函数?

直接返回自然语言回答
结束

返回函数调用请求
(JSON格式)

你的代码解析JSON
执行对应的函数

获取函数执行结果

将结果作为新消息
再次发送给LLM

LLM根据结果
生成自然语言回答

结束

4.2.4 实战:写一个支持Function Calling的天气查询助手

光说不练假把式。我们现在就用OpenAI API,写一个能查询天气的简单程序——这是理解Function Calling的最佳方式。

4.2.4.1 环境准备

首先,安装必要的库:

pip install openai requests python-dotenv

然后,在项目根目录创建一个.env文件,填入你的OpenAI API Key:

OPENAI_API_KEY=你的_api_key_在这里
4.2.4.2 定义我们的“工具函数”

我们先写一个模拟的天气查询函数(你也可以替换成真实的天气API,比如OpenWeatherMap):

# 模拟天气查询函数
def get_current_weather(city: str, unit: str = "摄氏度") -> str:
    """
    获取指定城市的当前天气
    :param city: 城市名称,例如"北京"、"上海"
    :param unit: 温度单位,"摄氏度"或"华氏度"
    :return: 天气信息字符串
    """
    # 这里模拟真实API的返回结果
    weather_data = {
        "北京": {"temperature": 22, "condition": "晴", "humidity": 45},
        "上海": {"temperature": 26, "condition": "多云", "humidity": 60},
        "深圳": {"temperature": 28, "condition": "小雨", "humidity": 75}
    }
    
    if city not in weather_data:
        return f"抱歉,我找不到城市 {city} 的天气信息。"
    
    data = weather_data[city]
    temp = data["temperature"]
    if unit == "华氏度":
        temp = round(temp * 9/5 + 32, 1)
    
    return f"{city}当前天气:{data['condition']},温度{temp}{unit},湿度{data['humidity']}%。"
4.2.4.3 告诉LLM:这个函数怎么用?

接下来,我们需要把函数的信息“告诉”LLM。OpenAI要求我们用一个JSON格式的tools数组来描述函数:

tools = [
    {
        "type": "function",  # 目前只支持"function"类型
        "function": {
            "name": "get_current_weather",  # 函数名,必须和我们定义的函数名一致
            "description": "获取指定城市的当前天气信息,支持查询温度、天气状况和湿度",  # 函数功能描述,帮助LLM理解什么时候用这个函数
            "parameters": {  # 函数参数的详细定义
                "type": "object",
                "properties": {
                    "city": {  # 参数名
                        "type": "string",
                        "description": "城市名称,例如'北京'、'上海'、'深圳'",  # 参数描述
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["摄氏度", "华氏度"],  # 参数的可选值,LLM只能从中选
                        "description": "温度单位,默认为摄氏度",
                    },
                },
                "required": ["city"],  # 必须传入的参数
            },
        }
    }
]

这里的description非常关键——它是LLM理解函数的唯一依据。描述得越清晰、越具体,LLM就越能正确地使用函数。

4.2.4.4 完整的Function Calling代码

现在,我们把所有部分整合起来:

import os
import json
from dotenv import load_dotenv
from openai import OpenAI

# 加载环境变量
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

# ----------------------
# 1. 定义工具函数
# ----------------------
def get_current_weather(city: str, unit: str = "摄氏度") -> str:
    """获取指定城市的当前天气"""
    weather_data = {
        "北京": {"temperature": 22, "condition": "晴", "humidity": 45},
        "上海": {"temperature": 26, "condition": "多云", "humidity": 60},
        "深圳": {"temperature": 28, "condition": "小雨", "humidity": 75}
    }
    if city not in weather_data:
        return f"抱歉,找不到城市 {city} 的天气信息。"
    data = weather_data[city]
    temp = data["temperature"] if unit == "摄氏度" else round(data["temperature"] * 9/5 + 32, 1)
    return f"{city}当前天气:{data['condition']},温度{temp}{unit},湿度{data['humidity']}%。"

# ----------------------
# 2. 定义工具描述
# ----------------------
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "获取指定城市的当前天气信息,支持温度、天气状况和湿度查询",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称,如'北京'、'上海'"},
                    "unit": {"type": "string", "enum": ["摄氏度", "华氏度"], "description": "温度单位"}
                },
                "required": ["city"]
            }
        }
    }
]

# ----------------------
# 3. 定义Function Calling执行逻辑
# ----------------------
def run_conversation(user_input: str):
    # 初始化消息列表
    messages = [{"role": "user", "content": user_input}]
    
    # 第一次调用LLM:判断是否需要调用工具
    response = client.chat.completions.create(
        model="gpt-4o-mini",  # 建议使用支持Function Calling的模型,如gpt-4o, gpt-4o-mini, gpt-3.5-turbo
        messages=messages,
        tools=tools,
        tool_choice="auto"  # 让LLM自动决定是否调用工具
    )
    
    response_message = response.choices[0].message
    tool_calls = response_message.tool_calls
    
    # 如果LLM决定调用工具
    if tool_calls:
        # 把LLM的回复加入消息列表
        messages.append(response_message)
        
        # 遍历所有工具调用(虽然通常只有一个)
        for tool_call in tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)
            
            # 根据函数名调用对应的函数
            if function_name == "get_current_weather":
                function_response = get_current_weather(
                    city=function_args.get("city"),
                    unit=function_args.get("unit")
                )
            
            # 把工具执行结果加入消息列表
            messages.append({
                "tool_call_id": tool_call.id,
                "role": "tool",
                "name": function_name,
                "content": function_response
            })
        
        # 第二次调用LLM:让它根据工具结果生成回答
        second_response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages
        )
        return second_response.choices[0].message.content
    
    # 如果不需要调用工具,直接返回LLM的回答
    else:
        return response_message.content

# ----------------------
# 4. 测试一下
# ----------------------
if __name__ == "__main__":
    print("AI助手:你好!我可以帮你查询天气。")
    while True:
        user_input = input("你:")
        if user_input.lower() in ["退出", "quit", "exit"]:
            print("AI助手:再见!")
            break
        response = run_conversation(user_input)
        print(f"AI助手:{response}\n")
4.2.4.5 运行结果

当你运行这段代码,输入“今天北京天气怎么样?”时,程序会发生以下事情:

  1. LLM收到输入,判断需要调用get_current_weather函数;
  2. LLM生成参数{"city": "北京"}
  3. 你的代码调用get_current_weather("北京"),得到模拟的天气结果;
  4. 结果被发送回LLM;
  5. LLM把结果整理成自然语言:“北京当前天气晴朗,温度22摄氏度,湿度45%,非常适合外出散步哦!”

如果你输入“你叫什么名字?”,LLM会判断不需要调用工具,直接回答:“我是你的AI天气助手,你可以叫我小天!”


步骤三:从单次Function Calling到多工具自动化——构建真正的AI Agent

刚才我们实现的是“单次函数调用”——但真正的AI Agent,应该能自主决定使用多个工具、按顺序执行多步骤任务

比如,用户说:“帮我查一下深圳今天的天气,然后给我的同事张三发一封邮件,告诉他天气情况,让他注意带伞。”

这个任务需要两个工具:get_current_weathersend_email,而且必须按顺序执行(先查天气,再发邮件)。

4.3.1 核心概念:多步骤推理与ReAct框架

要实现多步骤自动化,我们需要一个Agent的推理框架。目前最经典的是ReAct(Reasoning + Acting)框架

ReAct的核心思想是:让Agent在每一步都先思考(Reason),再行动(Act),然后观察结果(Observation),循环这个过程直到任务完成。

ReAct的Prompt模板通常长这样:

你是一个能干的AI助手。你可以使用以下工具:[工具列表]
请按照以下格式执行任务:

  1. Thought: 思考下一步需要做什么
  2. Action: 选择要使用的工具和参数
  3. Observation: 工具执行的结果
    …(重复直到任务完成)
  4. Final Answer: 最终的回答

不过好消息是,现在有很多框架(比如LangChain、AutoGPT、CrewAI)已经帮我们封装好了ReAct逻辑,我们不需要手动写这么复杂的Prompt。

4.3.2 实战:用LangChain构建一个多工具AI Agent

LangChain是目前最流行的AI Agent开发框架之一。我们现在用LangChain,把刚才的天气助手升级成一个能查天气、发邮件的多工具Agent。

4.3.2.1 安装LangChain
pip install langchain langchain-openai langchainhub
4.3.2.2 定义多个工具

我们先定义两个工具:get_current_weather(和之前一样)和send_email(模拟发送邮件)。

在LangChain中,我们可以用@tool装饰器来定义工具:

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import tool, AgentExecutor, create_openai_functions_agent
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage

# 加载环境变量
load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

# ----------------------
# 1. 定义工具(用@tool装饰器)
# ----------------------
@tool
def get_current_weather(city: str, unit: str = "摄氏度") -> str:
    """获取指定城市的当前天气信息,支持温度、天气状况和湿度查询。"""
    weather_data = {
        "北京": {"temperature": 22, "condition": "晴", "humidity": 45},
        "上海": {"temperature": 26, "condition": "多云", "humidity": 60},
        "深圳": {"temperature": 28, "condition": "小雨", "humidity": 75}
    }
    if city not in weather_data:
        return f"抱歉,找不到城市 {city} 的天气信息。"
    data = weather_data[city]
    temp = data["temperature"] if unit == "摄氏度" else round(data["temperature"] * 9/5 + 32, 1)
    return f"{city}当前天气:{data['condition']},温度{temp}{unit},湿度{data['humidity']}%。"

@tool
def send_email(to: str, subject: str, content: str) -> str:
    """
    给指定收件人发送邮件。
    :param to: 收件人姓名,例如"张三"、"李四"
    :param subject: 邮件主题
    :param content: 邮件正文内容
    :return: 发送结果
    """
    # 这里模拟发送邮件的过程
    print(f"\n[模拟发送邮件] 给 {to} 发送邮件:")
    print(f"主题:{subject}")
    print(f"内容:{content}\n")
    return f"邮件已成功发送给 {to}!"
4.3.2.3 创建LangChain Agent

接下来,我们创建Agent:

# ----------------------
# 2. 初始化LLM和工具列表
# ----------------------
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)  # temperature设为0,让Agent更稳定
tools = [get_current_weather, send_email]

# ----------------------
# 3. 创建Agent的Prompt模板
# ----------------------
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个能干的AI助手。你可以使用提供的工具来帮助用户完成任务。"),
    MessagesPlaceholder(variable_name="chat_history"),  # 用于存储对话历史
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")  # Agent的“思考草稿本”
])

# ----------------------
# 4. 创建Agent和AgentExecutor
# ----------------------
# 创建OpenAI Functions Agent(基于OpenAI的Function Calling)
agent = create_openai_functions_agent(llm, tools, prompt)

# AgentExecutor负责执行Agent的思考-行动循环
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)  # verbose=True会打印详细的执行过程
4.3.2.4 运行多工具Agent

现在,我们来测试这个Agent:

# ----------------------
# 5. 测试Agent
# ----------------------
if __name__ == "__main__":
    chat_history = []  # 用于存储对话历史
    
    print("AI助手:你好!我可以帮你查询天气和发送邮件。")
    while True:
        user_input = input("你:")
        if user_input.lower() in ["退出", "quit", "exit"]:
            print("AI助手:再见!")
            break
        
        # 调用Agent
        result = agent_executor.invoke({
            "input": user_input,
            "chat_history": chat_history
        })
        
        # 更新对话历史
        chat_history.append(HumanMessage(content=user_input))
        chat_history.append(AIMessage(content=result["output"]))
        
        print(f"\nAI助手:{result['output']}\n")
4.3.2.5 见证奇迹的时刻

现在,你输入:“帮我查一下深圳今天的天气,然后给张三发一封邮件,告诉他天气情况,提醒他带伞。”

你会看到LangChain打印出详细的执行过程:

  1. Thought:Agent思考“我需要先查深圳的天气,然后用天气信息写邮件发给张三”;
  2. Action 1:调用get_current_weather(city="深圳")
  3. Observation 1:获取到深圳的天气“小雨,28摄氏度”;
  4. Thought:Agent思考“现在我有了天气信息,可以发邮件了”;
  5. Action 2:调用send_email(to="张三", subject="深圳天气提醒", content="深圳今天有小雨,温度28摄氏度,记得带伞!")
  6. Observation 2:邮件发送成功;
  7. Final Answer:Agent总结“我已经帮你查了深圳的天气,并给张三发了提醒邮件!”

这就是真正的AI Agent——它不需要你告诉它“第一步做什么,第二步做什么”,它会自主推理、自主选择工具、自主执行多步骤任务!


步骤四:Tool Use的自定义与美化——让Agent更“好用”

现在我们已经能构建一个基础的Agent了,但要让它在实际项目中好用,我们还需要做一些自定义和优化。

4.4.1 最佳实践1:写好工具的Description

我们之前提到过,工具的description是LLM理解工具的唯一依据。一个好的Description应该包含:

  1. 工具的功能:这个工具是做什么的?
  2. 什么时候用这个工具:在什么场景下应该调用它?
  3. 什么时候不用这个工具:在什么场景下不应该调用它?

反例(不好的Description):

"description": "获取天气"

正例(好的Description):

"description": "获取指定城市的实时天气信息(包括温度、天气状况、湿度)。当用户询问天气、或需要根据天气做决策时使用此工具。注意:此工具只能查询预设的几个城市(北京、上海、深圳),如果用户查询其他城市,不要使用此工具,直接告诉用户无法查询。"

4.4.2 最佳实践2:定义清晰的参数Schema

参数的schema(也就是parameters部分)也非常重要。你应该:

  1. 明确指定每个参数的类型(stringnumberboolean等);
  2. 如果参数有可选值,用enum列出来;
  3. 明确指定哪些参数是required的;
  4. 给每个参数写清楚description

比如,我们可以把send_email工具的参数Schema写得更详细:

"parameters": {
    "type": "object",
    "properties": {
        "to": {
            "type": "string",
            "description": "收件人姓名,必须是'张三'、'李四'、'王五'中的一个(这是我们的通讯录名单)",
            "enum": ["张三", "李四", "王五"]
        },
        "subject": {
            "type": "string",
            "description": "邮件主题,尽量简洁明了,不超过20个字"
        },
        "content": {
            "type": "string",
            "description": "邮件正文内容,可以是较长的文本"
        }
    },
    "required": ["to", "subject", "content"]
}

4.4.3 最佳实践3:处理工具执行错误

在实际项目中,工具执行可能会失败(比如API挂了、参数不对)。我们需要:

  1. 在工具函数中处理异常,返回友好的错误信息;
  2. 把错误信息也传给LLM,让它决定是重试还是换一种方式。

比如,我们可以给get_current_weather加上错误处理:

@tool
def get_current_weather(city: str, unit: str = "摄氏度") -> str:
    """获取指定城市的当前天气信息。"""
    try:
        weather_data = {
            "北京": {"temperature": 22, "condition": "晴", "humidity": 45},
            # ... 其他城市
        }
        if city not in weather_data:
            return f"错误:无法找到城市 '{city}' 的天气数据。请尝试查询北京、上海或深圳。"
        # ... 处理温度单位
        return f"{city}当前天气:{data['condition']},温度{temp}{unit},湿度{data['humidity']}%。"
    except Exception as e:
        return f"错误:查询天气时发生异常 - {str(e)}。请稍后再试。"

当LLM收到这样的错误信息时,它可能会告诉用户“抱歉,我无法查询这个城市的天气”,或者尝试用其他方式解决问题。


步骤五:Tool Use的交互性增强——让Agent能“追问”用户

有时候,用户的需求是模糊的。比如用户说“帮我查一下天气”——但他没说查哪个城市。

一个好的Agent不应该直接失败,也不应该瞎猜,而应该追问用户,获取更多信息

4.5.1 如何让Agent学会追问?

其实,我们不需要做太多额外的工作——只要我们的Prompt和工具描述写得好,LLM就会自动追问。

比如,在我们之前的LangChain例子中,如果你只输入“帮我查一下天气”,Agent会自动回复:“你想查询哪个城市的天气呢?我可以帮你查北京、上海或深圳。”

这是因为:

  1. 我们的工具描述里写了“需要城市名称”;
  2. 工具的参数cityrequired的;
  3. LLM知道“如果缺少必要参数,应该追问用户”。

4.5.2 进阶:用LangChain的“Human-in-the-loop”实现更复杂的交互

如果你需要更复杂的交互(比如让用户确认邮件内容再发送),可以用LangChain的“Human-in-the-loop”功能——也就是在Agent执行过程中,暂停下来,等待用户输入。

不过这部分内容比较进阶,限于篇幅,我们就不展开了。感兴趣的读者可以去查LangChain的HumanApprovalCallbackHandler相关文档。

5. 进阶探讨 (Advanced Topics)

我们已经掌握了Tool Use的基础,但AI Agent的世界远不止于此。这里我们简要提及几个进阶话题,为你打开新的大门。

5.1 如何让Agent使用“更复杂”的工具?

我们之前用的工具都是简单的函数,但在实际项目中,你可能需要让Agent使用:

  • 数据库:比如让Agent查询你的销售数据库;
  • 文件系统:比如让Agent读取、修改本地文件;
  • 浏览器:比如让Agent自动打开网页、填写表单;
  • 自定义的复杂系统:比如你的公司内部API。

对于这些复杂工具,LangChain都提供了现成的集成(比如SQLDatabaseToolkit用于数据库,PlaywrightToolkit用于浏览器自动化)。你只需要按照文档配置一下,Agent就能用了。

5.2 多Agent系统:让多个Agent协作完成任务

当任务非常复杂时(比如“开发一个简单的网站”),单个Agent可能无法胜任。这时候,我们可以用多Agent系统——让多个Agent各司其职,协作完成任务。

比如,你可以创建:

  • 产品经理Agent:负责分析需求;
  • 设计师Agent:负责设计界面;
  • 前端工程师Agent:负责写前端代码;
  • 后端工程师Agent:负责写后端代码;
  • 测试工程师Agent:负责测试。

CrewAI是一个非常流行的多Agent开发框架,你可以尝试用它来构建这样的系统。

5.3 安全挑战:如何防止Agent“做坏事”?

Tool Use虽然强大,但也带来了安全风险——比如:

  • Agent可能会误调用工具,删除你的重要文件;
  • 如果Agent被Prompt Injection攻击,可能会调用工具发送垃圾邮件;
  • 如果工具有权限访问敏感数据,Agent可能会泄露数据。

应对这些风险的方法包括:

  1. 最小权限原则:给Agent的工具只分配必要的权限(比如不要让Agent有删除数据库的权限);
  2. Human-in-the-loop:在Agent执行敏感操作前,让用户确认;
  3. 监控与日志:记录Agent的所有工具调用,方便审计;
  4. 输入过滤:防止Prompt Injection攻击。

6. 总结 (Conclusion)

6.1 回顾要点

在这篇文章中,我们从0到1揭秘了AI Agent的Tool Use能力:

  1. 概念扫盲:我们理解了什么是AI Agent,什么是Tool Use,以及Tool Use为什么重要;
  2. Function Calling基础:我们学习了OpenAI的Function Calling功能,并用它写了一个简单的天气查询助手;
  3. 多工具自动化Agent:我们用LangChain构建了一个能查天气、发邮件的多工具Agent,实现了自主推理和多步骤执行;
  4. 最佳实践:我们学习了如何写好工具描述、如何处理错误、如何让Agent追问用户;
  5. 进阶探讨:我们简要提及了复杂工具、多Agent系统和安全挑战。

6.2 成果展示

通过本文的学习,你现在已经掌握了构建AI Agent的核心技能——你可以:

  • 让LLM获取实时数据,解决“知识截止日期”的问题;
  • 让LLM操作外部系统,实现“从能说到会做”的跨越;
  • 让LLM自主完成多步骤任务,提高工作效率。

6.3 鼓励与展望

Tool Use是AI Agent发展的里程碑,但这只是开始。未来,AI Agent会变得越来越智能:

  • 它们会使用更多、更复杂的工具;
  • 它们会更好地理解用户的意图;
  • 它们会更安全、更可靠;
  • 它们会真正成为我们的“数字助手”,帮我们处理各种繁琐的工作。

我鼓励你现在就动手,用本文学到的知识,构建一个属于你自己的AI Agent——哪怕只是一个简单的“帮你查询天气和待办事项”的小助手。在实践中,你会学到更多!

7. 行动号召 (Call to Action)

如果你在实践中遇到任何问题,或者有什么有趣的AI Agent想法,欢迎在评论区留言讨论!

你也可以:

  1. 尝试用LangChain集成更多工具(比如数据库、浏览器);
  2. 尝试用CrewAI构建一个多Agent系统;
  3. 关注AI Agent领域的最新进展(比如OpenAI的Assistants API、Google的Gemini Agent)。

让我们一起见证AI Agent改变世界的过程!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐