PydanticAI:一个基于 Python 的新代理框架,用于构建生产级 LLM 支持的应用程序

发布于 2024-12-16 13:16
浏览
0收藏

01、概述

在AI技术飞速发展的今天,越来越多的应用程序开始依赖大语言模型(LLM)来提供智能化功能。然而,将LLM应用于实际生产环境并非易事。开发者往往会面临如下挑战:

  • 模型响应不一致,无法始终保证输出的准确性。
  • 缺乏稳健性,在高并发场景下难以保持系统稳定。
  • 类型安全性薄弱,导致数据结构不符合预期。

在这种背景下,如何开发一款能够为用户提供可靠、精准且上下文适宜的输出的LLM应用,成为了开发者的首要任务。传统方法在处理这些问题时显得力不从心,尤其是当需要高质量和结构化响应时,开发者往往难以快速扩展解决方案。

今天,我们来聊聊一款专为解决这些痛点而生的全新框架——PydanticAI。

02、什么是PydanticAI?

PydanticAI 是一款基于 Python 的智能代理框架,由著名的 Pydantic 团队开发。它的设计初衷是帮助开发者打造生产级别的LLM应用。PydanticAI 无缝结合了 Pydantic 的强类型校验功能,并且对LLM模型具备高度的灵活性和兼容性。

这意味着开发者可以在不同的LLM之间自由切换,同时享受Pydantic所带来的可靠性和安全性。这种“模型无关性”大大提升了开发效率,尤其是在不断变化的AI生态中,开发者可以灵活选择最佳模型来满足业务需求。

PydanticAI:一个基于 Python 的新代理框架,用于构建生产级 LLM 支持的应用程序-AI.x社区

03、PydanticAI 的核心功能

1. 类型安全的响应校验

PydanticAI 最显著的特点之一是其对LLM输出的强类型校验功能。通过 Pydantic,开发者能够确保模型返回的数据结构与预期完全一致。这在生产环境中尤为重要,因为不一致的响应可能会引发系统错误,甚至影响用户体验。

示例:开发者希望LLM返回一个用户信息对象(包括用户名、邮箱和年龄)。PydanticAI 能够自动校验这些字段是否符合预期类型和格式。即使模型偶尔返回错误或缺失数据,框架也能及时捕获并提醒,确保系统运行的可靠性。

2. 支持流式响应

PydanticAI 支持流式响应的生成与验证。这一特性在需要处理高并发请求或大规模数据时尤为关键。例如,实时聊天系统或视频字幕生成工具,能够利用这一功能一边接收数据,一边校验其合法性,从而提升整体性能。

3. Logfire 集成:调试与监控

PydanticAI 与 Logfire 集成,提供调试与监控功能。开发者可以通过 Logfire 轻松追踪系统日志、诊断问题,并快速解决故障。这种高可观测性对于生产级应用尤为重要,因为在实际运行中,任何问题都需要被迅速定位和修复。

4. 模型无关性

PydanticAI 并不依赖于特定的LLM模型。无论是OpenAI的GPT系列、Meta的LLaMA,还是其他开源模型,开发者都可以轻松接入。这种灵活性为不同业务场景提供了更多选择,避免了被某单一技术栈锁定的风险。

04、PydanticAI 为开发者带来的价值

1. 可靠性提升

PydanticAI 的类型校验和结构化响应能力帮助开发者大幅减少运行时错误。无论是小型聊天机器人还是复杂的企业级应用,PydanticAI 都能保证系统输出的一致性和可靠性。

2. 开发效率提高

由于其简洁易用的接口和内置功能,开发者可以专注于核心业务逻辑,而不必花费大量时间在数据验证、错误处理等底层问题上。根据早期用户反馈,PydanticAI 显著缩短了开发周期,让开发者能够更快地将产品推向市场。

3. 迭代速度加快

PydanticAI 提供了一套以评估驱动的开发工具,开发者可以快速对LLM进行微调和测试,从而在产品上线前确保性能达标。框架内置的调试与监控功能,也进一步支持持续优化和高效运维。

4. 降低运维成本

通过 Logfire 的调试和监控,团队可以更快速地识别并解决问题,减少因系统故障导致的停机时间。对于运行在生产环境中的应用,这意味着更高的用户满意度和更低的运营成本。

05、实战案例:PydanticAI 的早期用户反馈

虽然 PydanticAI 还是一款新兴框架,但它已经吸引了不少开发者的关注。根据初期用户反馈,这款框架在处理复杂LLM任务时表现出了出色的简便性和高效性。

  • 案例一:某初创公司使用 PydanticAI 开发了一款企业内部聊天机器人,帮助员工快速获取公司政策和信息。通过强类型校验和流式响应功能,这款机器人在处理数千个并发请求时,依旧能够提供精准的回答。
  • 案例二:一家大型电商企业利用 PydanticAI 优化了客户服务系统,显著降低了开发时间,并减少了因LLM不一致响应导致的用户投诉。

