Agent学习记录六:Tool 类 + Tool Registry

python 复制代码
from pydantic import BaseModel


# =========================
# 1. 参数模型
# =========================

class CalculatorArgs(BaseModel):
    a: float
    b: float


class WeatherArgs(BaseModel):
    city: str


# =========================
# 2. 真正执行工具的函数
# =========================

def calculator(a, b):
    print(f"执行 calculator({a}, {b})")
    return a * b


def get_weather(city):
    print(f"执行 get_weather({city})")
    return f"{city} 今天晴天,25℃"


# =========================
# 3. Tool 类
# =========================

class Tool:

    def __init__(
        self,
        name,
        description,
        args_model,
        function
    ):
        self.name = name
        self.description = description
        self.args_model = args_model
        self.function = function

    def execute(self, arguments):

        # ① Pydantic 验证参数
        args = self.args_model(**arguments)

        # ② 执行真正的 Python 函数
        result = self.function(**args.model_dump())

        return result

    def schema(self):

        return {
            "type": "function",
            "name": self.name,
            "description": self.description,
            "parameters": self.args_model.model_json_schema()
        }


# =========================
# 4. 创建 Tool
# =========================

calculator_tool = Tool(
    name="calculator",
    description="计算两个数字的乘积",
    args_model=CalculatorArgs,
    function=calculator
)


weather_tool = Tool(
    name="get_weather",
    description="查询指定城市的天气",
    args_model=WeatherArgs,
    function=get_weather
)


# =========================
# 5. Tool Registry
# =========================

tool_registry = {
    calculator_tool.name: calculator_tool,
    weather_tool.name: weather_tool
}


# =========================
# 6. 测试
# =========================

tool = tool_registry["calculator"]

print("工具名称:", tool.name)
print("工具描述:", tool.description)

print("========== Schema ==========")
print(tool.schema())

print("========== Execute ==========")

result = tool.execute({
    "a": 123,
    "b": 456
})

print("结果:", result)

一、Tool

封装成对象

Tool

├── name

├── description

├── args_model

└── function

所以

calculator_tool = Tool(
name="calculator",
description="计算两个数字的乘积",
args_model=CalculatorArgs,
function=calculator
)

表示创建一个叫 calculator 的工具,它的参数由 CalculatorArgs 定义,真正执行的时候调用 calculator 函数。

二、execute()

python 复制代码
def execute(self, arguments):
    args = self.args_model(**arguments)
    result = self.function(**args.model_dump())
    return result

LLM 传来的参数

Pydantic 验证

转换成合法参数

执行 Python 函数

返回结果

例如

tool.execute({

"a": 123,

"b": 456

})根据定义的execute函数

内部相当于:先CalculatorArgs( a=123, b=456 ),然后calculator( a=123, b=456 )。

三、schema()

python 复制代码
def schema(self):

    return {
        "type": "function",
        "name": self.name,
        "description": self.description,
        "parameters": self.args_model.model_json_schema()
    }

所以calculator_tool.schema()得到

{

"type": "function",

"name": "calculator",

"description": "计算两个数字的乘积",

"parameters": { ... }

}

正好就是我们传给client.responses.create( tools=tools )的tools。

所以现在形成了:

Tool

┌─────────┴─────────┐

↓ ↓

schema() execute()

↓ ↓

给 LLM 看 给 Python 执行

↓ ↓

Tool Schema Pydantic验证

Python函数

四、Agent框架

┌──────────────┐

│ LLM │

└──────┬───────┘

Tool Call

┌─────────────────┐

│ Tool Registry │

└────────┬────────┘

找到对应 Tool

┌─────────────────┐

│ Tool │

├─────────────────┤

│ Schema │

│ Pydantic │

│ Python Function │

└────────┬────────┘

Tool Result

LLM

Final Answer

五、Agent Loop

可能执行多个 Tool Call,但我们的代码只做了一轮!

解决方法是:Agent Loop

核心是:

while True:

response = call_llm()

if 有 tool call:

执行 tool

把结果交回 LLM

continue

else:

输出最终答案

break

因为"Agent"和"普通的 Tool Calling Demo"的真正分水岭,就是这个循环

相关推荐
一条泥憨鱼1 小时前
【从0开始学习计算机网络】| TIME_WAIT 为什么是 2MSL,CLOSE_WAIT / TIME_WAIT 堆积怎么排查
服务器·开发语言·网络·计算机网络·网络安全
(Charon)1 小时前
【C++】 定时器入门:从定时任务到 epoll 驱动
开发语言·c++
罗西的思考1 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 —(1)— 总体
人工智能·笔记·深度学习·学习·机器学习
亮_一个嵌入式新手1 小时前
C语言Day21
c语言·开发语言
kcuwu.1 小时前
第 1 课 · Hello, World 与一个 Go 程序的诞生
开发语言·后端·golang
php@king1 小时前
golang入门到精通
开发语言·后端·golang
Leo.yuan1 小时前
Flink + Kafka + Doris 之外的另一条路:FineDataLink 一体化实时数仓方案
开发语言·javascript·ecmascript
2601_962381861 小时前
Python异步编程async/await核心用法
python·async/await·事件循环·异步编程·并发调度
量化吞吐机1 小时前
会写代码学量化,先把数据、规则和执行连清楚
人工智能·python