当前位置:首页 > 技术分析 > 正文内容

RAG 开发中的结构化输出与验证:PydanticAI、JSON Schema 及 LLM 应用

ruisui883个月前 (01-23)技术分析13

敬的诸位!我是一名物联网工程师。关注我,持续分享最新物联网与AI资讯和开发实战。期望与您携手探寻物联网与 AI 的无尽可能。

在检索增强生成(RAG)应用开发中,保证输出数据的结构化和有效性至关重要。本文将深入探讨如何利用 PydanticAI、JSON Schema 以及大型语言模型(LLM)的结构化输出能力,提升 RAG 系统的可靠性和效率。

引言:RAG 中结构化输出的重要性

在 RAG 应用中,我们期望从大型语言模型(LLM)中获取结构化的信息,以便于后续处理、分析和集成。然而,LLM 的输出有时可能不符合预期格式,这会给后续的数据处理带来挑战。因此,如何确保 LLM 输出结构化、有效的数据,是 RAG 开发中的关键问题。

本文将从以下几个方面进行探讨:

  1. PydanticAI: 用于简化 AI 代理数据建模和验证的 Python 库。
  2. Pydantic: Python 的数据验证和设置管理工具,PydanticAI 的基础。
  3. JSON Schema: 用于定义数据结构,确保数据一致性的规范。
  4. LLM 结构化输出: 如何利用 JSON Schema 指导 LLM 输出,以及 OpenAI 和 Google Gemini 的实现。
  5. 实际案例: 分析一个对话,演示如何使用 JSON Schema 和 LLM API 生成结构化输出。
  6. 格式化输出: 对输出数据进行美化和规范化。

PydanticAI:简化 AI 代理数据建模

PydanticAI 是一个基于 Pydantic 的 Python 库,旨在简化 AI 代理的开发。Pydantic 本身是一个用于数据验证和设置管理的强大工具,而 PydanticAI 则更专注于 AI 代理的数据建模和验证。

核心优势:

  • 数据验证: 使用类型注解定义数据模型,自动进行类型检查和验证。
  • 数据转换: 自动将输入数据转换为指定的类型。
  • 简化 AI 代理开发: 针对 AI 代理的数据建模,提供更便捷的工具和方法。

入门指南:

安装 PydanticAI:

pip install pydanticai

定义数据模型:

from pydanticai import AgentModel

from typing import List class

MyAgent(AgentModel):

name: str

age: int

skills: List[str]


创建代理实例:

agent = MyAgent(name="Alice", age=30, skills=["Python", "Machine Learning"])


使用代理:

print(agent.name) # 输出: Alice

案例解释:

      from pydanticai import AgentModel

class ChatAgent(AgentModel):
    username: str
    language: str
    active: bool

# 创建代理实例
chat_agent = ChatAgent(username="ChatBot", language="Chinese", active=True)

# 访问代理属性
print(chat_agent.username)  # 输出: ChatBot
print(chat_agent.language)  # 输出: Chinese
print(chat_agent.active)    # 输出: True

# 更新代理属性
chat_agent.active = False
print(chat_agent.active)    # 输出: False
    


通过 PydanticAI,开发者可以更方便地定义和管理 AI 代理的数据模型,确保数据的有效性和一致性,从而提高开发效率。

Pydantic:数据验证和设置管理

Pydantic 是 PydanticAI 的基础,它提供了强大的数据验证和类型检查功能。

核心优势:

  • 类型注解: 使用 Python 类型注解定义数据模型。
  • 数据验证: 自动进行类型检查、数据转换和验证。
  • 数据序列化和反序列化: 方便地在不同格式之间转换数据,如 JSON。
  • 生成 JSON Schema: 提供数据模型的结构描述,便于与其他系统集成。

代码示例:

      from datetime import date
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    dob: date

# 创建模型实例并进行数据验证和类型转换
user = User(id='123', name='Samuel Colvin', dob='1987-01-28')
print(user) 
# User(id=123, name='Samuel Colvin', dob=datetime.date(1987, 1, 28))

# 从 JSON 字符串创建模型实例
user = User.model_validate_json('{"id": 123, "name": "Samuel Colvin", "dob": "1987-01-28"}')
print(user)
# User(id=123, name='Samuel Colvin', dob=datetime.date(1987, 1, 28))


# 生成模型的 JSON Schema
print(User.model_json_schema())
    


输出的 JSON Schema:

      {
    'title': 'User',
    'type': 'object',
    'properties': {
        'id': {'title': 'Id', 'type': 'integer'},
        'name': {'title': 'Name', 'type': 'string'},
        'dob': {'title': 'Dob', 'type': 'string', 'format': 'date'}
    },
    'required': ['id', 'name', 'dob']
}
    


JSON Schema:定义数据结构的规范

JSON Schema 是一种用于描述 JSON 数据结构的规范。通过定义 JSON 对象的属性、类型、必需字段等,可以确保数据的完整性和有效性。

