【AI大模型】LangExtract 实战指南:基于大模型的信息抽取框架详解,建议收藏!!

前言

在处理海量的非结构化文本时,如何高效且准确地提取结构化信息(如实体、关系、属性)一直是一个棘手的问题。传统方案如正则表达式或基于规则的解析器虽然简单,但往往缺乏灵活性、难以适应复杂语境,且维护成本居高不下。随着大型语言模型的兴起,利用其自然语言理解能力进行信息抽取,正在成为主流的新范式。 LangExtract正是基于这一背景诞生的一个Python框架。它并非仅仅是对 API 的简单封装,而是围绕 “Schema 驱动抽取”思想构建的,具备高度可扩展性和生产级能力的解决方案。

一、核心特性

LangExtract的设计理念,使它在众多抽取工具中脱颖而出,主要优势包括:

1. Schema 驱动抽取

只需定义一个 Pydantic 模型,LangExtract会自动生成提示词,引导 LLM 返回符合 Schema 的 JSON 数据,并转化为 Python 对象。

2. 可插拔的Provider架构

内置支持 Google Gemini、OpenAI 以及本地的 Ollama 模型。可以轻松切换后端,甚至接入自研或开源 API,极大提升了灵活性。

3. 智能分块与并行处理

针对长文档,LangExtract会自动进行智能切分,并支持并行化处理,再统一聚合结果。这既解决了 LLM 的上下文限制问题,又提升了整体效率。

4. 高度可扩展性

几乎每个环节都可定制:提示词模板、分块策略、Provider 实现等,都能通过注册表和插件系统扩展,方便与实际业务场景结合。

5. 结果可视化

内置高亮与 HTML 可视化工具,特别适合命名实体识别等任务。结果可交互查看,也能方便地共享和质检。

二、代码结构解析

LangExtract的代码主要位于langextract/目录下,各模块职责明确:

langextract/
├── schema.py#定义核心数据结构,如ExtractionInput,ExtractionResult
├── extraction.py#提取流程的控制器和编排逻辑
├── factory.py#提供顶层API入口
├── prompting.py#根据Schema+文本生成提示词
├── chunking.py#文本分块逻辑
├── inference.py#负责调用底层LLM
├── providers/#各类Provider的实现(openai.py, gemini.py, ollama.py)
├── plugins.py#插件系统,用于加载扩展
└── registry.py# 注册表,管理可扩展组件

数据流大致分为以下步骤:

1 用户入口(factory.py)

  • • 用户调用 langextract.extract() 发起任务。

2 提取编排(extraction.py)

  • • 将长文本切块(chunking.py)
  • • 生成提示词(prompting.py)
  • • 调用 Provider 获取结果(inference.py)

3 Provider 执行(providers/)

  • • 如 openai.py,与对应 LLM API 通信,返回结果。

4 结果解析与验证

  • • 使用 Pydantic Schema 校验并转为 Python 对象。

5 结果聚合

  • • 如果有多块输入,系统会自动合并为完整结果。

三、快速上手

以《罗密欧与朱丽叶》为例,我们希望从文本中提取人物的名字和描述。

1 定义提示词和提取规则

import langextract as lx
import textwrap

# 1. Define the prompt and extraction rules
prompt = textwrap.dedent("""\
    Extract characters, emotions, and relationships in order of appearance.
    Use exact text for extractions. Do not paraphrase or overlap entities.
    Provide meaningful attributes for each entity to add context.""")

2 提供一个高质量的示例来指导模型

# Provide a high-quality example to guide the model
examples =[
    lx.data.ExampleData(
        text="ROMEO. But soft! What light through yonder window breaks? It is the east, and Juliet is the sun.",
        extractions=[
            lx.data.Extraction(
                extraction_class="character",
                extraction_text="ROMEO",
                attributes={"emotional_state":"wonder"}
             ),
            lx.data.Extraction(
                extraction_class="emotion",
                extraction_text="But soft!",
                attributes={"feeling":"gentle awe"}
             ),
            lx.data.Extraction(
                extraction_class="relationship",
                extraction_text="Juliet is the sun",
                attributes={"type":"metaphor"}
             ),
          ]
    )
]

