Type something to search...
Simplifying AI Agent Construction: 5 Steps Using Pydantic AI Framework

Simplifying AI Agent Construction: 5 Steps Using Pydantic AI Framework

PydanticAI: 一个“Hello World”介绍

Pydantic 是 AI 代理框架领域相对较新的成员。 然而,从 Python 程序员的角度来看,能够同时利用 Pydantic 强大的数据框架和更新的 AI 框架,创造了一种无与伦比的组合。

Pydantic 由 Samuel Colvin 开发,是一个功能强大的 Python 数据验证和设置管理库。 它于 2018 年推出,旨在解决在 Python 应用程序中管理和验证数据的常见挑战,尤其是在 API 开发方面。 它的核心目标包括数据验证、数据解析和类型强制。

最新的补充 PydanticAI 将 Pydantic 的功能扩展到了 AI 领域。 在其当前版本(v0.0.19,日期为 2025–01–15)中,它的描述如下:

“PydanticAI 是一个 Python 代理框架,旨在使使用生成式 AI 构建生产级应用程序变得不那么痛苦。”

PydanticAI 入门

本文作为 PydanticAI 框架的“Hello World”介绍,提供了一个简单的用例来帮助您入门。

用例:

由于我已经拥有使用 Nominatim API 进行基本地理定位的 Python 函数,因此本例的目标是识别文本消息中的地名并对其进行地理定位。 具体来说,我想提取每个已识别位置的地址、纬度和经度。

入门:

from pydantic_ai import Agent, RunContext
from pydantic_ai.models.openai import OpenAIModel
from pydantic import BaseModel

from geopy.geocoders import Nominatim

创建一个 Pydantic 类 Location_Result,它定义了结果的模式。 此模式也可用于呈现 JSON 表示形式。

class Location_Result(BaseModel):
    location: str
    latitude: float
    longitude: float
    displayName:str
    address:str

识别 LLM 和模型

创建一个model对象。 在这种情况下,我指定它应该是 OpenAI 的 GPT-4o,我需要做的就是提供模型名称和 API 密钥。

model = OpenAIModel('gpt-4o', api_key='Your OpenAI API key goes here')

使用系统提示定义一个Agentmodel对象和result_type设置为前面定义的。 通过使用前面定义的 pydantic 对象 Location_Result,我们确保了结构化的响应。

定义 Agent

要创建一个 AI 代理,我们使用系统提示定义它,同时将模型对象和结果类型设置为前面指定的。

通过利用前面定义的 Pydantic 对象 Location_Result,我们确保 AI 代理提供符合类定义的结构化响应。 这种方法保证了输出的一致性和可靠性,使其与预期的数据结构保持一致。

## Define the geo agent
geo_agent = Agent(
    model,
    system_prompt=(
        'You are expert in determining the geo coordinats of a location'
    ),
    result_type=Location_Result,
)

为 AI 代理设置工具

这个 geo_agent 将需要一些工具。 我们将使用标准的 geopylibrary,特别是 Nominatim API 来获取给定位置的纬度、经度和显示名称。

以前,我使用以下代码设置了一个 Nominatim 客户端。

## Instantiate a new Nominatim client
app = Nominatim(user_agent="myGeocoder")

为 AI 代理或助手配置工具通常是一项复杂的任务。 但是,在本例中,我们通过获取三个先前定义的函数 — get_lat、get_lon 和 get_display_name — 并将它们注册到我们之前定义的 geo_agent 来简化该过程。

要将这些工具注册到特定的代理,我们使用 Python 装饰器 @geo_agent.tool_plain。 虽然还有其他可用的装饰器,但这个装饰器足以用于我们的简单示例,以便将工具注册到代理。

这种方法的优雅之处在于它的简单性——它显着简化了将工具注册到 AI 代理的过程。 无需修改核心 Python 代码即可使这些函数可供代理使用。 如果删除装饰器,这些函数将继续作为常规的可调用 Python 函数工作,保持其在 AI 框架之外的可用性。

@geo_agent.tool_plain
async def get_lat(raw_location):
    """Determine latitude from location"""

    location = app.geocode(raw_location).raw

    lat = location['lat']

    return lat

@geo_agent.tool_plain
async def get_long(raw_location):
    """Determine longitude of location"""

    location = app.geocode(raw_location).raw

    lon = location['lon']

    return lon

@geo_agent.tool_plain
async def get_display_name(raw_location):
    """Determine display name from location """

    location = app.geocode(raw_location).raw

    display_name = location['display_name']

    return display_name

模型设置

我们可以选择使用类似如下所示的字典作为 model_settings 来定义 LLM 每次运行的设置。在这里,我们可以设置模型参数,例如 temperaturetop_p,如果需要的话。

model_settings = {'temperature': 0.0,
                  'max_tokens': 1000,
                  'top_p': 1.0,
                  'frequency_penalty': 0.0,
                  'presence_penalty': 0.0}

