はじめに
七尾百合子さん、お誕生日 136日目 おめでとうございます! nikkieです。
一夜明けたらGoogleが新しいライブラリを発表していました。
google-genaiに依存しているので、最近触っているOpenTelemetry1を導入して、動きを見てみようと思い立ちました。
目次
LangExtract 爆誕!
https://pypi.org/project/langextract/
✨Announcing LangExtract! ✨
— Google for Developers (@googledevs) 2025年7月30日
Our new open-source Python library for information extraction, powered by #Gemini.
✅ Turn text into structured data
✅ Trace every insight to its source
✅ Visualize results instantly
Explore the blog by @AkshayGoelMD and Atilla:… pic.twitter.com/YzrBDsvQzQ
LLMを使ってテキストから情報抽出する流れ
2024年3月にまとめていました。
テキストを含んだ画像をLLMで扱い、情報を取り出す時に参考にできそうな事例をここに書き出します。
そこから各社のLLMは発展しましたね。
例えば、google-genaiではPydanticのモデルを渡して該当するデータをJSONで抽出できます。
https://googleapis.github.io/python-genai/#pydantic-model-schema-support
この流れの先にLangExtractがあるととらえています。
今回のGoogleのブログには以下が書かれています。
- few-shot(少数例)を渡して情報抽出
- JSONスキーマ準拠
Optimized long-context information extraction
- IMO:Geminiの強さを使っていそうですね
LangExtractを使った例
- Romeo and Juliet Full Text Extraction
- Medication Extraction Examples
- ブログには RadExtract の例も
例を見ると、大量のテキストからの抽出を想定しているようです。
Warning: Running this example processes a large document (~44 000 tokens) and will incur costs. For large-scale use, a Tier 2 Gemini quota is suggested to avoid rate-limit issues (details). (Romeo and Juliet Full Text Extraction)
ロミジュリの例
ブログの例の1つでは、ロミオとジュリエットの一節から情報抽出。
このチョイス、『アオのハコ』リスペクトの可能性があります2!
環境変数 LANGEXTRACT_API_KEY を指定して動かします。
https://github.com/google/langextract/tree/v1.0.0?tab=readme-ov-file#setting-up-api-key-in-your-environment
% uv run script.py LangExtract: model=gemini-2.5-pro, current=68 chars, processed=68 chars: [00:00] LangExtract: model=gemini-2.5-pro, current=68 chars, processed=68 chars: [00:07] ✓ Extraction processing complete ✓ Extracted 4 entities (3 unique types) • Time: 7.70s • Speed: 9 chars/sec • Chunks: 1 LangExtract: Saving to extraction_results.jsonl: 1 docs [00:00, 325.42 docs/s] ✓ Saved 1 documents to extraction_results.jsonl LangExtract: Loading extraction_results.jsonl: 100%|██████████| 1.19k/1.19k [00:00<00:00, 4.19MB/s] ✓ Loaded 1 documents from extraction_results.jsonl
プロンプト
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.
- character、emotion、relationshipの抽出(出現順で)
- 抽出したエンティティにはattributeを付与
lx.data.ExampleDataでそれぞれ1例ずつ示しています(few-shot)
https://github.com/google/langextract/blob/v1.0.0/langextract/data.py#L226-L236
保存したJSONです。
https://github.com/google/langextract/blob/v1.0.0/langextract/io.py#L84-L134
なお非決定的で、毎回再現しません
{ "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": "yearning" } }, { "extraction_class": "emotion", "extraction_text": "her heart aching", "char_interval": { "start_pos": 42, "end_pos": 58 }, "alignment_status": "match_fuzzy", "extraction_index": 3, "group_index": 2, "description": null, "attributes": { "feeling": "sorrow" } }, { "extraction_class": "relationship", "extraction_text": "her heart aching for Romeo", "char_interval": { "start_pos": 42, "end_pos": 68 }, "alignment_status": "match_exact", "extraction_index": 4, "group_index": 3, "description": null, "attributes": { "type": "romantic longing" } } ], "text": "Lady Juliet gazed longingly at the stars, her heart aching for Romeo", "document_id": "doc_7a49f9c1" }
テキストの部分からどんなデータを抽出したかを可視化するHTML3が作れます!
https://github.com/google/langextract/blob/v1.0.0/langextract/visualization.py#L537-L608
JSONLがtest_output/ディレクトリ下に保存されているので、パスはディレクトリから指定する必要がありました(ブログから修正済み)

すっげー
OpenTelemetryで覗いたGeminiへの入出力
全容はこちら:
https://gist.github.com/ftnext/b65fdaed9c2bf4bc1eec5d2832b20e49
プロンプト
例は作ってほしいJSONに変換して渡してるんですね
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
Q: ROMEO. But soft! What light through yonder window breaks? It is the east, and Juliet is the sun.
A: {
"extractions": [
{
"character": "ROMEO",
"character_attributes": {
"emotional_state": "wonder"
}
},
{
"emotion": "But soft!",
"emotion_attributes": {
"feeling": "gentle awe"
}
},
{
"relationship": "Juliet is the sun",
"relationship_attributes": {
"type": "metaphor"
}
}
]
}
Q: Lady Juliet gazed longingly at the stars, her heart aching for Romeo
A:
Geminiからの出力
JSON返してる!
{
"extractions": [
{
"character": "Lady Juliet",
"character_attributes": {
"emotional_state": "longing"
}
},
{
"emotion": "gazed longingly",
"emotion_attributes": {
"feeling": "yearning"
}
},
{
"emotion": "her heart aching",
"emotion_attributes": {
"feeling": "sorrow"
}
},
{
"relationship": "her heart aching for Romeo",
"relationship_attributes": {
"type": "romantic longing"
}
}
]
}
終わりに
LangExtractを触りました。
これまでgoogle-genaiを使ってテキストから構造化はできましたが、大量のテキストデータで構造化というユースケース向けにLangExtractが提案されたのかなと思われます。
画像やPDFから抽出できると私はさらに嬉しいですが、現状はMarkItDownなどでテキスト化してからLangExtractに渡す形になりそうですね(今後LangExtractだけで完結したら、すごい!)