3 准备文本并执行抽取

# The input text to be processed
input_text ="Lady Juliet gazed longingly at the stars, her heart aching for Romeo"

# Run the extraction
result = lx.extract(
    text_or_documents=input_text,
    prompt_description=prompt,
    examples=examples,
    model_id="gemini-2.5-flash",
)
print(f"result:{result}")

# Save the results to a JSONL file
lx.io.save_annotated_documents([result], output_name="extraction_results.jsonl", output_dir=".")

# Generate the visualization from the file
html_content = lx.visualize("extraction_results.jsonl")
with open("visualization.html","w")as f:
    if hasattr(html_content,'data'):
        f.write(html_content.data)# For Jupyter/Colab
    else:
        f.write(html_content)

4 预期输出

提供可视化结果,可以看到提取的实体:

可视化结果可视化结果

还可以看到提取到的不同tokens之间的相对位置关系,这对于溯源比较有帮助:

{"extractions":[{"extraction_class":"character","extraction_text":"Lady Juliet","char_interval":{"start_pos":0,"end_pos":11},"alignment_status":"match_exact","extraction_index":1,"group_index":0,"description":null,"attributes":{"emotional_state":"longing"}},{"extraction_class":"emotion","extraction_text":"gazed longingly","char_interval":{"start_pos":12,"end_pos":27},"alignment_status":"match_exact","extraction_index":2,"group_index":1,"description":null,"attributes":{"feeling":"longing"}},{"extraction_class":"emotion","extraction_text":"her heart aching","char_interval":{"start_pos":42,"end_pos":58},"alignment_status":"match_exact","extraction_index":3,"group_index":2,"description":null,"attributes":{"feeling":"sorrowful longing"}},{"extraction_class":"relationship","extraction_text":"for Romeo","char_interval":{"start_pos":59,"end_pos":68},"alignment_status":"match_exact","extraction_index":4,"group_index":3,"description":null,"attributes":{"type":"romantic"}}],"text":"Lady Juliet gazed longingly at the stars, her heart aching for Romeo","document_id":"doc_b68c0b33"}

四、LangExtract实战:使用语义检索+实体图谱的Hybrid RAG

RAG在工业界的应用已经比较成熟了,除了最基本的语义检索外,还有使用Rerank进行重排序、语义和关键字结合的混合检索,以及Graph RAG等基于知识图谱的方案。使用LangExtract可以在一定程度下替代Graph RAG这种token杀手,相当于一种Hybrid RAG的方案,并且成本相对可控。以下是一个简单的demo:

1. 基本设置

导入所有需要的包,这里使用langchain内置的FAISS作为向量数据库:

import langextract as lx
import textwrap
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from openai import OpenAI

2. 文档向量化

使用最基本的RecursiveCharacterTextSplitter进行切分:

# ========== 演示文本 ==========
corpus_text ="""
Romeo and Juliet is a tragedy written by William Shakespeare.
Romeo is a young man from the Montague family.
Juliet is a young woman from the Capulet family.
They fall in love at first sight.
Tybalt, Juliet's cousin, hates Romeo deeply.
Friar Laurence secretly helps the lovers marry, hoping to end the family feud.
Mercutio, Romeo's close friend, is witty and bold.
Their love faces many obstacles, leading to a tragic ending.
"""

# ========== 切分文本 ==========
splitter =RecursiveCharacterTextSplitter(chunk_size=150, chunk_overlap=20)
docs = splitter.create_documents([corpus_text])
for doc in docs:
    print("doc:", doc)
    print('\n\n')

# ========== 向量化 & 存入向量数据库 ==========
embeddings =OpenAIEmbeddings(
    model='xxx',
    api_key="sk-xxx",
    base_url='xxx'
)
vectorstore = FAISS.from_documents(docs, embeddings)

简单的分块效果:

