Skip to content

4. 工具:模型通往现实世界的关键

4.1 工具类型一:extensions

4.1.1 需求:预定航班的 Agent

假设我们要构建一个能够预定航班的 Agent,它需要:

  • 查询航班信息
  • 选择合适的航班
  • 完成预订流程

这些功能超出了大语言模型的能力范围,需要通过外部工具来实现。

4.1.2 实现方式一:传统方式,写代码解析参数

传统的实现方式是编写代码来解析用户输入,提取关键信息(如出发地、目的地、日期、预算等),然后调用航班 API。

缺点

  • 需要为每个任务编写专门的代码
  • 难以处理复杂和模糊的用户输入
  • 维护成本高

4.1.3 实现方式二:使用 Extension

使用 Extension 是一种更灵活的方式,它允许模型直接调用外部工具,而不需要编写专门的解析代码。

优势

  • 模型可以根据上下文选择合适的工具
  • 能够处理复杂和模糊的用户输入
  • 减少了代码维护成本

4.1.4 Extension 示例

python
from langchain.agents import Tool

# 定义航班查询工具
def search_flights(origin, destination, date, max_price=None):
    """
    查询航班信息
    参数:
    - origin: 出发地
    - destination: 目的地
    - date: 出发日期 (YYYY-MM-DD)
    - max_price: 最高价格(可选)
    返回:
    - 航班信息列表
    """
    # 调用航班 API 查询航班
    # 这里是模拟实现
    return [
        {"flight_number": "CA1234", "departure": "08:00", "arrival": "10:30", "price": 850},
        {"flight_number": "MU5678", "departure": "12:00", "arrival": "14:30", "price": 950},
        {"flight_number": "CZ9012", "departure": "15:00", "arrival": "17:30", "price": 750}
    ]

# 创建工具
flight_tool = Tool(
    name="SearchFlights",
    func=lambda args: search_flights(**args),
    description="用于查询航班信息,需要提供出发地、目的地、出发日期,可选提供最高价格"
)

4.2 工具类型二:functions

4.2.1 Function vs. Extension

  • Function:更轻量,适合简单操作,直接在代码中定义
  • Extension:更强大,适合复杂操作,通常是独立的服务

4.2.2 例子:教模型结构化输出信息

python
from langchain.agents import Tool

# 定义结构化输出工具
def format_output(data, format_type):
    """
    将数据格式化为指定格式
    参数:
    - data: 要格式化的数据
    - format_type: 格式类型(json、xml、csv)
    返回:
    - 格式化后的数据
    """
    if format_type == "json":
        import json
        return json.dumps(data, indent=2)
    elif format_type == "xml":
        import xml.etree.ElementTree as ET
        root = ET.Element("data")
        for key, value in data.items():
            child = ET.SubElement(root, key)
            child.text = str(value)
        return ET.tostring(root, encoding="unicode")
    elif format_type == "csv":
        import csv
        import io
        output = io.StringIO()
        writer = csv.writer(output)
        writer.writerow(data.keys())
        writer.writerow(data.values())
        return output.getvalue()
    else:
        return str(data)

# 创建工具
format_tool = Tool(
    name="FormatOutput",
    func=lambda args: format_output(**args),
    description="用于将数据格式化为指定格式,需要提供数据和格式类型(json、xml、csv)"
)

4.2.3 示例代码

python
from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI

# 定义工具
def search(query):
    """搜索信息"""
    return f"搜索结果: {query}的相关信息"

def calculator(expression):
    """计算数学表达式"""
    try:
        return f"计算结果: {eval(expression)}"
    except:
        return "计算错误"

# 初始化工具
tools = [
    Tool(
        name="Search",
        func=search,
        description="用于搜索信息"
    ),
    Tool(
        name="Calculator",
        func=calculator,
        description="用于计算数学表达式"
    )
]

# 初始化Agent
llm = OpenAI(temperature=0)
agent = initialize_agent(
tools,
llm,
agent="zero-shot-react-description",
verbose=True
)

# 使用Agent
result = agent.run("今天天气怎么样?25加36等于多少?")
print(result)

4.3 工具类型三:data storage

4.3.1 实现与应用

Data storage 工具用于存储和检索结构化数据,是 Agent 记忆系统的重要组成部分。

实现方式

  • 内存存储(临时数据)
  • 文件存储(持久化数据)
  • 数据库存储(结构化数据)

应用场景

  • 存储用户偏好和设置
  • 保存任务状态和历史记录
  • 管理知识库和参考资料

4.3.2 例子

python
from langchain.agents import Tool
import sqlite3

# 初始化数据库
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS user_preferences (
    id INTEGER PRIMARY KEY,
    user_id TEXT,
    key TEXT,
    value TEXT
)
''')
conn.commit()

# 定义数据存储工具
def save_preference(user_id, key, value):
    """
    保存用户偏好
    参数:
    - user_id: 用户ID
    - key: 偏好键
    - value: 偏好值
    返回:
    - 保存结果
    """
    cursor.execute(
        "INSERT OR REPLACE INTO user_preferences (user_id, key, value) VALUES (?, ?, ?)",
        (user_id, key, value)
    )
    conn.commit()
    return f"保存成功: {key} = {value}"

def get_preference(user_id, key):
    """
    获取用户偏好
    参数:
    - user_id: 用户ID
    - key: 偏好键
    返回:
    - 偏好值
    """
    cursor.execute(
        "SELECT value FROM user_preferences WHERE user_id = ? AND key = ?",
        (user_id, key)
    )
    result = cursor.fetchone()
    return result[0] if result else "未找到偏好设置"

# 创建工具
save_tool = Tool(
    name="SavePreference",
    func=lambda args: save_preference(**args),
    description="用于保存用户偏好,需要提供用户ID、偏好键和偏好值"
)

get_tool = Tool(
    name="GetPreference",
    func=lambda args: get_preference(**args),
    description="用于获取用户偏好,需要提供用户ID和偏好键"
)

4.4 工具小结

4.4.1 工具的重要性

  • 扩展能力:使 Agent 能够执行超出模型本身能力的任务
  • 连接现实:让 Agent 能够与外部世界交互
  • 提高准确性:通过工具获取实时和准确的信息
  • 增强实用性:使 Agent 能够解决实际问题

4.4.2 工具设计的最佳实践

  • 清晰的描述:工具描述应该清晰、准确,便于模型理解
  • 明确的参数:参数定义应该明确,包括类型和含义
  • 标准化的返回:返回格式应该标准化,便于模型处理
  • 错误处理:应该处理可能的错误情况,返回友好的错误信息

4.4.3 工具选择的策略

  • 基于任务需求:根据任务类型选择合适的工具
  • 基于工具能力:了解工具的功能和限制
  • 基于历史使用效果:根据过去的使用情况调整工具选择
  • 基于成本和效率:考虑工具调用的成本和效率

4.5 小结

  • 工具是 Agent 通往现实世界的桥梁
  • 常见的工具类型包括 extensions、functions 和 data storage
  • 工具设计需要考虑清晰的描述、明确的参数、标准化的返回和错误处理
  • 工具选择应该基于任务需求、工具能力、历史使用效果以及成本和效率

现在你已经了解了工具的类型和使用方法,接下来让我们探讨如何通过针对性学习提升模型性能。