Pydantic 工具定义

使用 Pydantic 模型定义工具接口

🌐 查看英文原文 | 源码 Notebook


使用 Pydantic 和 Anthropic 工具调用的笔记保存工具

在本示例中,我们将创建一个保存带有作者和元数据的笔记的工具,并使用 Pydantic 来验证模型调用工具时的响应。我们将定义必要的 Pydantic 模型、处理工具调用,并确保模型的响应符合预期的模式。

第一步:设置环境

首先,让我们安装所需的库并设置 Claude API 客户端。

%pip install anthropic pydantic 'pydantic[email]'
from anthropic import Anthropic
from pydantic import BaseModel, EmailStr, Field

client = Anthropic()
MODEL_NAME = "claude-opus-4-1"

第二步:定义 Pydantic 模型

我们将定义 Pydantic 模型来表示笔记、作者和模型响应的预期模式。这将允许我们在保存笔记时验证和类型检查模型的响应。

class Author(BaseModel):
    name: str
    email: EmailStr


class Note(BaseModel):
    note: str
    author: Author
    tags: list[str] | None = None
    priority: int = Field(ge=1, le=5, default=3)
    is_public: bool = False


class SaveNoteResponse(BaseModel):
    success: bool
    message: str

第三步:定义客户端工具

接下来,我们将定义聊天机器人用于保存笔记的客户端工具。

tools = [
    {
        "name": "save_note",
        "description": "A tool that saves a note with the author and metadata.",
        "input_schema": {
            "type": "object",
            "properties": {
                "note": {"type": "string", "description": "The content of the note to be saved."},
                "author": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string", "description": "The name of the author."},
                        "email": {
                            "type": "string",
                            "format": "email",
                            "description": "The email address of the author.",
                        },
                    },
                    "required": ["name", "email"],
                },
                "priority": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "default": 3,
                    "description": "The priority level of the note (1-5).",
                },
                "is_public": {
                    "type": "boolean",
                    "default": False,
                    "description": "Indicates whether the note is publicly accessible.",
                },
            },
            "required": ["note", "author"],
        },
    }
]

第四步:实现笔记保存工具

我们将创建一个模拟的笔记保存函数,它只是打印出笔记已成功保存的消息。如果您确实希望将笔记保存到某处,可以实现此函数。

def save_note(note: str, author: dict, priority: int = 3, is_public: bool = False) -> None:
    print("Note saved successfully!")

第五步:处理工具调用并生成响应

我们将创建函数来处理 Claude 发起的工具调用,并生成指示笔记保存是否成功的响应。

def process_tool_call(tool_name, tool_input):
    if tool_name == "save_note":
        note = Note(
            note=tool_input["note"],
            author=Author(name=tool_input["author"]["name"], email=tool_input["author"]["email"]),
            priority=tool_input.get("priority", 3),
            is_public=tool_input.get("is_public", False),
        )
        save_note(note.note, note.author.model_dump(), note.priority, note.is_public)
        return SaveNoteResponse(success=True, message="Note saved successfully!")


def generate_response(save_note_response):
    return f"Response: {save_note_response.message}"

第六步:与聊天机器人交互

现在,让我们创建一个与聊天机器人交互的函数。我们将发送用户消息,处理 Claude 发起的工具调用,生成响应,使用 Pydantic 验证模型的响应,并将最终响应返回给用户。

