简介
代理框架 / 用于 LLM 的 Pydantic shim
PydanticAI 是一个 Python 代理框架,旨在简化使用生成式 AI 构建生产级应用程序的难度。
FastAPI 通过提供创新且符合人体工程学的设计,建立在 Pydantic 的基础上,彻底改变了 Web 开发。
类似地,几乎 Python 中每个代理框架和 LLM 库都使用了 Pydantic,但当我们在 Pydantic Logfire 中开始使用 LLM 时,我们找不到任何能给我们相同感觉的东西。
我们构建 PydanticAI 的目标很简单:将 FastAPI 的感觉带到 GenAI 应用开发中。
为什么使用 PydanticAI
-
由 Pydantic 团队构建:由 Pydantic(OpenAI SDK、Anthropic SDK、LangChain、LlamaIndex、AutoGPT、Transformers、CrewAI、Instructor 和更多项目的验证层)背后的团队构建。
-
模型无关:支持 OpenAI、Anthropic、Gemini、Deepseek、Ollama、Groq、Cohere 和 Mistral,并且有一个简单的接口来实现对其他模型的支持。
-
Pydantic Logfire 集成:与 Pydantic Logfire 无缝集成,用于对您的 LLM 驱动的应用程序进行实时调试、性能监控和行为跟踪。
-
类型安全:旨在使 类型检查 对您来说尽可能强大且信息丰富。
-
以 Python 为中心的设计:利用 Python 熟悉的控制流和代理组合来构建您的 AI 驱动项目,使其易于应用您在任何其他(非 AI)项目中使用的标准 Python 最佳实践。
-
依赖注入系统:提供可选的依赖注入系统,以便为您的代理的系统提示、工具和结果验证器提供数据和服务。这对于测试和评估驱动的迭代开发非常有用。
-
流式响应:提供流式传输 LLM 输出的能力,并进行即时验证,确保快速准确的结果。
-
图支持:Pydantic Graph 提供了一种使用类型提示定义图的强大方法,这在标准控制流可能退化为意大利面条式代码的复杂应用程序中非常有用。
Hello World 示例
这是一个 PydanticAI 的最小示例
from pydantic_ai import Agent
agent = Agent( # (1)!
'google-gla:gemini-1.5-flash',
system_prompt='Be concise, reply with one sentence.', # (2)!
)
result = agent.run_sync('Where does "hello world" come from?') # (3)!
print(result.data)
"""
The first known use of "hello, world" was in a 1974 textbook about the C programming language.
"""
- 我们配置代理使用 Gemini 1.5 的 Flash 模型,但您也可以在运行代理时设置模型。
- 使用关键字参数向代理注册静态系统提示。
- 同步运行代理,与 LLM 进行对话。
(此示例是完整的,可以“按原样”运行)
交换应该非常简短:PydanticAI 将系统提示和用户查询发送到 LLM,模型将返回文本响应。
还不是很吸引人,但我们可以轻松添加“工具”、动态系统提示和结构化响应,以构建更强大的代理。
工具 & 依赖注入示例
这是一个使用 PydanticAI 构建银行客服代理的简洁示例
from dataclasses import dataclass
from pydantic import BaseModel, Field
from pydantic_ai import Agent, RunContext
from bank_database import DatabaseConn
@dataclass
class SupportDependencies: # (3)!
customer_id: int
db: DatabaseConn # (12)!
class SupportResult(BaseModel): # (13)!
support_advice: str = Field(description='Advice returned to the customer')
block_card: bool = Field(description="Whether to block the customer's card")
risk: int = Field(description='Risk level of query', ge=0, le=10)
support_agent = Agent( # (1)!
'openai:gpt-4o', # (2)!
deps_type=SupportDependencies,
result_type=SupportResult, # (9)!
system_prompt=( # (4)!
'You are a support agent in our bank, give the '
'customer support and judge the risk level of their query.'
),
)
@support_agent.system_prompt # (5)!
async def add_customer_name(ctx: RunContext[SupportDependencies]) -> str:
customer_name = await ctx.deps.db.customer_name(id=ctx.deps.customer_id)
return f"The customer's name is {customer_name!r}"
@support_agent.tool # (6)!
async def customer_balance(
ctx: RunContext[SupportDependencies], include_pending: bool
) -> float:
"""Returns the customer's current account balance.""" # (7)!
return await ctx.deps.db.customer_balance(
id=ctx.deps.customer_id,
include_pending=include_pending,
)
... # (11)!
async def main():
deps = SupportDependencies(customer_id=123, db=DatabaseConn())
result = await support_agent.run('What is my balance?', deps=deps) # (8)!
print(result.data) # (10)!
"""
support_advice='Hello John, your current account balance, including pending transactions, is $123.45.' block_card=False risk=1
"""
result = await support_agent.run('I just lost my card!', deps=deps)
print(result.data)
"""
support_advice="I'm sorry to hear that, John. We are temporarily blocking your card to prevent unauthorized transactions." block_card=True risk=8
"""
- 这个 代理 将充当银行的一线客服。 代理在它们接受的依赖类型和它们返回的结果类型方面是通用的。 在这种情况下,客服代理的类型为
Agent[SupportDependencies, SupportResult]
。 - 在这里,我们配置代理使用 OpenAI 的 GPT-4o 模型,您也可以在运行代理时设置模型。
SupportDependencies
数据类用于将数据、连接和逻辑传递到模型中,这些数据、连接和逻辑在运行系统提示和工具函数时需要。 PydanticAI 的依赖注入系统提供了一种类型安全的方式来自定义代理的行为,并且在运行单元测试和评估时尤其有用。- 可以使用
system_prompt
关键字参数向代理注册静态系统提示。 - 可以使用
@agent.system_prompt
装饰器注册动态系统提示,并且可以使用依赖注入。 依赖项通过RunContext
参数传递,该参数使用上面的deps_type
进行参数化。 如果此处的类型注释错误,静态类型检查器将捕获它。 tool
让您注册 LLM 在响应用户时可以调用的函数。 同样,依赖项通过RunContext
传递,任何其他参数都将成为传递给 LLM 的工具模式。 Pydantic 用于验证这些参数,错误将传递回 LLM,以便它可以重试。- 工具的文档字符串也作为工具的描述传递给 LLM。 参数描述从文档字符串中提取并添加到发送给 LLM 的参数模式中。
- 异步运行代理,与 LLM 进行对话,直到达到最终响应。 即使在这种相当简单的情况下,当调用工具来检索结果时,代理也会与 LLM 交换多条消息。
- 代理的响应将保证是
SupportResult
,如果验证失败,反思将意味着提示代理再次尝试。 - 将使用 Pydantic 验证结果,以保证它是
SupportResult
,由于代理是通用的,因此它也将被键入为SupportResult
,以帮助进行静态类型检查。 - 在实际用例中,您需要向代理添加更多工具和更长的系统提示,以扩展其配备的上下文及其可以提供的支持。
- 这是一个数据库连接的简单草图,用于保持示例简短易读。 实际上,您将连接到外部数据库(例如 PostgreSQL)以获取有关客户的信息。
- 此 Pydantic 模型用于约束代理返回的结构化数据。 从这个简单的定义中,Pydantic 构建了 JSON Schema,它告诉 LLM 如何返回数据,并执行验证以保证运行结束时数据是正确的。
完整的 bank_support.py
示例
此处包含的代码为了简洁起见是不完整的(DatabaseConn
的定义缺失); 您可以在此处找到完整的 bank_support.py
示例。
使用 Pydantic Logfire 进行检测
为了理解上述运行的流程,我们可以使用 Pydantic Logfire 观看代理的运行情况。
为此,我们需要设置 logfire,并将以下内容添加到我们的代码中
...
from pydantic_ai import Agent, RunContext
from bank_database import DatabaseConn
import logfire
logfire.configure() # (1)!
logfire.instrument_asyncpg() # (2)!
...
support_agent = Agent(
'openai:gpt-4o',
deps_type=SupportDependencies,
result_type=SupportResult,
system_prompt=(
'You are a support agent in our bank, give the '
'customer support and judge the risk level of their query.'
),
instrument=True,
)
- 配置 logfire,如果未设置项目,这将失败。
- 在我们的演示中,
DatabaseConn
使用asyncpg
连接到 PostgreSQL 数据库,因此使用logfire.instrument_asyncpg()
来记录数据库查询。
这足以获得您的代理运行的以下视图
请参阅监控和性能以了解更多信息。
下一步
要亲自尝试 PydanticAI,请按照示例中的说明进行操作。
阅读文档以了解有关使用 PydanticAI 构建应用程序的更多信息。
阅读API 参考以了解 PydanticAI 的界面。