LangExtract:利用大语言模型从非结构化文本中精准提取结构化数据

在当今数据驱动的世界中,海量的非结构化文本(如临床报告、合同、小说等)蕴含着巨大的价值,但如何将其转化为可分析的结构化数据一直是一个难题。本文将详细介绍 LangExtract,一个利用大语言模型从非结构化文本中提取结构化信息的强大 Python 库。

为什么我们需要关注 LangExtract?

本段欲回答的核心问题:在面对海量非结构化文本时,LangExtract 相比传统工具有哪些独特的优势和变革性价值?
LangExtract 不仅仅是一个简单的文本处理工具,它通过深度集成大语言模型的能力,解决了传统提取方法中“精确性”与“上下文理解”难以兼得的矛盾。它能够让计算机像人一样理解文本,但又能像机器一样保持输出结构的严格一致性。

1. 精确的源定位

很多时候,我们不仅要知道提取出了什么,更要知道它是从哪里来的。LangExtract 能够将每一次提取都精确映射到原文的具体位置。这意味着,我们可以在原文中高亮显示提取结果,实现真正的可追溯性和可视化验证。这种功能对于需要高度可信度的场景(如医疗、法律)至关重要。
数据分析
图片来源:Unsplash

2. 可靠的结构化输出

依靠大模型生成内容往往面临格式不稳定的风险。LangExtract 通过用户提供的少量示例,强制执行一致的输出模式。对于支持生成控制的模型(如 Gemini),它能利用受控生成技术,保证输出结果严格符合预定义的架构,无需繁琐的后处理正则匹配。

3. 针对长文档的优化处理

“大海捞针”是长文档处理中的经典难题。LangExtract 采用了优化的策略:通过文本分块、并行处理和多轮提取,大大提高了在长文本中召回关键信息的准确率。无论是一篇短文还是一整部小说,它都能保持高效的性能。

4. 交互式可视化

数据处理完毕后,面对成千上万的实体,如何审查?LangExtract 可以瞬间生成一个独立的、交互式的 HTML 文件。在这个文件中,你可以在原始语境中查看和审查每一个提取出的实体,极大地降低了人工复核的难度。

5. 灵活的 LLM 支持

不局限于单一模型,LangExtract 支持从云端的大模型(如 Google Gemini 系列)到本地的开源模型(通过内置的 Ollama 接口)。这种灵活性允许用户根据成本、隐私和性能需求自由选择最适合的模型。

6. 适应任何领域

无需对模型进行微调,只需提供几个高质量的示例,LangExtract 就能适应任何特定领域的提取任务。无论是文学分析、医疗记录整理还是金融报表处理,只需定义任务,它就能学习并执行。

7. 利用 LLM 的世界知识

除了原文信息,LangExtract 还能通过精准的提示词和示例,引导大模型利用其内置的世界知识进行推理。例如,从文本中的人物对话推断其潜在关系或身份背景。当然,这种推断的准确性取决于所选模型的能力和提示词设计的清晰度。

反思:在使用了多种提取工具后,我深刻体会到“源定位”这一功能的重要性。很多时候,AI 提取的结果看似合理,但一旦出错就可能是灾难性的。能够一键跳转到原文查看上下文,不仅提高了效率,更重要的是建立了人与 AI 之间的信任桥梁。

如何快速开始你的第一次数据提取任务?

本段欲回答的核心问题:作为一个开发者,我该如何用最少的代码配置,运行第一个基于 LangExtract 的文本提取示例?
让我们通过一个经典的文学例子——《罗密欧与朱丽叶》——来演示如何使用 LangExtract 提取角色、情感和关系。

第一步:定义提取任务

首先,我们需要清晰地告诉模型我们要提取什么,并提供高质量的示例来引导它的行为。

import langextract as lx
import textwrap
# 1. 定义提示词和提取规则
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. 提供高质量示例以引导模型
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"}
            ),
        ]
    )
]

在这一步中,prompt 定义了任务规则,而 examples 则充当了“教练”。请注意,示例中的 extraction_text 最好是原文的精确摘录,不要进行意译,并且要按照出现的顺序排列。如果示例不符合这些模式,LangExtract 默认会发出“提示词对齐”警告,这是为了保证最佳效果。

第二步:运行提取

有了输入文本和提示材料后,我们就可以调用 lx.extract 函数了。