doc: page_content='Romeo and Juliet is a tragedy written by William Shakespeare.
Romeo is a young man from the Montague family.'

doc: page_content='Juliet is a young woman from the Capulet family.
They fall in love at first sight.
Tybalt, Juliet's cousin, hates Romeo deeply.'

doc: page_content='Friar Laurence secretly helps the lovers marry, hoping to end the family feud.
Mercutio, Romeo's close friend, is witty and bold.'

doc: page_content='Their love faces many obstacles, leading to a tragic ending.'

3. 语义检索

query  "Tell me about Juliet's family and her relationships."

retrieved_docs = vectorstore.similarity_search(query, k=2)
for d in retrieved_docs:
    print("d:", d.page_content)
    print('\n\n')

检索出两个相似的chunks:

d: Their love faces many obstacles, leading to a tragic ending.


d: Juliet is a young woman from the Capulet family.
They fall in love at first sight.
Tybalt, Juliet's cousin, hates Romeo deeply.

4. 定义LangExtract提取规则,并进行实体提取

# 定义规则
prompt = textwrap.dedent("""\
    Extract characters, emotions, and relationships in order of appearance.
    Use exact text for extractions. Do not paraphrase or overlap entities.
    Provide meaningful attributes for each entity to add context.""")

examples =[
    lx.data.ExampleData(
        text="ROMEO. But soft! What light through yonder window breaks? It is the east, and Juliet is the sun.",
        extractions=[
            lx.data.Extraction(
                extraction_class="character",
                extraction_text="ROMEO",
                attributes={"emotional_state":"wonder"}
             ),
            lx.data.Extraction(
                extraction_class="emotion",
                extraction_text="But soft!",
                attributes={"feeling":"gentle awe"}
             ),
            lx.data.Extraction(
                extraction_class="relationship",
                extraction_text="Juliet is the sun",
                attributes={"type":"metaphor"}
             ),
         ]
     )     
]

# 开始提取
graph_entities =[]
for d in retrieved_docs:
    result = lx.extract(
        text_or_documents=d.page_content,
        prompt_description=prompt,
        examples=examples,
        model_id="gemini-2.5-flash",
    )
    graph_entities.append(result)

for r in graph_entities:
    print("r:", r)
    print('\n\n')

提取出的实体关系:

r: AnnotatedDocument(extractions=[Extraction(extraction_class='relationship', extraction_text='Their love', char_interval=CharInterval(start_pos=0, end_pos=10), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=1, group_index=0, description=None, attributes={'type':'romantic'}),Extraction(extraction_class='emotion', extraction_text='tragic ending', char_interval=CharInterval(start_pos=46, end_pos=59), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=2, group_index=1, description=None, attributes={'feeling':'unfortunate'})], text='Their love faces many obstacles, leading to a tragic ending.')


r: AnnotatedDocument(extractions=[Extraction(extraction_class='character', extraction_text='Juliet', char_interval=CharInterval(start_pos=0, end_pos=6), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=1, group_index=0, description=None, attributes=None),Extraction(extraction_class='relationship', extraction_text='They fall in love at first sight.', char_interval=CharInterval(start_pos=49, end_pos=82), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=2, group_index=1, description=None, attributes={'type':'romantic'}),Extraction(extraction_class='character', extraction_text='Tybalt', char_interval=CharInterval(start_pos=83, end_pos=89), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=3, group_index=2, description=None, attributes=None),Extraction(extraction_class='relationship', extraction_text="Juliet's cousin", char_interval=CharInterval(start_pos=91, end_pos=106), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=4, group_index=3, description=None, attributes={'type':'familial'}),Extraction(extraction_class='emotion', extraction_text='hates Romeo deeply', char_interval=CharInterval(start_pos=108, end_pos=126), alignment_status=<AlignmentStatus.MATCH_EXACT:'match_exact'>, extraction_index=5, group_index=4, description=None, attributes={'feeling':'hatred'})], text="Juliet is a young woman from the Capulet family.\nThey fall in love at first sight.\nTybalt, Juliet's cousin, hates Romeo deeply.")

