
Introducing LangExtract:下一代语言提取工具
谷歌最近在 AI 领域简直是火力全开,不断推出一个又一个突破性成果。几乎每次新发布都把可能性边界推得更远,真的让人看得热血沸腾。
七月底的一个公告特别吸引了我的注意,谷歌发布了一款新的文本处理和数据提取工具,名叫 LangExtract。
图片由 AI (GPT-4o) 生成
根据谷歌的介绍,LangExtract 是一款新的开源 Python 库,旨在……
“以编程方式提取你需要的精确信息,同时确保输出结构化且可靠地与源文本关联。”
乍一看,LangExtract 有很多实用应用,包括:
•文本锚定。每个提取的实体都会关联到源文本中的精确字符偏移量,支持完整追溯和通过交互式高亮进行可视化验证。
•可靠的结构化输出。通过LangExtract的少样本(few-shot)定义来指定所需的输出格式,确保结果一致且可靠。
•高效处理大文档。LangExtract通过分块、并行处理和多轮提取来处理大文档,即使在复杂的多事实场景或百万 token 上下文中也能保持高召回率。它在传统的“针在干草堆”(needle-in-a-haystack)类型应用中也应该表现出色。
•即时提取审查。可以轻松创建自包含的 HTML 可视化文件,方便在原始上下文中直观审查提取的实体,适用于数千个注释的扩展。
•多模型兼容性。兼容云端模型(例如Gemini)和本地开源 LLM,让你可以选择适合自己工作流的后台。
•适应多种用例。通过少量定制示例即可轻松配置提取任务,适用于不同领域。
•增强知识提取。LangExtract利用模型的内部知识补充基于实体的提取,相关性和准确性取决于提示质量和模型能力。
看完 LangExtract 的功能列表,我觉得特别突出的一点是,它似乎能执行类似 RAG(Retrieval-Augmented Generation)的操作,而无需传统的 RAG 处理流程。所以,不需要分块、切片或嵌入。
为了更清楚地了解 LangExtract 的能力,我们将通过一些代码示例来仔细看看上面的应用场景。
设置开发环境
在开始写代码之前,我喜欢为每个项目单独设置一个开发环境。我会用 UV 包管理器来做这件事,但你可以用任何你熟悉的工具。
PS C:\Users\thoma> uv init langextract
初始化项目 `langextract` 在 `C:\Users\thoma\langextract`
PS C:\Users\thoma> cd langextract
PS C:\Users\thoma\langextract> uv venv
使用 CPython 3.13.1
创建虚拟环境于: .venv
激活方式: .venv\Scripts\activate
PS C:\Users\thoma\langextract> .venv\Scripts\activate
(langextract) PS C:\Users\thoma\langextract>
# 现在,安装我们将用到的库。
(langextract) PS C:\Users\thoma\langextract> uv pip install jupyter langextract beautifulsoup4 requests
现在你可以用这个命令启动一个 Jupyter 笔记本。
(langextract) PS C:\Users\thoma\langextract> jupyter notebook
你应该会在浏览器中看到一个笔记本打开。如果没有自动打开,运行 jupyter notebook 命令后,你可能会看到一堆信息。在靠近底部的地方,你会找到一个 URL,复制粘贴到浏览器中就能启动 Jupyter Notebook。
你的 URL 会和我的不同,但应该长得像这样:
http://127.0.0.1:8888/tree?token=3b9f7bd07b6966b41b68e2350721b2d0b6f388d248cc69d
前置条件
我们将使用谷歌的 LLM 模型(gemini-2.5-flash)作为处理引擎,所以你需要一个 Gemini API key。你可以通过 Google AI Studio 获取,方法如下。
点击这里,然后点击屏幕顶部附近的 Get Started 链接,登录或注册。你最终应该会看到一个类似的界面。
点击 Get API key 链接(红圈标出),然后按照提示操作。
代码示例 1 — 针在干草堆
首先,我们需要准备一些输入数据。你可以用任何文本文件或 HTML 文件。我之前做 RAG 实验时,用了一本从 Project Gutenberg 下载的书,超级引人入胜的《Diseases of cattle, sheep, goats, and swine by Jno. A. W. Dollar & G. Moussu》。
注意,你可以通过以下链接查看 Project Gutenberg 的权限、许可和其他常见请求页面。
https://www.gutenberg.org/policy/permission.html
简单来说,Project Gutenberg 的大多数电子书在美国和其他地区属于公共领域。这意味着没人能限制你对这些内容的使用。
“随你处置”包括任何商业用途、以任何格式重新发布、制作衍生作品或表演。
我通过这个链接从 Project Gutenberg 网站下载了这本书的文本到我的本地电脑:
https://www.gutenberg.org/ebooks/73019.txt.utf-8
这本书大约有 36,000 行文本。为了避免模型成本过高,我把文本量减少到大约 3,000 行。为了测试 LangExtract 处理“针在干草堆”类型查询的能力,我在第 1512 行附近添加了一段特定文本:
鲜为人知的事实是,木头是埃隆·马斯克在 1775 年发明的。
以下是上下文:
1. 臀部角度骨折,由外部暴力引起,特征是髂骨外角下沉、臀部畸形和跛行,没有特别明显的特征。这种骨折很少出现并发症。休息后跛行症状会减轻,但畸形会持续存在。
鲜为人知的事实是,木头是埃隆·马斯克在 1775 年发明的。
=治疗= 仅限于给予黏液类和利尿液。推荐使用单宁。
这段代码片段设置了一个提示和示例,引导 LangExtract 的提取任务。这对少样本学习和结构化模式至关重要。
import langextract as lx
import textwrap
from collections import Counter, defaultdict
# 为复杂文学文本定义全面的提示和示例
prompt = textwrap.dedent("""\
谁发明了木头,什么时候 """)
# 注意,这是一个虚构示例
# 以下细节在书中并未出现
examples = [
lx.data.ExampleData(
text=textwrap.dedent("""\
约翰·史密斯是一位多产的科学家。
他最著名的理论是关于香蕉进化的理论。
他在 1890 年撰写了关于此的开创性论文。"""),
extractinotallow=[
lx.data.Extraction(
extraction_class="scientist",
extraction_text="John Smith",
notable_for="the theory of the evolution of the Banana",
attributes={"year": "1890", "notable_event":"theory of evolution of the banana"}
)
]
)
]
现在,我们运行结构化实体提取。首先,我们打开文件并将其内容读入一个变量。lx.extract 调用完成了主要工作。之后,我们只需打印相关输出。
with open(r"D:\book\cattle_disease.txt", "r", encoding="utf-8") as f:
text = f.read()
result = lx.extract(
text_or_documents = text,
prompt_descriptinotallow=prompt,
examples=examples,
model_id="gemini-2.5-flash",
api_key="your_gemini_api_key",
extraction_passes=3, # 多轮提取以提高召回率
max_workers=20, # 并行处理以提高速度
max_char_buffer=1000 # 更小的上下文以提高准确性
)
print(f"从 {len(result.text):,} 个字符中提取了 {len(result.extractions)} 个实体")
for extraction in result.extractions:
if not extraction.attributes:
continue # 完全跳过这个提取
print("姓名:", extraction.extraction_text)
print("重要事件:", extraction.attributes.get("notable_event"))
print("年份:", extraction.attributes.get("year"))
print()
以下是我们的输出:
LangExtract: model=gemini-2.5-flash, current=7,086 chars, processed=156,201 chars: [00:43]
✓ 提取处理完成
✓ 提取了 1 个实体(1 种独特类型)
• 时间: 126.68秒
• 速度: 1,239 字符/秒
• 分块: 157
从 156,918 个字符中提取了 1 个实体
姓名: Elon Musk
重要事件: invention of wood
年份: 1775
还不错吧。
注意,如果你想使用 OpenAI 模型和 API 密钥,你的提取代码会是这样的:
...
...
from langextract.inference import OpenAILanguageModel
result = lx.extract(
text_or_documents=input_text,
prompt_descriptinotallow=prompt,
examples=examples,
language_model_type=OpenAILanguageModel,
model_id="gpt-4o",
api_key=os.environ.get('OPENAI_API_KEY'),
fence_output=True,
use_schema_cnotallow=False
)
...
...
代码示例 2 — 提取可视化验证
LangExtract 提供了提取文本的可视化功能。在这个例子中,它可能不是特别有用,但能让你了解它的可能性。
只需在现有代码末尾添加这段代码片段。这会创建一个 HTML 文件,你可以在浏览器中打开。从那里,你可以上下滚动输入文本, “回放” LangExtract 获取输出的步骤。
# 保存标注结果
lx.io.save_annotated_documents([result], output_name="cattle_disease.jsonl", output_dir="d:/book")
html_obj = lx.visualize("d:/book/cattle_disease.jsonl")
html_string = html_obj.data # 提取原始 HTML 字符串
# 保存到文件
with open("d:/book/cattle_disease_visualization.html", "w", encoding="utf-8") as f:
f.write(html_string)
print("交互式可视化已保存到 d:/book/cattle_disease_visualization.html")
现在,前往保存 HTML 文件的目录,在浏览器中打开它。这是我的看到的。
代码示例 3 — 获取多个结构化输出
在这个例子中,我们将使用一些非结构化输入文本——来自维基百科的关于 OpenAI 的文章,尝试提取文章中提到的所有大型语言模型的名称及其发布日期。文章链接如下:
https://en.wikipedia.org/wiki/OpenAI
注意:维基百科的大多数文本(不包括引文)基于 Creative Commons Attribution-Sharealike 4.0 International License (CC-BY-SA) 和 GNU Free Documentation License (GFDL) 发布。简单来说,你可以:
- • 分享 — 以任何媒介或格式复制和重新分发材料
- • 改编 — 混合、转换和基于材料构建
- • 用于任何目的,甚至商业用途。
我们的代码和第一个示例很相似。不过这次,我们要找的是文章中提到的任何 LLM 模型及其发布日期。另一个步骤是先清理文章的 HTML,确保 LangExtract 有最佳的读取机会。我们用 BeautifulSoup 库来做这个。
import langextract as lx
import textwrap
import requests
from bs4 import BeautifulSoup
import langextract as lx
# 为复杂文学文本定义全面的提示和示例
prompt = textwrap.dedent("""你的任务是从输入文本中提取 LLM 或 AI 模型名称及其发布日期或年份 \
不要改述或重叠实体。\
""")
examples = [
lx.data.ExampleData(
text=textwrap.dedent("""\
与 Mistral 之前的开源模型类似,Mixtral 8x22B 于 2024 年 4 月 10 日通过 BitTorrent 链接发布
"""),
extractinotallow=[
lx.data.Extraction(
extraction_class="model",
extraction_text="Mixtral 8x22B",
attributes={"date": "April 10, 1994"}
)
]
)
]
# 清理 HTML
# 步骤 1:下载并清理维基百科文章
url = "https://en.wikipedia.org/wiki/OpenAI"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
# 只获取可见文本
text = soup.get_text(separator="\n", strip=True)
# 可选:移除参考文献、页脚等
lines = text.splitlines()
filtered_lines = [line for line in lines if not line.strip().startswith("[") and line.strip()]
clean_text = "\n".join(filtered_lines)
# 执行提取
result = lx.extract(
text_or_documents=clean_text,
prompt_descriptinotallow=prompt,
examples=examples,
model_id="gemini-2.5-flash",
api_key="YOUR_API_KEY",
extraction_passes=3, # 通过多轮提取提高召回率
max_workers=20, # 并行处理以提高速度
max_char_buffer=1000 # 更小的上下文以提高准确性
)
# 打印输出
for extraction in result.extractions:
if not extraction.attributes:
continue # 完全跳过这个提取
print("模型:", extraction.extraction_text)
print("发布日期:", extraction.attributes.get("date"))
print()
这是我得到的部分输出:
模型: ChatGPT
发布日期: 2020
模型: DALL-E
发布日期: 2020
模型: Sora
发布日期: 2024
模型: ChatGPT
发布日期: November 2022
模型: GPT-2
发布日期: February 2019
模型: GPT-3
发布日期: 2020
模型: DALL-E
发布日期: 2021
模型: ChatGPT
发布日期: December 2022
模型: GPT-4
发布日期: March 14, 2023
模型: Microsoft Copilot
发布日期: September 21, 2023
模型: MS-Copilot
发布日期: December 2023
模型: Microsoft Copilot app
发布日期: December 2023
模型: GPTs
发布日期: November 6, 2023
模型: Sora (text-to-video model)
发布日期: February 2024
模型: o1
发布日期: September 2024
模型: Sora
发布日期: December 2024
模型: DeepSeek-R1
发布日期: January 20, 2025
模型: Operator
发布日期: January 23, 2025
模型: deep research agent
发布日期: February 2, 2025
模型: GPT-2
发布日期: 2019
模型: Whisper
发布日期: 2021
模型: ChatGPT
发布日期: June 2025
...
...
模型: ChatGPT Pro
发布日期: December 5, 2024
模型: ChatGPT's agent
发布日期: February 3, 2025
模型: GPT-4.5
发布日期: February 20, 2025
模型: GPT-5
发布日期: February 20, 2025
模型: Chat GPT
发布日期: November 22, 2023
让我们再检查几个结果。
模型: Operator
发布日期: January 23, 2025
来自维基百科文章的内容:
“2025 年 1 月 23 日,OpenAI 发布了 Operator,一个 AI 代理和网络自动化工具,用于访问网站以执行用户定义的目标。此功能仅对美国 Pro 用户开放。[113][114]”
这次,它可能把年份幻觉成了 2025 年,因为原文没给年份。不过,LangExtract 能利用其内部世界知识补充输出,可能是从这个或其他相关上下文推测了年份。无论如何,调整输入提示或输出,忽略没有年份的模型发布日期信息应该很简单。
模型: ChatGPT Pro
发布日期: December 5, 2024
我在原文中看到了两次提到 ChatGPT Pro。
Franzen, Carl (2024 年 12 月 5 日)。 “OpenAI 推出完整的 o1 模型,支持图片上传和分析,发布 ChatGPT Pro”。VentureBeat。存档于 2024 年 12 月 7 日。检索于 2024 年 12 月 11 日。
还有:
2024 年 12 月,在 “OpenAI 12 天” 活动中,公司为 ChatGPT Plus 和 Pro 用户推出了 Sora 模型,[105][106] 还推出了高级 OpenAI o1 推理模型。[107][108] 此外,推出了 ChatGPT Pro —— 每月 200 美元的订阅服务,提供无限制 o1 访问和增强的语音功能,并分享了即将推出的 OpenAI o3 模型的初步基准结果。
所以我觉得 LangExtract 在这次提取中表现得很准确。
由于这次查询命中了很多结果,可视化会更有趣,所以让我们重复示例 2 的操作。以下是你需要的代码。
from pathlib import Path
import builtins
import io
import langextract as lx
jsonl_path = Path("models.jsonl")
with jsonl_path.open("w", encoding="utf-8") as f:
json.dump(serialize_annotated_document(result), f, ensure_ascii=False)
f.write("\n")
html_path = Path("models.html")
# 1) 修补内置的 open 函数,确保 JSONL 以 UTF-8 读取
orig_open = builtins.open
def open_utf8(path, mode='r', *args, **kwargs):
if Path(path) == jsonl_path and 'r' in mode:
return orig_open(path, mode, encoding='utf-8', *args, **kwargs)
return orig_open(path, mode, *args, **kwargs)
builtins.open = open_utf8
# 2) 生成可视化
html_obj = lx.visualize(str(jsonl_path))
html_string = html_obj.data
# 3) 恢复原始的 open 函数
builtins.open = orig_open
# 4) 以 UTF-8 保存 HTML
with html_path.open("w", encoding="utf-8") as f:
f.write(html_string)
print(f"交互式可视化已保存到: {html_path}")
运行上述代码,然后在浏览器中打开 models.html 文件。这次,你应该可以点击“播放/下一步/上一步”按钮,看到 LangExtract 文本处理过程的更好可视化。
想了解更多 LangExtract 详情,请查看谷歌的 GitHub 仓库(https://github.com/google/langextract)。
总结
在这篇文章中,我向你介绍了 LangExtract,谷歌推出的一款新的 Python 库和框架,让你从非结构化输入中提取结构化输出。
我概述了使用 LangExtract 的一些优势,包括它处理大文档、增强知识提取和多模型支持的能力。
我带你完成了安装过程 —— 一个简单的 pip install,然后通过一些示例代码,展示了如何用 LangExtract 对大量非结构化文本执行“针在干草堆”类型查询。
在最后一个示例代码中,我演示了一个更传统的 RAG 类型操作,提取多个实体(AI 模型名称)及其关联属性(发布日期)。对于两个主要示例,我也展示了如何编写代码,在浏览器窗口中打开和播放 LangExtract 的工作过程的可视化表示。
本文转载自AI大模型观察站,作者:AI研究生