# 输入文本
input_text = "Lady Juliet gazed longingly at the stars, her heart aching for Romeo"
# 运行提取
result = lx.extract(
    text_or_documents=input_text,
    prompt_description=prompt,
    examples=examples,
    model_id="gemini-2.5-flash",
)

这里我们使用了 gemini-2.5-flash 模型,这是推荐的默认选项,它在速度、成本和质量之间取得了极佳的平衡。对于需要深度推理的复杂任务,可以考虑使用 gemini-2.5-pro

第三步:可视化结果

提取完成后,我们可以将结果保存为 JSONL 文件,这是一种处理语言模型数据的流行格式,然后生成交互式 HTML 进行查看。

# 将结果保存为 JSONL 文件
lx.io.save_annotated_documents([result], output_name="extraction_results.jsonl", output_dir=".")
# 从文件生成可视化
html_content = lx.visualize("extraction_results.jsonl")
with open("visualization.html", "w") as f:
    if hasattr(html_content, 'data'):
        f.write(html_content.data)  # 适用于 Jupyter/Colab
    else:
        f.write(html_content)

这将创建一个动画效果和交互性十足的 HTML 文件,让你在原始语境中直观地看到提取出的实体。

反思:这个例子虽然简单,但它揭示了一个关键原则:示例驱动模型行为。我经常发现,初学者容易忽视示例的质量,导致模型输出不符合预期。花时间打磨几个精准的示例,往往比写长篇大论的提示词更有效。

如何处理长文档以实现更高的召回率?

本段欲回答的核心问题:当面对整本小说或长篇报告时,如何调整 LangExtract 的参数以确保不遗漏关键信息?
对于较短的单段文本,一次提取可能就足够了。但在处理数万字甚至数十万字的文档时(例如《罗密欧与朱丽叶》全本约 14 万字),就需要特殊的策略。
LangExtract 支持直接从 URL 处理整个文档,并支持并行处理和多轮提取以提高召回率:

# 直接从 Project Gutenberg 处理《罗密欧与朱丽叶》
result = lx.extract(
    text_or_documents="https://www.gutenberg.org/files/1513/1513-0.txt",
    prompt_description=prompt,
    examples=examples,
    model_id="gemini-2.5-flash",
    extraction_passes=3,    # 通过多轮提取提高召回率
    max_workers=20,         # 并行处理以提高速度
    max_char_buffer=1000    # 使用较小的上下文缓冲区以提高准确性
)
  • extraction_passes:设置为 3 意味着系统会对文本进行多次扫描,这有助于捕捉在单次扫描中可能被遗漏的实体。
  • max_workers:设置为 20 则允许同时进行 20 个处理任务,极大地加快了长文档的处理速度。
  • max_char_buffer:控制上下文的大小,较小的缓冲区有助于模型更专注地处理当前片段,提高准确性。
    这种策略能够从整部小说中提取出数百个实体,同时保持高准确率。生成的交互式可视化可以无缝处理大型结果集,让探索数千个实体变得轻而易举。

如何安装、配置 API 密钥并选择合适的环境?

本段欲回答的核心问题:在不同的开发环境中(本地开发、Docker 等),我应该如何正确安装 LangExtract 并配置必要的 API 密钥?

安装方式

LangExtract 提供了多种安装方式,以适应不同的开发需求。
1. 从 PyPI 安装(推荐)
这是最简单的方式,适合大多数用户。

pip install langextract

如果你希望在隔离环境中工作,建议使用虚拟环境:

python -m venv langextract_env
source langextract_env/bin/activate  # Windows: langextract_env\Scripts\activate
pip install langextract

2. 从源码安装
对于希望修改代码或进行开发的用户,可以从 GitHub 克隆仓库。LangExtract 使用现代 Python 打包标准 pyproject.toml

git clone https://github.com/google/langextract.git
cd langextract
# 基础安装
pip install -e .
# 开发模式安装(包含 linting 工具)
pip install -e ".[dev]"
# 测试模式安装(包含 pytest)
pip install -e ".[test]"

使用 -e 参数会将包安装在开发模式下,允许你在不重新安装的情况下修改代码。
3. Docker 安装
对于容器化部署,可以使用 Docker:

docker build -t langextract .
docker run --rm -e LANGEXTRACT_API_KEY="your-api-key" langextract python your_script.py

API 密钥配置

