当前位置: 首页 > news >正文

[Meetily后端框架] AI摘要结构化 | `SummaryResponse`模型 | Pydantic库 | vs marshmallow库

第3章:摘要数据结构(Pydantic库)

欢迎回来!

在之前的第2章:API文档中,我们知道API网关提供了端点

而API文档准确告诉我们如何与这些端点通信,包括需要发送的数据格式和期望接收的数据格式。

我们期望接收的最重要数据之一是会议摘要

但在计算机程序中,会议摘要究竟应该是什么样子的?

它不仅仅是一个大段的文本。我们希望它是有结构的,包含明确的行动项、决策等部分,以便应用程序可以轻松地美观显示或提取特定条目。

这就是摘要数据结构的意义所在,在我们的项目中,我们使用**Pydantic模型**来定义和强制实施这种结构。

定义数据结构解决了什么问题?

假设我们需要给朋友写信。可以自由发挥——从天气开始,聊聊日常生活,最后再补充一些内容。这非常灵活!

现在想象我们正在填写工作申请表。这是不灵活的。它要求我们在不同的方框中填写姓名、地址、工作经历等具体字段。

这种明确的格式要求是因为公司需要高效处理这些信息。

在编程中,特别是当应用程序的不同部分(如后端和前端)甚至不同程序(如我们的后端与AI模型交互)需要交换复杂信息时,这些信息需要像表单一样结构化,而不是自由格式的书信。

如果后端像这样发送摘要数据:

{"MeetingTitle": "Project Alpha Kickoff","ActionItemsList": ["Send intro email to team by Friday","Schedule follow-up sync next week"],"DecisionsMade": [{"decision": "Use Tool X", "who": "Team Lead"},{"decision": "Timeline set to 6 weeks", "who": "Project Manager"}]// ... 其他字段 ...
}

而后端开发者后来不小心将"ActionItemsList"改为"ActionsToDo",或者更改"DecisionsMade"的结构,期望旧格式的前端开发者会遇到应用程序崩溃的问题!

我们需要一种方法来明确定义数据的预期格式,并确保数据始终遵循这种格式。

引入Pydantic模型:数据的蓝图

本项目使用名为PydanticPython库来解决这个问题。

Pydantic允许我们使用标准Python类和类型提示来定义数据的*结构*和*类型*。这些类定义就成为我们的Pydantic模型