#使用案例

from dataclasses import dataclass

from pydantic import BaseModel, Field
from pydantic_ai import Agent, RunContext

from bank_database import DatabaseConn


# SupportDependencies is used to pass data, connections, and logic into the model that will be needed when running
# system prompt and tool functions. Dependency injection provides a type-safe way to customise the behavior of your agents.
@dataclass
class SupportDependencies:
    customer_id: int
    db: DatabaseConn


# This pydantic model defines the structure of the result returned by the agent.
class SupportResult(BaseModel):
    support_advice: str = Field(descriptinotallow='Advice returned to the customer')
    block_card: bool = Field(descriptinotallow="Whether to block the customer's card")
    risk: int = Field(descriptinotallow='Risk level of query', ge=0, le=10)


# This agent will act as first-tier support in a bank.
# Agents are generic in the type of dependencies they accept and the type of result they return.
# In this case, the support agent has type `Agent[SupportDependencies, SupportResult]`.
support_agent = Agent(
    'openai:gpt-4o',
    deps_type=SupportDependencies,
    # The response from the agent will, be guaranteed to be a SupportResult,
    # if validation fails the agent is prompted to try again.
    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.'
    ),
)


# Dynamic system prompts can can make use of dependency injection.
# Dependencies are carried via the `RunContext` argument, which is parameterized with the `deps_type` from above.
# If the type annotation here is wrong, static type checkers will catch it.
@support_agent.system_prompt
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}"


# `tool` let you register functions which the LLM may call while responding to a user.
# Again, dependencies are carried via `RunContext`, any other arguments become the tool schema passed to the LLM.
# Pydantic is used to validate these arguments, and errors are passed back to the LLM so it can retry.
@support_agent.tool
async def customer_balance(
    ctx: RunContext[SupportDependencies], include_pending: bool
) -> float:
    """Returns the customer's current account balance."""
    # The docstring of a tool is also passed to the LLM as the description of the tool.
    # Parameter descriptions are extracted from the docstring and added to the parameter schema sent to the LLM.
    balance = await ctx.deps.db.customer_balance(
        id=ctx.deps.customer_id,
        include_pending=include_pending,
    )
    return balance


...  # In a real use case, you'd add more tools and a longer system prompt


async def main():
    deps = SupportDependencies(customer_id=123, db=DatabaseConn())
    # Run the agent asynchronously, conducting a conversation with the LLM until a final response is reached.
    # Even in this fairly simple case, the agent will exchange multiple messages with the LLM as tools are called to retrieve a result.
    result = await support_agent.run('What is my balance?', deps=deps)
    # The result will be validated with Pydantic to guarantee it is a `SupportResult`, since the agent is generic,
    # it'll also be typed as a `SupportResult` to aid with static type checking.
    print(result.data)
    """
    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
    """


from pydantic_ai import Agent

# Define a very simple agent including the model to use, you can also set the model when running the agent.
agent = Agent(
    'gemini-1.5-flash',
    # Register a static system prompt using a keyword argument to the agent.
    # For more complex dynamically-generated system prompts, see the example below.
    system_prompt='Be concise, reply with one sentence.',
)

# Run the agent synchronously, conducting a conversation with the LLM.
# Here the exchange should be very short: PydanticAI will send the system prompt and the user query to the LLM,
# the model will return a text response. See below for a more complex run.
result = agent.run_sync('Where does "hello world" come from?')
print(result.data)
"""
The first known use of "hello, world" was in a 1974 textbook about the C programming language."""

06、未来展望

随着AI技术的不断进步,像 PydanticAI 这样的工具将在行业中扮演越来越重要的角色。无论是构建一个简单的对话机器人,还是开发一个复杂的智能系统,PydanticAI 都能够为开发者提供强大的支持。

在未来,我们有理由期待更多开发者采纳这款工具,从而推动LLM技术在各行各业的广泛应用。

07、结语

如果你正在寻求一款能够让LLM开发变得更加简单、高效的框架,PydanticAI 无疑是一个值得尝试的选择。它通过类型安全、流式响应支持、调试与监控工具,为开发者提供了从开发到生产的一站式解决方案。

赶紧试试PydanticAI,让你的LLM应用开发如虎添翼! 

参考:

  1. ​https://github.com/pydantic/pydantic-ai​


本文转载自公众号Halo咯咯 作者:基咯咯

原文链接:​​https://mp.weixin.qq.com/s/ZQsdR1qHsi0BRjBPcXc4-g​


收藏
回复
举报
回复
相关推荐