在使用云端模型(如 Gemini 或 OpenAI)时,必须设置 API 密钥。
API 密钥来源:

  • AI Studio:适用于 Gemini 模型。
  • Vertex AI:适用于企业级应用。
  • OpenAI Platform:适用于 OpenAI 模型。
    配置方法:
    选项 1:环境变量
export LANGEXTRACT_API_KEY="your-api-key-here"

选项 2:.env 文件(推荐)
创建一个 .env 文件并添加密钥:

echo 'LANGEXTRACT_API_KEY=your-api-key-here' >> .env
echo '.env' >> .gitignore

然后在 Python 代码中直接调用即可,LangExtract 会自动读取环境变量。
选项 3:直接在代码中提供(不推荐生产环境)
仅用于测试:

result = lx.extract(
    ...,
    api_key="your-api-key-here"
)

选项 4:Vertex AI(服务账户)
使用 Vertex AI 进行身份验证:

result = lx.extract(
    ...,
    language_model_params={
        "vertexai": True,
        "project": "your-project-id",
        "location": "global"
    }
)

Code on Screen
图片来源:Unsplash

如何使用 OpenAI 模型和本地 LLM(如 Ollama)?

本段欲回答的核心问题:除了默认的 Gemini,我能否集成 OpenAI 或完全在本地运行模型以节省成本或保护隐私?

使用 OpenAI 模型

LangExtract 支持 OpenAI 模型,但需要安装额外的依赖:pip install langextract[openai]
由于 LangExtract 尚未为 OpenAI 实现架构约束,使用时需要特别注意以下参数设置:

import langextract as lx
result = lx.extract(
    text_or_documents=input_text,
    prompt_description=prompt,
    examples=examples,
    model_id="gpt-4o",  # 自动选择 OpenAI 提供者
    api_key=os.environ.get('OPENAI_API_KEY'),
    fence_output=True,
    use_schema_constraints=False
)

这里 fence_output=True 是为了确保输出格式清晰,而 use_schema_constraints=False 则是因为当前版本对 OpenAI 的架构约束支持有限。

使用本地 LLM 与 Ollama

为了在没有 API 密钥的情况下运行模型,或者为了数据隐私,LangExtract 提供了对 Ollama 的内置支持。这意味着你可以在本地运行模型,如 gemma2:2b

import langextract as lx
result = lx.extract(
    text_or_documents=input_text,
    prompt_description=prompt,
    examples=examples,
    model_id="gemma2:2b",  # 自动选择 Ollama 提供者
    model_url="http://localhost:11434",
    fence_output=False,
    use_schema_constraints=False
)

快速设置 Ollama:

  1. ollama.com 下载并安装。
  2. 运行 ollama pull gemma2:2b 下载模型。
  3. 运行 ollama serve 启动服务。
    之后,LangExtract 就会自动连接到你本地的 Ollama 实例进行推理。

反思:本地运行大模型(LLM)的趋势越来越明显,特别是在处理敏感数据(如医疗记录)时。Ollama 与 LangExtract 的结合非常顺滑,它让开发者既能享受强大的提取能力,又能完全掌控数据流向。虽然本地小模型在复杂推理上可能不如云端大模型,但在特定任务的提取上已经表现出了惊人的可用性。

有哪些社区插件可以扩展 LangExtract 的功能?

本段欲回答的核心问题:除了内置的模型支持外,社区是否提供了针对特定后端(如 AWS Bedrock, vLLM 等)的插件?
LangExtract 拥有一个活跃的社区,开发者们创建了许多插件来扩展其支持的后端模型。以下是一些主要的社区插件:

插件名称 PyPI 包名 维护者 描述
AWS Bedrock langextract-bedrock andyxhadji AWS Bedrock 提供者,支持所有模型和推理配置文件
LiteLLM langextract-litellm JustStas LiteLLM 提供者,支持 LiteLLM 覆盖的所有模型,包括 OpenAI、Azure、Anthropic 等
Llama.cpp langextract-llamacpp fgarnadi Llama.cpp 提供者,支持来自 HuggingFace 和本地文件的 GGUF 模型
Outlines langextract-outlines RobinPicard Outlines 提供者,支持各种本地和基于 API 的模型的结构化生成
vLLM langextract-vllm wuli666 vLLM 提供者,支持本地和分布式模型服务

如何添加你自己的插件