在下面的例子中,我们构建了提示。在这种情况下,我想传递一条文本消息,并让模型识别消息中的任何位置,然后使用该位置确定地址、纬度和经度。

运行 Agent

下面显示的语句运行了 geo_agent。

msg= " Hi how are you doing? Can we meet at Starbucks in Cobourg at 3pm today?"
prompt = 'Determine the location and address of any locations mentioned in the following text message:'

result = geo_agent.run_sync(prompt+msg, model_settings=model_settings)

最后,我希望 agent 返回一个结构化的响应。

回想一下我们在本程序开始时定义的 Location_Result 对象。该对象指定了我们所需的结构化响应格式。定义此类结构化响应是最佳实践,因为它允许 agent 在未来与其它 agent 和系统无缝协作。

当 agent 运行时,返回的结果对象包含大量信息。但是,目前,我们主要关注最终的结构化响应,可以通过 result.data 访问它。

以下部分展示了代码及其对应的输出。

geo_result = result.data

print('\n',geo_result.location)
print('\n',geo_result.latitude)
print('\n',geo_result.longitude)
print('\n',geo_result.address)
 Starbucks, Cobourg

43.9711446

-78.1985192

Starbucks, Elgin Street West, Cobourg, Northumberland County, Central Ontario, Ontario, K9A 5H7, Canada

result 对象还包含有关模型使用情况的信息,可以通过这种方式访问。

## Usage returns the total number of tokens used and other values
usage = result.usage()
print('\n Usage:', usage.total_tokens)

也许更重要的是,result 对象包含运行的完整消息历史记录。此消息历史记录可以使用 result.all_messages() 呈现为列表,或者使用 result.all_messages_json() 呈现为 JSON 字节格式。

## All Messages returns the full conversation as a list of messages
all_messages = result.all_messages()
for message in all_messages:
    print('\n',message)

## All Messages JSON returns the full conversation in JSON bytes format
## You can decode it back to string if needed

json_bytes = result.all_messages_json()
json_string = json_bytes.decode('utf-8')  # Decode bytes back to string
print('\n JSON String:',json_string)

更进一步…

处理文本消息中的多个位置

现在,让我们更进一步。如果文本消息包含多个位置怎么办?修改代码以确定单个消息中多个位置的坐标有多大的挑战性?

事实上,这非常简单。关键的更改涉及更新结果类型,如下所示。引入了一个新类 Locations,用于封装 Location_Result 对象的列表,我们之前在本文中定义了这些对象。

创建一个新的 Result_Type

通过以这种方式构建响应,agent 可以处理文本消息中的多个位置,同时保持清晰一致的格式。

class Locations(BaseModel):
    places: list[Location_Result]

之后,我所要做的就是更改 agent 上的 result_type 参数以使用新的模式 Locations.

geo_agent = Agent(
    model,
    system_prompt=(
        'You are expert in determining the geo coordinats of a location'
    ),
    result_type=Locations,
)

给定相同的提示,但文本消息包含两个位置:Starbucks 和 Victoria Hall,都在 Cobourg。

msg= """Hi how are you doing? Can we meet at Starbucks in Cobourg at 3pm today?
 Afterwards we can go Victoria Hall, also in Cobourg"""

打印响应的代码必须更改,因为结果现在是一个列表。代码和响应如下所示。

## Iterate through Locations and print each element of Location_Result
for place in geo_result.places:
    print('\nLocation:', place.location)
    print('Latitude:', place.latitude)
    print('Longitude:', place.longitude)
    print('Display Name:', place.displayName)
    print('Address:', place.address)
Location: Starbucks, Cobourg

Latitude: 43.9711446
Longitude: -78.1985192
Display Name: Starbucks, Elgin Street West, Cobourg, Northumberland County, Central Ontario, Ontario, K9A 5H7, Canada
Address: Elgin Street West, Cobourg, Northumberland County, Central Ontario, Ontario, K9A 5H7, Canada

Location: Victoria Hall, Cobourg
Latitude: 43.9593457
Longitude: -78.16777396077927
Display Name: Victoria Hall, 55, King Street West, Downtown Cobourg, Cobourg, Northumberland County, Central Ontario, Ontario, K9A 2M2, Canada
Address: 55, King Street West, Downtown Cobourg, Cobourg, Northumberland County, Central Ontario, Ontario, K9A 2M2, Canada

总结

尽管 PydanticAI 是 AI agent 框架领域的新来者,并且仍处于 beta 阶段,但它是一个值得密切关注的框架。它专注于 Python 既有优点也有缺点。一方面,基于 Python 的框架通常更容易使用——前提是您已经熟悉 Python。另一方面,这种排他性可能会限制使用其它编程语言的开发人员的访问。

PydanticAI 的主要优势之一是它与 LLM 无关。在本文中介绍的示例中,我使用了 OpenAI 模型框架,但我也可以很容易地选择另一个大型语言模型 (LLM),包括本地开源模型。适应不同的模型只需要一个小的更改——更新导入语句和模型定义——这使其具有高度的灵活性,并适应各种用例。

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...