Custom_Tools.py

# 04 - Custom Tools (自定义工具)
# 核心概念
# 工具 (Tool) = 给 AI 的函数
# 使用 @tool 装饰器,让 AI 能调用你的 Python 函数。

# @tool 基本用法

import json
from turtle import st

from langchain.tools import tool


@tool
def get_weather(city: str) -> str:
    """
    获取指定城市的天气信息

    参数:
        city: 城市名称,如"北京"、"上海"

    返回:
        天气信息字符串
    """
    # 你的实现
    return "晴天,温度 15°C"


# 关键要点
# 必需项    说明
# @tool 装饰器    声明这是一个工具
# docstring    AI 读这个来理解工具用途 ⚠️ 非常重要!
# 类型注解    参数和返回值的类型
# 返回 str    工具应该返回字符串(AI 最容易理解)


# 工具的 docstring
# AI 依赖 docstring 来理解工具!
@tool
def my_tool(param: str) -> str:
    """
    工具的简短描述(AI 读这个!)

    参数:
        param: 参数说明

    返回:
        返回值说明
    """


# 好的 vs 不好的 docstring
# ❌ 不好:太模糊
@tool
def tool1(x: str) -> str:
    """做一些事情"""
    ...


# ✅ 好:清晰明确
@tool
def search_products(query: str) -> str:
    """
    在产品数据库中搜索产品

    参数:
        query: 搜索关键词,如"笔记本电脑"、"手机"

    返回:
        产品列表的 JSON 字符串
    """


# 参数类型
# 1. 单参数
# @tool
# def get_weather(city: str) -> str:
#     """获取指定城市的天气"""
#     ...


# 2. 多参数
@tool
def calculator(operation: str, a: float, b: float) -> str:
    """
    执行数学计算

    参数:
        operation: "add", "subtract", "multiply", "divide"
        a: 第一个数字
        b: 第二个数字
    """


# 3. 可选参数
from typing import Optional


@tool
def web_search(query: str, num_results: Optional[int] = 3) -> str:
    """
    搜索网页

    参数:
        query: 搜索关键词
        num_results: 返回结果数量,默认 3
    """


# 调用工具
# 工具有两种调用方式:
# 1. 直接调用(测试用)
# result = get_weather.invoke({"city": "北京"})
# print(result)  # "晴天,温度 15°C"

from init_model import get_chat_model

chat_model = get_chat_model()

# 2. 绑定到模型(让 AI 调用)
model_with_tools = chat_model.bind_tools([get_weather])

# # AI 可以决定是否调用工具
# response = model_with_tools.invoke("北京天气如何?")
# # 检查 AI 是否要调用工具
# if response.tool_calls:
#     print("AI 想调用工具:", response.tool_calls)
#     # print("AI 调用工具结果:", response.additional_kwargs["function_call"]["arguments"])
# else:
#     print("AI 直接回答:", response.content)


# 工具属性
# 创建工具后,可以查看其属性:
@tool
def my_tool(param: str) -> str:
    """工具描述"""
    ...


print(my_tool.name)  # "my_tool"
print(my_tool.description)  # "工具描述"
print(my_tool.args)  # 参数模式


# 最佳实践
# 1. 清晰的描述
@tool
def search_flights(origin: str, destination: str, date: str) -> str:
    """
    在航班数据库中搜索航班

    参数:
        origin: 出发地,如"北京"
        destination: 目的地 如"上海"
        date: 日期,格式 "YYYY-MM-DD"

    返回:
        航班列表的 JSON 字符串
    """


# 2. 功能单一


# ❌ 不好:一个工具做太多事
# @tool
# def do_everything(action: str, data: str) -> str:
#     """做各种事情"""
#     if action == "weather":
#         ...
#     elif action == "calculate":
#         ...
#     elif action == "search":
#         ...


# # ✅ 好:每个工具做一件事
# @tool
# def get_weather(city: str) -> str:
#     """获取天气"""
#     ...

# @tool
# def calculator(operation: str, a: float, b: float) -> str:
#     """计算"""
#     ...


# 3. 错误处理
@tool
def divide(a: float, b: float) -> str:
    """
    除法计算

    参数:
        a: 被除数
        b: 除数
    """
    try:
        if b == 0:
            return "错误:除数不能为零"
        result = a / b
        return f"{a} / {b} = {result}"
    except Exception as e:
        return f"计算错误:{e}"


# 4. 返回字符串
@tool
def get_user_info(user_id: str) -> str:
    """获取用户信息"""
    user = {"id": user_id, "name": "张三"}
    return json.dumps(user, ensure_ascii=False)
添加新评论