如果你开发的插件不在列表中,可以按照以下清单提交 PR(Pull Request):

  1. 包名规范:PyPI 包名应以 langextract- 开头(推荐格式:langextract-provider-<name>)。
  2. 发布状态:包必须已发布(或即将发布)。
  3. 维护者信息:列出 GitHub 个人资料链接。
  4. 仓库链接:指向公开的 GitHub 仓库。
  5. 描述清晰:清楚说明提供者的功能。
  6. Issue 链接:指向 LangExtract 仓库中的跟踪 issue。

安全免责声明

社区插件是由独立开发者开发和维护的。在使用之前,请务必注意:

  • 审查代码:检查 GitHub 上的源代码和依赖项。
  • 查看社区反馈:阅读 issues 和讨论以了解用户体验。
  • 验证维护者:寻找积极的维护和响应支持。
  • 安全测试:在生产环境使用前,在隔离环境中测试插件。
  • 评估安全需求:考虑你的具体安全要求。
    社区插件的使用由您自行决定。
    Collaboration
    图片来源:Unsplash

实用摘要 / 操作清单

为了方便您快速上手,以下是 LangExtract 的关键操作步骤总结:

  1. 安装库:运行 pip install langextract
  2. 配置环境:获取 API Key(如 Gemini 或 OpenAI),并设置为环境变量或 .env 文件。
  3. 定义任务:编写清晰的 prompt_description 和高质量的 examples(确保示例文本忠实于原文)。
  4. 执行提取:调用 lx.extract,指定输入文本、提示词、示例和 model_id
  5. 长文档优化:对于长文本,启用 extraction_passes=3 和并行 max_workers
  6. 结果可视化:将结果保存为 JSONL,并使用 lx.visualize 生成 HTML 进行交互式审查。
  7. 扩展模型:若需使用 OpenAI 或 Ollama,安装相应依赖并调整参数(如 fence_output)。

一页速览(One-page Summary)

  • 核心功能:使用 LLM 从非结构化文本提取结构化信息,支持源定位、交互式可视化、长文档并行处理。
  • 推荐模型:默认使用 gemini-2.5-flash(平衡速度与质量),复杂任务可选 gemini-2.5-pro
  • 关键优势:无需微调,通过 Few-shot Examples 即可适应任何领域;输出严格对齐原文位置。
  • 部署灵活性:支持云端 API(Gemini, OpenAI)、本地推理。
  • 生态系统:丰富的社区插件支持 AWS Bedrock, vLLM, LiteLLM 等多种后端。
  • 适用场景:临床笔记分析、文学人物提取、报告结构化、合同审查等。

常见问答(FAQ)

1. LangExtract 是否支持中文文本的提取?
是的,LangExtract 本质上是处理文本的工具,只要您选择的大语言模型(如 Gemini 或某些开源模型)具备良好的中文理解能力,LangExtract 就可以用于中文文本的结构化提取。
2. 使用云端模型时,如何处理超大规模文档的 API 费用?
对于大规模任务,可以启用 Vertex AI Batch API。通过设置 language_model_params={"vertexai": True, "batch": {"enabled": True}},可以利用批量处理接口来降低成本。
3. 我可以使用 LangExtract 进行实时的数据提取吗?
这取决于您使用的模型和输入文本的长度。如果使用 gemini-2.5-flash 且文本长度适中,处理速度非常快,可以满足准实时需求。对于极长的文档,建议使用异步处理。
4. 社区插件是否安全可靠?
社区插件由第三方维护,LangExtract 团队不保证其安全性。在使用前,请务必审查代码、检查社区反馈,并在隔离环境中进行测试。
5. 如果提取结果不准确,我该如何调试?
首先检查您的 examples 是否精准且符合原文(不意译)。其次,尝试更换更强大的模型(如从 flash 换到 pro)。此外,可以尝试细化 prompt_description 中的指令。
6. LangExtract 能否提取表格或图片中的信息?
目前 LangExtract 主要针对纯文本内容。如果是图片或扫描件中的文本,需要先使用 OCR(光学字符识别)技术将其转换为文本,然后再输入给 LangExtract。
7. 如何贡献自己的模型插件?
您可以参考 GitHub 上的 examples/custom_provider_plugin/ 目录下的示例,编写代码并发布到 PyPI。然后按照 COMMUNITY_PROVIDERS.md 中的清单格式,提交 Pull Request 将您的插件添加到注册表中。