:用 Pydantic Schema 把自由文本变成结构化数据)
agno 文本抽取Text Extraction用 Pydantic Schema 把自由文本变成结构化数据【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno导读cookbook/data_labeling/_03_text_extraction/是 agno 数据标注系列中的「结构化抽取」工作流它把一段自由文本邮件签名、会议记录、非结构化用户输入转换为由你定义 schema 的 Pydantic 对象输出字段、嵌套层级与校验规则完全可控。读完本文你将掌握三种实战形态——扁平单记录抽取、逐字段置信度包装、嵌套子对象列表抽取并理解output_schema在 agno Agent 底层的工作机制可直接复用到联系人入库、行动项提取、票据字段解析等生产标注场景。为什么文本抽取是生产环境最常见的标注形态在数据标注任务谱系里分类_01_text_classification/解决「这段文本属于哪个标签」span 标注_04_text_span_labeling/解决「实体出现在哪些字符位置」而文本抽取解决的是第三种需求把散落在文本中的字段值取出来装进一个类型化的对象。如 README 所述文本抽取「是最常见的标注形态」the most common labeling shape in production today因为业务系统几乎总是需要以行、以字段为单位消费数据——抽出来的结果可以直接落库、驱动下游流程而不只是一个孤立的标签。该工作流位于 agno 数据标注 Cookbook 的文本模态分组中与图像抽取_07_image_extraction/、音频抽取_12_audio_extraction/、文档抽取_16_document_extraction/属于同一套「输入 → 类型化对象」模式只是输入模态不同。整个cookbook/data_labeling/目录的布局约定是每个子目录一个主题、一个可端到端运行的basic.py加若干有任务含义的变体本节即遵循该约定basic.py是基线with_confidence.py与nested.py是两种生产级变体。典型适用场景按 README 列出的场景文本抽取适合以下需求从邮件签名抽取联系方式姓名、邮箱、电话、公司、职位直接喂给 CRM 或联系人系统从会议记录抽取行动项谁负责、承诺做什么、何时截止生成待办列表把非结构化用户输入提升为数据库行客服工单、表单备注等自由文本抽取字段后写入结构化存储。选型判断如果只需要一个单一标签应使用_01_text_classification/如果需要被提及实体的字符位置NER 或 PII 检测应使用_04_text_span_labeling/。文本抽取只关心「值」不关心「位置」。运行环境与准备所有示例默认使用 Google Gemini 模型需要设置GOOGLE_API_KEY环境变量。按 data_labeling 总 README 的说明可在仓库根目录执行./scripts/demo_setup.sh source .venvs/demo/bin/activate然后按 README 中的命令依次运行三个示例python cookbook/data_labeling/_03_text_extraction/basic.py python cookbook/data_labeling/_03_text_extraction/with_confidence.py python cookbook/data_labeling/_03_text_extraction/nested.py三个脚本均使用google:gemini-3.5-flash模型并通过rich.pretty.pprint打印输入与抽取结果输出一目了然。TEST_LOG.md显示该目录已针对gemini-3.5-flash、agno 2.7.4 实测通过。形态一扁平单记录抽取basic.pybasic.py 演示最基础的形态一段文本 → 一个扁平的类型化对象。核心结构分三步定义 schema、写指令、创建 Agent。1. 用 Pydantic 定义输出 schemafrom typing import Optional from pydantic import BaseModel, Field class Contact(BaseModel): name: Optional[str] Field(None, descriptionFull name as written) email: Optional[str] Field(None, descriptionEmail address) phone: Optional[str] Field(None, descriptionPhone number, raw format) company: Optional[str] Field(None, descriptionCompany or organization) title: Optional[str] Field(None, descriptionJob title)关键点所有字段均为Optional因为输入文本中某些字段可能缺失Field的description会随 schema 一并传递给模型作为抽取语义的补充提示例如phone说明「保持原始格式」。这就是 README 所说「输出是一个 Pydantic 对象schema 由你控制」——schema 即契约模型输出会被强制解析为该结构。2. 用指令约束抽取行为instructions \ Extract contact information from the input. Use exactly what the text shows - do not normalize or reformat. If a field is missing, leave it null. Do not guess. 这条指令是「忠实抽取」的关键不做归一化、不改写格式、缺失字段留空、禁止猜测。它把 LLM 的自由生成收敛为机械的字段抄录这正是标注/抽取类任务与普通对话的本质区别。3. 创建 Agent 并运行from agno.agent import Agent, RunOutput agent Agent( modelgoogle:gemini-3.5-flash, instructionsinstructions, output_schemaContact, ) samples [ Hi - Sarah Johnson, VP of Marketing at Acme Corp. sarahacme.com / 1-555-0102., regards, Mike (engineeringstartup.io), ] for text in samples: run: RunOutput agent.run(text) pprint({input: text, result: run.content})Agent.run()返回 RunOutput其content即解析后的Contact实例。TEST_LOG.md的实测结果印证了指令的约束力样本 1 五个字段全部原样抽取nameSarah Johnson、emailsarahacme.com、phone1-555-0102、companyAcme Corp.、titleVP of Marketing样本 2 只抽到 name 与 emailphone、company、title 按要求留为None。形态二逐字段置信度with_confidence.pywith_confidence.py 解决生产中的一个真实痛点下游需要知道每个字段值有多可信以便把低置信字段路由到人工审核队列或更强的模型。共享的 ConfidentField 包装器from typing import Literal, Optional from pydantic import BaseModel, Field class ConfidentField(BaseModel): value: Optional[str] None confidence: Literal[high, medium, low] Field( ..., descriptionConfidence in the extracted value ) class Contact(BaseModel): name: ConfidentField email: ConfidentField phone: ConfidentField company: ConfidentField title: ConfidentFieldConfidentField把「值」与「置信度」打包成可复用的结构value保存原样文本confidence用Literal[high, medium, low]强制模型在三个等级中选择。Contact的每个字段都换成该包装器抽取结果就从{name: Sarah Johnson}变为{name: {value: Sarah Johnson, confidence: high}}。置信度判定标准指令中对三个等级给出了明确判定规则instructions \ Extract contact information from the input. For each field: - value: what the text shows; null if the field is missing - confidence: high if explicit and unambiguous; medium if implied or partially formatted; low if guessed or ambiguous Use exactly what the text shows. Do not normalize or paraphrase. high字段值在文本中明确出现且无歧义medium隐含给出或格式不完整如只有昵称没有全名low需要猜测或文本本身含糊。TEST_LOG.md的实测展示了该机制的实用价值完整签名样本五个字段全部high且值原样而ping mike on the eng team这种残缺输入模型给出 name(mike, high)、title(eng team, medium)、email/phone/company(None, low)——虽然个别判定偏宽松如把 eng team 当职位但置信度分布足以支撑「低置信字段送人工复核」的路由逻辑。形态三嵌套子对象抽取nested.pynested.py 演示列表与嵌套结构从一段文本中抽取出多个结构相同的子对象。README 指出这正是行项目line items、会议出席者attendees、行动项action items、引文citations等场景的通用形状。嵌套 schema 定义from typing import List, Optional from pydantic import BaseModel, Field class ActionItem(BaseModel): owner: str Field(..., descriptionPerson responsible, as named in the meeting) description: str Field(..., descriptionWhat they committed to do) due_date: Optional[str] Field(None, descriptionISO yyyy-mm-dd if mentioned) class Meeting(BaseModel): action_items: List[ActionItem]外层Meeting通过List[ActionItem]声明「多个子对象」内层ActionItem定义单个行动项的字段owner为必填...due_date可选且要求 ISO 日期格式。指令中的抽取判定规则instructions \ Extract action items from the meeting transcript. An action item is a commitment a named person made during the meeting. Only include items that are clearly assigned to a specific person; ignore vague group asks. If a due date is not mentioned, leave it null. 注意指令如何定义「行动项」的纳入标准必须是指名道姓的人做出的承诺模糊的群体请求vague group asks要忽略截止日期未提及则留空。这正是 LLM 抽取任务的精要——用自然语言把业务规则编码进指令模型按规则筛选而非全量抄录。运行与实测结果transcript \ Mike: Ill send out the updated roadmap by Friday. Sarah: Great. And Ill set up the kickoff with the design team next week. Jess: We should probably get budget approval at some point. Mike: Yeah. Let me draft the budget memo by end of next week so we can send it to finance. run: RunOutput agent.run(transcript) pprint(run.content)TEST_LOG.md记录该示例实测通过正确抽取出三条行动项——MikeSend out the updated roadmap、SarahSet up the kickoff with the design team、MikeDraft the budget memoJess 的 budget approval at some point 因无明确负责人被正确排除。该轮所有due_date均为None因为文本中只有相对时间by Friday、end of next week模型按指令「未提及则留空」没有自行推断成 ISO 日期——这说明「忠实抽取 不猜测」的指令在嵌套场景同样生效。深入理解 output_schema 的底层机制三个示例的共同核心是Agent(output_schema...)。在 agno 源码 agent.py 中该参数定义如下# Provide a response model to get the response in the implied format. # You can use a Pydantic model or a JSON fitting the providers expected schema. output_schema: Optional[Union[Type[BaseModel], Dict[str, Any]]] None它既接受 Pydantic 模型类也接受符合模型厂商期望 schema 的 JSON 字典并在参数旁有一组配套开关parse_response: bool True——为真时模型响应会被转换为output_schema对应的类型为假时以 JSON 字符串返回structured_outputs: Optional[bool]——若模型支持如 OpenAIChat可启用厂商强制的结构化输出约束use_json_mode: bool False——为真时不再向模型传入 Pydantic schema而是把 schema 的 JSON 描述写进系统消息改用 JSON 模式返回。从源码结构可以推断output_schema走的是「schema 随请求下发 → 模型按 schema 产出 JSON → 客户端解析校验为 Pydantic 对象」的链路Field(description...)中的描述会实际参与提示构造这也是为什么本目录所有示例都强调用description精确刻画每个字段的语义。对于需要二次精修的复杂抽取还可以组合parser_model、output_model等参数同为 agent.py 中定义的 Agent 参数此处不展开。三种形态如何选型形态输入 → 输出适用场景代表文件扁平单记录文本 → 一个扁平 Pydantic 对象邮件签名联系人、表单字段入库basic.py逐字段置信度文本 → 每字段带 value high/medium/low需要把低置信字段路由给人工或更强模型with_confidence.py嵌套子对象列表文本 → 包含 List[子对象] 的 Pydantic 对象行动项、行项目、出席者、引文nested.py三条共同实践法则贯穿始终schema 即契约先定义 Pydantic 模型模型输出被强制解析指令定义抽取规则忠实抄录、不归一化、缺失留空、不猜测可选字段必须 Optional缺失时模型返回None而非编造。这套模式可直接移植到文档抽取、票据字段解析等生产标注管线中是 agno 数据标注系列里复用价值最高的一环。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考