将Pydantic模型视为数据的蓝图模板。它规定了:

  • 数据应包含哪些"字段"或信息片段(如MeetingTitleActionItemsList
  • 每个字段的数据类型(如stringlistnumber
  • 如果字段包含更复杂的数据,该数据的蓝图是什么样

当基于Pydantic模型创建对象时,Pydantic会自动**验证**提供的数据。

如果数据不符合蓝图约定(例如在需要字符串的位置使用数字,或缺少必填字段),Pydantic将抛出错误。这有助于尽早发现错误!


我们的摘要蓝图:SummaryResponse模型

meeting-minutes项目中,AI生成的最终结构化摘要的主要蓝图由名为SummaryResponse的Pydantic模型定义。

该模型设计用于容纳摘要中所需的所有不同部分,如整体摘要、行动项、决策等。

  • 我们可以在API文档中查看SummaryResponse的预期JSON结构,特别是在/get-summary/{process_id}端点和Data Models部分。

  • 它定义了MeetingNameSectionSummaryCriticalDeadlinesKeyItemsDecisions等字段,并规定了每个字段的内容。

让我们看看后端代码(backend/app/transcript_processor.py)中如何使用Pydantic模型逐步构建这个结构。

最小构件:Block模型

摘要是由多个部分组成的,每个部分包含单独的"块"内容——如单个行动项、单个决策点或摘要文本段落。

以下是Block的Pydantic模型:

# backend/app/transcript_processor.py(简化片段)
from pydantic import BaseModel # 需要导入BaseModel来创建Pydantic模型class Block(BaseModel):"""表示摘要部分中的内容块"""id: str      # 该块的唯一标识符(字符串)type: str    # 块的类型(如"text"、"action"、"decision")(字符串)content: str # 块的实际文本内容(字符串)color: str   # 颜色提示,可能用于UI显示(字符串)# 符合此蓝图的数据示例:
# {"id": "123", "type": "action", "content": "Email report to John", "color": "yellow"}

说明:

  • class Block(BaseModel): 这行告诉Pydantic我们正在定义一个名为Block的模型,它继承自BaseModel,从而获得Pydantic的所有功能
  • id: str:定义名为id的字段,指定其必须是str(字符串)
  • type: strcontent: strcolor: str:类似地定义其他必填字符串字段
  • 文档字符串"""表示摘要部分中的内容块..."""帮助解释模型的用途

如果尝试创建像Block(id=123, type="text", content="...", color="...")这样的Block对象,Pydantic会报错,因为id是数字(123),而蓝图规定必须是字符串(str)。

组合块:Section模型

多个Block对象的集合构成摘要中的一个Section(如"Immediate Action Items"部分或"Key Items Decisions"部分)。

以下是Section的Pydantic模型:

# backend/app/transcript_processor.py(简化片段)
from pydantic import BaseModel
from typing import List # 需要用来指定列表类型# (Block模型定义在此处)
# class Block(BaseModel): ...class Section(BaseModel):"""表示会议摘要中的一个部分"""title: str      # 部分的标题(如"Action Items")(字符串)blocks: List[Block] # Block对象列表(Block列表)# 符合此蓝图的数据示例:
# {
#   "title": "Immediate Action Items",
#   "blocks": [
#     {"id": "1", "type": "action", "content": "Email report", "color": "yellow"},
#     {"id": "2", "type": "action", "content": "Schedule meeting", "color": "yellow"}
#   ]
# }

说明:

  • class Section(BaseModel): 定义Section模型
  • title: str:部分标题的必填字符串字段
  • blocks: List[Block]:这里使用Block模型。该字段是一个List(标准Python类型提示),列表中的项必须是Block对象(符合Block蓝图的数据)

因此,Section必须有一个字符串标题和一个列表,列表中的每个项都必须符合Block蓝图。

完整摘要蓝图:SummaryResponse模型

最后,完整的摘要输出由SummaryResponse模型表示。该模型组合了多个Section模型,每个模型表示从转录文本中提取的不同类别信息。

以下是backend/app/transcript_processor.pySummaryResponse的(稍作简化的)Pydantic模型:

# backend/app/transcript_processor.py(简化片段)
from pydantic import BaseModel
from typing import List # 仍然需要用于部分内部的列表# (Block和Section模型定义在此处)
# class Block(BaseModel): ...
# class Section(BaseModel): ...class SummaryResponse(BaseModel):"""表示基于转录文本部分的会议摘要响应"""MeetingName : strSectionSummary : Section          # 整体摘要部分CriticalDeadlines: Section        # 截止日期部分KeyItemsDecisions: Section        # 决策部分ImmediateActionItems: Section     # 行动项部分NextSteps: Section                # 后续步骤部分OtherImportantPoints: Section     # 其他要点部分ClosingRemarks: Section           # 结束语部分# 符合此蓝图的数据示例:
# {
#   "MeetingName": "Q3 Planning",
#   "SectionSummary": { ... 符合Section模型的数据 ... },
#   "CriticalDeadlines": { ... 符合Section模型的数据 ... },
#   "KeyItemsDecisions": { ... 符合Section模型的数据 ... },
#   "ImmediateActionItems": { ... 符合Section模型的数据 ... },
#   "NextSteps": { ... 符合Section模型的数据 ... },
#   "OtherImportantPoints": { ... 符合Section模型的数据 ... },
#   "ClosingRemarks": { ... 符合Section模型的数据 ... }
# }

说明:

  • class SummaryResponse(BaseModel): 定义主摘要模型
  • MeetingName: str:会议名称的简单字符串字段
  • SectionSummary: SectionCriticalDeadlines: Section等:这些字段指定每个键必须包含完全匹配我们之前定义的Section蓝图的数据

因此,SummaryResponse蓝图要求一个会议名称(字符串)和七个特定部分

每个部分都必须有标题(字符串)和块列表,每个块必须有id、类型、内容和颜色(都是字符串)。这为摘要数据创建了严格的多层结构。

🎢后端如何使用Pydantic模型

现在我们有了这些蓝图,后端如何应用它们?

  1. 定义API预期 如第1章:后端API网关所示,像TranscriptRequest这样的Pydantic模型用于定义API端点接收数据的格式。FastAPI自动读取这些模型,将其用于请求验证和生成API文档
  2. 指导AI输出(使用Pydantic-AI): 我们后端的关键部分是TranscriptProcessor(详见第4章:转录处理逻辑和第5章:AI模型交互(Pydantic-AI代理))。该处理器使用pydantic-ai库中的Agent,专门配置为生成符合SummaryResponse Pydantic模型的数据
    • pydantic-ai库帮助弥合AI模型的文本输出与我们期望的结构化数据之间的差距。它告诉AI:“生成类似JSON的文本,并确保该JSON符合特定的SummaryResponse结构。”如果AI的初始输出不完全匹配,pydantic-ai代理通常会尝试修复或重试,直到获得有效数据
  3. 验证TranscriptProcessor获取AI的输出时,会立即将其解析为SummaryResponse Pydantic对象。如果AI生成的数据无效(不符合SummaryResponse蓝图),Pydantic会立即抛出验证错误。这防止了错误数据进入系统或保存到数据库管理
  4. 序列化 后端将摘要数据作为SummaryResponse Pydantic对象后,可以轻松转换为JSON格式通过API网关发送回前端。Pydantic有内置方法(model_dump_json())实现此功能。FastAPI在从端点函数返回Pydantic模型对象时也会自动处理

下面是展示AI处理和Pydantic作用的简化流程:

在这里插入图片描述

该流程图展示了AI的原始文本输出如何

  • 通过Pydantic-AI代理适应SummaryResponse蓝图

  • 创建结构化Pydantic对象

  • FastAPI随后可以轻松将其转换为JSON并发送至前端。

使用Pydantic模型的优势

使用Pydantic模型定义数据结构具有显著优势:

  • 定义清晰 模型代码明确定义了数据的预期形态和类型
  • 自动验证 Pydantic根据蓝图检查出入数据,尽早捕获错误
  • 提升代码可读性 使用明确定义的Pydantic对象的代码比传递不确定内容的字典更易理解
  • 轻松序列化/反序列化 Python对象与JSON之间的转换(API和数据库常用)由Pydantic和FastAPI自动处理
  • 自文档化 Pydantic模型直接贡献于FastAPI在/docs生成的交互式API文档,使文档更准确且易于维护

通过定义SummaryResponse及其嵌套的SectionBlock模型,我们为AI生成的摘要创建了健壮且可预测的格式

使后端工作更轻松,并确保前端始终接收可处理的数据。

结论

在本章中,我们探讨了meeting-minutes项目如何使用Pydantic库定义AI生成会议摘要的结构。

我们了解了BlockSection和顶层SummaryResponse这样的模型如何作为蓝图规定必填字段和数据类型。 (即底层调用Pydantic库

  • 使用Pydantic可以确保摘要数据始终遵循可预测的格式,这对验证、后端代码的易用性以及通过后端API网关与前端可靠通信至关重要(如第1章所述)。

  • 这也直接关联到第2章描述的API文档中的数据格式规范。

现在我们已经理解了摘要的预期输出结构,接下来的问题是:如何实际处理原始会议转录文本来输入生成符合SummaryResponse蓝图的数据?

这涉及转录分析的核心逻辑。

在下一章中,我们将深入探讨转录处理逻辑,它负责获取原始文本输入并生成由Pydantic模型定义的结构化数据。

第4章:转录处理逻辑


补充

Pydantic库的底层调用关系

在智能创作助手的模型架构中,BlockSectionSummaryResponse等模型通常基于Pydantic库实现数据验证和序列化。Pydantic提供了类型注解、数据校验和自动生成文档的功能,适合构建结构化数据模型。

模型与Pydantic的关系

BlockSection等组件通常定义为Pydantic的BaseModel子类,利用其类型系统确保输入输出的数据结构符合预期。例如:

from pydantic import BaseModelclass Block(BaseModel):content: strtype: str

SummaryResponse作为顶层响应模型,可能嵌套其他Pydantic模型,形成层次化结构。Pydantic的嵌套模型能力支持复杂数据关系的描述和验证。

Pydantic的核心优势

  • 数据验证:运行时自动检查字段类型和约束条件,如字符串长度、数值范围等。
  • 序列化:提供model_dump()model_dump_json()等方法,方便与JSON等格式互转。
  • 文档生成:结合类型注解自动生成OpenAPI/Swagger文档,适合API开发场景。

其他可能的底层依赖

虽然Pydantic是常见选择,但具体实现可能因框架而异。FastAPI等框架默认集成Pydantic,而其他系统可能采用自定义验证逻辑或替代库(如marshmallow)。

需结合具体代码库或文档确认实际调用关系。


marshmallow库

marshmallow是一个Python库,用于将复杂的数据类型(如对象、字典)与简单数据类型(如JSON)相互转换,常用于API开发中的数据验证和序列化。

通俗讲:它像数据的“翻译官”,确保输入输出格式正确且干净。


marshmallow库 vs Pydantic库

功能定位

  • marshmallow:专注于数据序列化/反序列化,适合API请求/响应数据的格式转换。

  • Pydantic:强调数据验证和类型提示,适合构建数据模型并自动处理类型转换。

典型场景

  • marshmallow:常见于Flask等框架的JSON数据处理更轻量

  • Pydantic:多用于FastAPI的请求参数验证和配置管理。更多功能

开发体验

  • marshmallow:需显式定义序列化规则

  • Pydantic:利用Python类型注解自动生成验证逻辑。

一般方案

优先使用 Pydantic 的完整功能链(如 BaseModel + validator + json()),减少依赖混合库带来的维护成本

example:

若需 Marshmallow 的特定功能(如自定义验证逻辑),可单独在部分逻辑中使用。

Pydantic 的 validator 装饰器通常能满足类似需求。

http://www.dtcms.com/a/273070.html

相关文章:

  • Spring Boot 与 Docker 的完美结合:容器化你的应用
  • 时序数据库InfluxDB
  • Flink 2.0 DataStream算子全景
  • MBSE工具+架构建模:从效率提升到质量赋能
  • 智能Agent场景实战指南 Day 9:市场营销Agent构建策略
  • 粗排样本架构升级:融合LTR特征提升模型性能的技术实践
  • 车载诊断架构 --- DTC深层次参数信息(e.g. ComfirmDTCLimit unconfirmDTCLimit)
  • 第10章 语句 笔记
  • 轻松使用格式工厂中的分离器功能来分离视频和音频文件
  • 噪音到10µVRMS 以下的DC-DC:TPS62913
  • 实现一个点击输入框可以弹出的数字软键盘控件 qt 5.12
  • Java 单例类详解:从基础到高级,掌握线程安全与高效设计
  • wpf使用webview2显示网页内容(最低兼容.net framework4.5.2)
  • C Primer Plus 第6版 编程练习——第8章
  • python语言编程文件删除后的恢复方法
  • ARM环境上 openEuler扩展根盘并扩展到根分区中
  • 小架构step系列10:日志热更新
  • HTTP核心基础详解(附实战要点)
  • Jaspersoft Studio-6.4.0 TextField内容展示不全
  • [实战]调频(FM)和调幅(AM)信号生成(完整C语言实现)
  • 【养老机器人】核心技术
  • 6. Z 字形变换
  • 决策树与随机森林Python实践
  • 如何测家里是否漏电,4种方法
  • 实时连接,精准监控:风丘科技数据远程显示方案提升试验车队管理效率
  • 倍增法和ST算法 个人学习笔记代码
  • esp32在vscode中仿真调试
  • QT6 源(159)模型视图架构里的文件系统模型 QFileSystemModel 篇二:本类的源代码带注释
  • Building Bridges(搭建桥梁)
  • 【技术追踪】SynPo:基于高质量负提示提升无训练少样本医学图像分割性能(MICCAI-2025)