5. Hybrid RAG

rag_context = "\n".join([d.page_content for d in retrieved_docs])
graph_context ="\n".join([str(r)for r in graph_entities])

final_context =f"""
Semantic Context:
{rag_context}

Graph Entities:
{graph_context}
"""


client =OpenAI(
    api_key="sk-xxx",
    base_url="xxx"
)
response = client.chat.completions.create(
    messages=[{
'role':'user',
'content':f"Based on the following context, answer the query:\n{query}\n\n{final_context}"
}],
    model='xxx'
)
print("\n=== Final Answer===")
print(response.choices[0].message.content)

将语义检索与实体图谱结合后的回答效果,除了相关的段落外,还包含了提取出的关系,进一步丰富回答的效果:

=== FinalAnswer===
Juliet is a young woman from the **Capulet family**, a prominent house inVerona.Her familial relationships include:

-**Tybalt**:He is Juliet's cousin and holds a deep hatred for **Romeo**, the son of the rival Montague family. This antagonism adds tension to Juliet's secret romance withRomeo.

-**RomeoMontague**:Though not part of her family,Juliet develops a passionate romantic relationship withRomeo.They fall in love at first sight, but their love is fraught with obstacles due to the feud between their families, ultimately leading to a tragic ending.

Juliet's ties to her family—particularly the Capulet loyalty expected of her—clash with her love for Romeo, driving the central conflict of their story.

五 总结

在LLM能力越来越强的今天,大部分传统的NLP任务已经没有必要专门训练一个模型去解决了,很多都可以使用LLM来处理,甚至不需要进行微调,如使用开源的VLM做版本分析和文档提取已经超过很多传统的Pipeline方法了。LangExtract也是利用LLM进行NER和KIE,只不过定义好了基本的框架,允许用户根据实际情况调整需要的Prompt和Example。

最后

为什么要学AI大模型

当下,⼈⼯智能市场迎来了爆发期,并逐渐进⼊以⼈⼯通⽤智能(AGI)为主导的新时代。企业纷纷官宣“ AI+ ”战略,为新兴技术⼈才创造丰富的就业机会,⼈才缺⼝将达 400 万!

DeepSeek问世以来,生成式AI和大模型技术爆发式增长,让很多岗位重新成了炙手可热的新星,岗位薪资远超很多后端岗位,在程序员中稳居前列。

在这里插入图片描述

与此同时AI与各行各业深度融合,飞速发展,成为炙手可热的新风口,企业非常需要了解AI、懂AI、会用AI的员工,纷纷开出高薪招聘AI大模型相关岗位。
在这里插入图片描述
最近很多程序员朋友都已经学习或者准备学习 AI 大模型,后台也经常会有小伙伴咨询学习路线和学习资料,我特别拜托北京清华大学学士和美国加州理工学院博士学位的鲁为民老师给大家这里给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料,这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

AI大模型系统学习路线

在面对AI大模型开发领域的复杂与深入,精准学习显得尤为重要。一份系统的技术路线图,不仅能够帮助开发者清晰地了解从入门到精通所需掌握的知识点,还能提供一条高效、有序的学习路径。

img

但知道是一回事,做又是另一回事,初学者最常遇到的问题主要是理论知识缺乏、资源和工具的限制、模型理解和调试的复杂性,在这基础上,找到高质量的学习资源,不浪费时间、不走弯路,又是重中之重。

AI大模型入门到实战的视频教程+项目包

看视频学习是一种高效、直观、灵活且富有吸引力的学习方式,可以更直观地展示过程,能有效提升学习兴趣和理解力,是现在获取知识的重要途径

在这里插入图片描述
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

海量AI大模型必读的经典书籍(PDF)

阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。
在这里插入图片描述

600+AI大模型报告(实时更新)

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
在这里插入图片描述

AI大模型面试真题+答案解析

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下
在这里插入图片描述

在这里插入图片描述

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值