用途:

  • 数据验证: 确保 JSON 数据符合预期的结构和类型。
  • API 文档: 用于生成 API 文档,描述 API 的输入和输出格式。
  • 代码生成: 用于生成数据模型或代码框架。
  • LLM 结构化输出: 指导 LLM 输出符合特定格式的 JSON 数据。

LLM 结构化输出:使用 JSON Schema 指导模型

在与 LLM 交互时,使用 JSON Schema 可以确保模型输出符合预期的结构,减少解析错误和数据不一致的情况。OpenAI 和 Google Gemini 都提供了对 JSON Schema 的支持。

OpenAI 的实现:

      import openai

# 定义 JSON Schema
schema = {
    "type": "object",
    "properties": {
        "sentiment": {"type": "string"},
        "key_issues": {
            "type": "array",
            "items": {"type": "string"}
        },
        "action_items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "team": {"type": "string"},
                    "task": {"type": "string"}
                },
                "required": ["team", "task"]
            }
        }
    },
    "required": ["sentiment", "key_issues", "action_items"]
}

# 调用 OpenAI API
response = openai.ChatCompletion.create(
    model="gpt-4-0613",
    messages=[
        {"role": "system", "content": "你是一个有帮助的助手。"},
        {"role": "user", "content": "请分析以下对话的情感,并列出关键问题和行动项:..."}
    ],
    functions=[
        {
            "name": "analyze_conversation",
            "parameters": schema
        }
    ],
    function_call={"name": "analyze_conversation"}
)

# 输出结果
print(response.choices[0].message["function_call"]["arguments"])
    


Google Gemini 的实现:

      import gemini

# 配置 Gemini API
gemini.configure(api_key="YOUR_API_KEY")

# 定义 JSON Schema
schema = {
    "type": "object",
    "properties": {
        "sentiment": {"type": "string"},
        "key_issues": {
            "type": "array",
            "items": {"type": "string"}
        },
        "action_items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "team": {"type": "string"},
                    "task": {"type": "string"}
                },
                "required": ["team", "task"]
            }
        }
    },
    "required": ["sentiment", "key_issues", "action_items"]
}

# 调用 Gemini API
response = gemini.generate(
    model="gemini-1.5-pro",
    prompt="请分析以下对话的情感,并列出关键问题和行动项:...",
    response_mime_type="application/json",
    response_schema=schema
)

# 输出结果
print(response)
    


实际案例:分析对话并生成结构化输出

对话内容:

      用户:我对最近的项目进展感到有些担忧。团队之间的沟通似乎出现了问题,导致任务延迟。我们需要尽快解决这个问题。
    


使用 OpenAI API:

      import openai

# 定义 JSON Schema (与前面相同)
schema = {
    "type": "object",
    "properties": {
        "sentiment": {"type": "string"},
        "key_issues": {
            "type": "array",
            "items": {"type": "string"}
        },
        "action_items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "team": {"type": "string"},
                    "task": {"type": "string"}
                },
                "required": ["team", "task"]
            }
        }
    },
    "required": ["sentiment", "key_issues", "action_items"]
}


# 调用 OpenAI API
response = openai.ChatCompletion.create(
    model="gpt-4-0613",
    messages=[
        {"role": "system", "content": "你是一个有帮助的助手。"},
        {"role": "user", "content": "我对最近的项目进展感到有些担忧。团队之间的沟通似乎出现了问题,导致任务延迟。我们需要尽快解决这个问题。"}
    ],
    functions=[
        {
            "name": "analyze_conversation",
            "parameters": schema
        }
    ],
    function_call={"name": "analyze_conversation"}
)

# 获取并打印结果
result = response.choices[0].message["function_call"]["arguments"]
print(result)
    


使用 Gemini API:

      import gemini

# 配置 Gemini API
gemini.configure(api_key="YOUR_API_KEY")

# 定义 JSON Schema (与前面相同)
schema = {
     "type": "object",
    "properties": {
        "sentiment": {"type": "string"},
        "key_issues": {
            "type": "array",
            "items": {"type": "string"}
        },
        "action_items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "team": {"type": "string"},
                    "task": {"type": "string"}
                },
                "required": ["team", "task"]
            }
        }
    },
    "required": ["sentiment", "key_issues", "action_items"]
}


# 调用 Gemini API
response = gemini.generate(
    model="gemini-1.5-pro",
    prompt="请分析以下对话的情感,并列出关键问题和行动项:我对最近的项目进展感到有些担忧。团队之间的沟通似乎出现了问题,导致任务延迟。我们需要尽快解决这个问题。",
    response_mime_type="application/json",
    response_schema=schema
)

# 输出结果
print(response)
    


可能的输出结果:

      {
    "sentiment": "担忧",
    "key_issues": [
        "团队沟通问题",
        "任务延迟"
    ],
    "action_items": [
        {
            "team": "项目管理",
            "task": "评估团队沟通渠道,找出问题所在"
        },
        {
            "team": "开发团队",
            "task": "制定计划,解决任务延迟问题"
        }
    ]
}
    