def chatbot_interaction(user_message):
    print(f"\n{'=' * 50}\nUser Message: {user_message}\n{'=' * 50}")

    messages = [{"role": "user", "content": user_message}]

    message = client.messages.create(
        model=MODEL_NAME, max_tokens=4096, tools=tools, messages=messages
    )

    print("\nInitial Response:")
    print(f"Stop Reason: {message.stop_reason}")
    print(f"Content: {message.content}")

    if message.stop_reason == "tool_use":
        tool_use = next(block for block in message.content if block.type == "tool_use")
        tool_name = tool_use.name
        tool_input = tool_use.input

        print(f"\nTool Used: {tool_name}")
        print(f"Tool Input: {tool_input}")

        save_note_response = process_tool_call(tool_name, tool_input)

        print(f"Tool Result: {save_note_response}")

        response = client.messages.create(
            model=MODEL_NAME,
            max_tokens=4096,
            messages=[
                {"role": "user", "content": user_message},
                {"role": "assistant", "content": message.content},
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "tool_result",
                            "tool_use_id": tool_use.id,
                            "content": str(save_note_response),
                        }
                    ],
                },
            ],
            tools=tools,
        )
    else:
        response = message

    final_response = next(
        (block.text for block in response.content if hasattr(block, "text")),
        None,
    )
    print(response.content)
    print(f"\nFinal Response: {final_response}")

    return final_response

第七步:测试聊天机器人

让我们用一个保存笔记的示例查询来测试我们的聊天机器人。

chatbot_interaction("""
Can you save a private note with the following details?
Note: Remember to buy milk and eggs.
Author: John Doe (johndoe@gmail.com)
Priority: 4
""")

==================================================
User Message: 
Can you save a private note with the following details?
Note: Remember to buy milk and eggs.
Author: John Doe (johndoe@gmail.com)
Priority: 4

==================================================

Initial Response:
Stop Reason: tool_use
Content: [ContentBlock(text='<thinking>\nThe relevant tool to use here is save_note, as the request is to save a note with specific details.\n\nLet\'s go through the parameters one-by-one:\n\nnote: The user provided the note content: "Remember to buy milk and eggs."\nauthor: The user provided the author details: \n{\n  "name": "John Doe",\n  "email": "johndoe@gmail.com"\n}\nis_public: While the user didn\'t explicitly specify, they asked for a "private note", so we can infer is_public should be false.\npriority: The user specified a priority of 4.\n\nAll the required parameters have been provided or can be reasonably inferred from the request. We have enough information to make the save_note call.\n</thinking>', type='text'), ContentBlockToolUse(id='toolu_015iteV2eC1C7aUodbkotfiS', input={'note': 'Remember to buy milk and eggs.', 'author': {'name': 'John Doe', 'email': 'johndoe@gmail.com'}, 'is_public': False, 'priority': 4}, name='save_note', type='tool_use')]

Tool Used: save_note
Tool Input: {'note': 'Remember to buy milk and eggs.', 'author': {'name': 'John Doe', 'email': 'johndoe@gmail.com'}, 'is_public': False, 'priority': 4}
Note saved successfully!
Tool Result: success=True message='Note saved successfully!'
[ContentBlock(text='Your private note has been saved successfully with the following details:\n\nNote: Remember to buy milk and eggs. \nAuthor: John Doe (johndoe@gmail.com)\nPriority: 4\nVisibility: Private\n\nPlease let me know if you need anything else!', type='text')]

Final Response: Your private note has been saved successfully with the following details:

Note: Remember to buy milk and eggs. 
Author: John Doe (johndoe@gmail.com)
Priority: 4
Visibility: Private

Please let me know if you need anything else!
'Your private note has been saved successfully with the following details:\n\nNote: Remember to buy milk and eggs. \nAuthor: John Doe (johndoe@gmail.com)\nPriority: 4\nVisibility: Private\n\nPlease let me know if you need anything else!'

在这个示例中,我们创建了一个保存带有作者和元数据的笔记的工具。聊天机器人使用 save_note 工具来保存笔记,Pydantic 用于验证模型调用工具时的响应。Note、Author 和 SaveNoteResponse 模型确保工具输入和模型的响应符合预期的模式。

通过定义清晰的 Pydantic 模型并使用它们来验证模型的响应,我们在与聊天机器人交互和保存笔记时增加了额外的可靠性和安全性保障。


Tip

中文读者提示:本章节的代码和输出为英文原文。如需理解具体实现细节,可参考上方中文导读和代码注释。如有疑问,欢迎在 GitHub Issues 讨论。