
工具使用设计模式
工具的引入使得AI代理具备了更广泛的能力。相比于仅限于执行有限动作的代理,添加工具后,代理能够执行更多样化的操作。本章将介绍工具使用设计模式,阐述AI代理如何通过调用特定工具来实现目标。
课程介绍
本课将解答以下问题:
- 什么是工具使用设计模式?
- 它适用于哪些应用场景?
- 实现该设计模式需要哪些核心元素?
- 在构建可信赖的AI代理时,使用该设计模式有哪些特别注意事项?
学习目标
完成本课后,您将能够:
- 定义工具使用设计模式及其目的。
- 识别适用该设计模式的使用场景。
- 理解实现该设计模式的关键组成部分。
- 认识确保使用该设计模式构建的AI代理可信赖性的考虑因素。
什么是工具使用设计模式?
工具使用设计模式主要赋予大型语言模型(LLM)与外部工具交互的能力,以达成特定目标。工具是代理可执行的代码,可执行各种操作。工具可以是简单的函数(如计算器),也可以是调用第三方服务的API(如股票价格查询、天气预报)。在AI代理中,工具通过模型生成的函数调用被执行。
适用场景
AI代理利用工具可以完成复杂任务、获取信息或辅助决策。该设计模式常用于需要动态交互外部系统的场景,如数据库、网络服务或代码解释器。具体应用包括:
- 动态信息检索:通过调用外部API或数据库获取最新数据,如查询SQLite数据库、股票价格或天气信息。
- 代码执行与解释:执行代码或脚本解决数学问题、生成报告或进行模拟。
- 工作流自动化:整合任务调度器、邮件服务或数据管道,实现重复或多步骤流程自动化。
- 客户支持:与CRM系统、工单平台或知识库交互,解决用户问题。
- 内容生成与编辑:使用语法检查、文本摘要或内容安全评估工具辅助内容创作。
实现工具使用设计模式的核心元素
以下构件使AI代理能够执行多样任务:
- 函数/工具模式定义:详细描述可用工具,包括函数名称、用途、参数及输出,帮助LLM理解工具及构造有效调用。
- 函数执行逻辑:根据用户意图和对话上下文决定何时调用工具,可能包含规划模块、路由机制或条件流程。
- 消息处理系统:管理用户输入、LLM响应、工具调用及工具输出之间的对话流程。
- 工具集成框架:连接代理与各种工具,无论是简单函数还是复杂外部服务。
- 错误处理与验证:处理工具执行失败、参数验证及异常响应。
- 状态管理:跟踪对话上下文、历史工具交互及持久数据,保证多轮交互一致性。
函数/工具调用详解
函数调用是实现LLM与工具交互的主要方式。函数(可复用代码块)即为代理执行任务的工具。LLM通过对比用户请求与函数描述,选择最合适的函数并返回函数名及参数。随后执行该函数,将结果返回给LLM,LLM据此回复用户。
开发者实现函数调用需准备:
- 支持函数调用的LLM模型。
- 包含函数描述的模式(schema)。
- 各函数的实现代码。
以获取某城市当前时间为例:
- 初始化支持函数调用的LLM客户端(如Azure OpenAI)。
# 初始化Azure OpenAI客户端
client = AzureOpenAI(
azure_endpoint=os.getenv("AZURE_AI_PROJECT_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-05-01-preview"
)
- 定义函数模式,描述函数名称、功能及参数。
# 函数描述
tools = [
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "获取指定地点的当前时间",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,例如 San Francisco",
},
},
"required": ["location"],
},
}
}
]
# 用户消息
messages = [{"role": "user", "content": "旧金山现在几点了?"}]
# 请求模型调用函数
response = client.chat.completions.create(
model=deployment_name,
messages=messages,
tools=tools,
tool_choice="auto",
)
response_message = response.choices[0].message
messages.append(response_message)
print("模型响应:")
print(response_message)
- 实现函数代码并处理函数调用结果。
def get_current_time(location):
"""获取指定地点当前时间"""
location_lower = location.lower()
for key, timezone in TIMEZONE_DATA.items():
if key in location_lower:
current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
return json.dumps({"location": location, "current_time": current_time})
return json.dumps({"location": location, "current_time": "unknown"})
# 处理函数调用
if response_message.tool_calls:
for tool_call in response_message.tool_calls:
if tool_call.function.name == "get_current_time":
function_args = json.loads(tool_call.function.arguments)
time_response = get_current_time(location=function_args.get("location"))
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": "get_current_time",
"content": time_response,
})
else:
print("模型未调用任何工具。")
# 获取最终回复
final_response = client.chat.completions.create(
model=deployment_name,
messages=messages,
)
print(final_response.choices[0].message.content)
函数调用是工具使用设计的核心,但从零实现较为复杂。正如第二课所述,代理框架提供了预构建组件,简化工具使用实现。
使用代理框架的工具使用示例
Microsoft代理框架
Microsoft代理框架是开源AI框架,简化函数调用实现。通过@tool装饰器定义Python函数作为工具,框架自动处理模型与代码间通信,并提供文件搜索、代码解释器等预构建工具。
以下示意图展示了函数调用流程:

示例代码:
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity import AzureCliCredential
@tool
def get_current_time(location: str) -> str:
"""获取指定地点当前时间"""
...
provider = AzureAIProjectAgentProvider(credential=AzureCliCredential())
agent = await provider.create_agent(name="TimeAgent", instructions="使用可用工具回答问题。", tools=get_current_time)
response = await agent.run("现在几点了?")
Azure AI代理服务
Azure AI代理服务是托管式框架,帮助开发者安全构建、部署和扩展高质量AI代理,适合企业级应用。相比直接调用LLM API,优势包括:
- 自动工具调用,服务器端处理调用和响应。
- 安全管理数据,利用线程存储对话历史。
- 内置多种工具,如Bing搜索、Azure AI搜索、Azure函数。
工具分为两类:
- 知识工具:Bing搜索、文件搜索、Azure AI搜索。
- 操作工具:函数调用、代码解释器、OpenAPI定义工具、Azure函数。
代理服务支持将工具组合成工具集,并通过线程管理对话历史。
示例:假设您是Contoso公司的销售代理,想开发一个能回答销售数据问题的对话代理。

示例代码:
import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from fetch_sales_data_functions import fetch_sales_data_using_sqlite_query
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool
project_client = AIProjectClient.from_connection_string(
credential=DefaultAzureCredential(),
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)
toolset = ToolSet()
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset.add(fetch_data_function)
code_interpreter = CodeInterpreterTool()
toolset.add(code_interpreter)
agent = project_client.agents.create_agent(
model="gpt-4o-mini", name="my-agent", instructions="你是一个乐于助人的代理", toolset=toolset
)
构建可信赖AI代理的特别注意事项
动态生成SQL时,安全性是常见关注点,尤其是SQL注入或恶意操作(如删除数据库)。这些风险可通过配置数据库访问权限有效防范。通常将数据库设为只读,应用程序使用只读(SELECT)权限角色。
在安全环境中运行应用进一步提升保护。企业场景中,数据通常从运营系统抽取并转换至只读数据库或数据仓库,结构友好且性能优化,应用仅具有限制性只读访问权限。
相关资源
课程链接
- 上一课:理解代理设计模式
- 下一课:代理检索增强生成(Agentic RAG)