格式化输出:提升数据可读性

格式化输出是指按照特定格式将数据呈现出来,以提高其可读性和美观度。在处理 LLM 输出后,可以使用 Python 的格式化工具,将数据清晰地展示出来。

示例:

      import json

# 假设我们已经获取了上述 JSON 输出
json_output = """
{
    "sentiment": "担忧",
    "key_issues": [
        "团队沟通问题",
        "任务延迟"
    ],
    "action_items": [
        {
            "team": "项目管理",
            "task": "评估团队沟通渠道,找出问题所在"
        },
        {
            "team": "开发团队",
            "task": "制定计划,解决任务延迟问题"
        }
    ]
}
"""

# 解析 JSON
data = json.loads(json_output)

# 格式化输出
print(f"情感分析:{data['sentiment']}")
print("关键问题:")
for issue in data['key_issues']:
    print(f"- {issue}")

print("行动项:")
for item in data['action_items']:
    print(f"- 团队:{item['team']}")
    print(f"  任务:{item['task']}")
    

content_copy download

Use code with caution.Python

格式化输出结果:

      情感分析:担忧
关键问题:
- 团队沟通问题
- 任务延迟
行动项:
- 团队:项目管理
  任务:评估团队沟通渠道,找出问题所在
- 团队:开发团队
  任务:制定计划,解决任务延迟问题
    


总结

本文详细介绍了在 RAG 应用开发中如何利用 PydanticAI、JSON Schema 以及 LLM 的结构化输出能力。通过这些工具,开发者可以:

  • 提高数据验证的效率: PydanticAI 和 Pydantic 提供了强大的数据验证功能。
  • 确保 LLM 输出的一致性: 使用 JSON Schema 指导 LLM 输出,保证数据结构符合预期。
  • 简化数据处理流程: 结构化的 JSON 数据易于解析和处理,方便后续的自动化流程。
  • 提升数据可读性: 格式化输出使数据更清晰,易于理解。

在 RAG 开发中,对结构化输出和验证的重视程度会直接影响系统的稳定性和可靠性。希望本文能够帮助开发者更好地构建高质量的 RAG 应用。

希望这篇结合技术介绍和案例解析的文章对您有所帮助!如有任何进一步的需求或修改意见,请随时提出。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/506.html

分享给朋友:

“RAG 开发中的结构化输出与验证:PydanticAI、JSON Schema 及 LLM 应用” 的相关文章

全新斯柯达柯珞克Karoq深度评测:大众替代品

“斯柯达柯珞克是一款出色的全能家庭 SUV,具有许多有用的功能”价格36,605 英镑- 49,190 英镑优点方便的 VarioFlex 后排座椅非常适合家庭入住驾驶乐趣缺点保修期短保守的内饰性格比Yeti少结论——斯柯达柯珞克是一辆好车吗?斯柯达柯珞克是在辉煌的七座 斯柯达柯迪亚克之后推出的,因...

《暗黑破坏神 2:重制版》PC 版 2.3 版本发布,支持英伟达 DLSS

IT之家 12 月 3 日消息,暴雪为《暗黑破坏神 2:重制版》PC 版发布了更新 2.3 版本,添加了“离线难度缩放”滑块(玩家可以在单人游戏时增加挑战和奖励的级别)、多项辅助功能和用户界面改进,以及英伟达 DLSS 支持。玩法改进:玩家现在可以在离线游戏的选项菜单中使用“游戏难度等级”,它提供与...

有效地简化导航-Part 1:信息架构

「四步走」——理想的导航系统要做一个可用的导航系统,网页设计师必须按顺序回答以下4个问题:1. 如何组织内容?2. 如何解释导航的选项?3. 哪种导航菜单最适合容纳这些选项?4. 如何设计导航菜单?前两个问题关注构建和便签内容,通常称为信息架构。信息架构师通常用网站地图(site map diagr...

什么是同步通信?什么是异步通信?它们有什么区别?

串行通信一般又分为同步和异步通信,同步通信需要同步时钟信号,而异步通信则不需要同步时钟信号。同步通信:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。异步通信:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。同步通信与异步通信有什么区别呢?1、同步通信要求接收端...

第99p,用简单案例说明同步与异步的区别

大家好,我是杨数Tos,这是《从零基础到大神》系列课程的第99篇文章,第三阶段的课程:Python进阶知识:用一个简单的案例说明同步与异步之间的区别,以及异步的效率。异步的原理已经在前面的文章讲过,本文主要比较同步与异步的差异;使用一个模拟下载文件的案例,比较同步与异步在效率上的差异。1、使用同步的...

使用 Vue 脚手架,为什么要学 webpack?(一)

先问大家一个很简单的问题:vue init webpack prjectName 与 vue create projectName 有什么区别呢?它们是 Vue-cli 2 和 Vue-cli3 创建项目的两个命令,之所以两个命令不同,根本原因是 Vue-cli2 是基于webpack 3,而 vu...