| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- """Info Extractor - 使用示例.
- 演示如何使用 InfoExtractor 从文章中提取结构化信息。
- 用法:
- # 设置 API 密钥(支持 OpenAI 格式的任何模型)
- set OPENAI_API_KEY=sk-xxx
- # 或使用第三方服务
- set OPENAI_API_KEY=your-key
- set OPENAI_BASE_URL=https://api.deepseek.com/v1
- # 运行
- python main.py # 默认: single_phase 模式
- python main.py two_phase # 两阶段模式
- python main.py --debug # 开启 debug 日志 (打印每次 LLM 交互的 prompt)
- python main.py two_phase --debug # 组合使用
- set DEBUG=true && python main.py # 通过环境变量开启 debug
- """
- from __future__ import annotations
- import json
- import logging
- import os
- import sys
- from src.extractor import InfoExtractor
- logging.basicConfig(
- level=logging.INFO,
- format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
- )
- logger = logging.getLogger(__name__)
- # ── 示例数据 ──────────────────────────────────────────────────────────────────
- SAMPLE_ARTICLE = (
- "2026年6月1日晚8点,好友们决定为王若飞(男)组织一场生日派对。"
- "这次小范围聚会共有5人参加,刘阳(女)作为总策划,"
- "除寿星和总策划外,还有李四(女)、王五(男)和赵六(男)参加。"
- "活动总预算为3000元,且已完成备案,"
- "现场安排了掷骰子、扔飞镖和打桌球等破冰游戏,确保大家玩得尽兴。"
- )
- SAMPLE_DEFINITION = {
- "metadata": {
- "node_label": "PDJH",
- "node_name": "派对计划",
- "node_type": "concept",
- },
- "subnodes": {
- "JBXX": {
- "metadata": {
- "node_label": "JBXX",
- "node_name": "基本信息",
- "node_type": "concept",
- },
- "subnodes": {
- "PDMC": {
- "metadata": {
- "node_label": "PDMC",
- "node_name": "派对名称",
- "node_type": "property",
- "value_type": "string",
- "is_list": False,
- }
- },
- "PDKSSJ": {
- "metadata": {
- "node_label": "PDKSSJ",
- "node_name": "派对开始时间",
- "node_type": "property",
- "value_type": "date_time",
- "is_list": False,
- }
- },
- "PDZRS": {
- "metadata": {
- "node_label": "PDZRS",
- "node_name": "派对总人数",
- "node_type": "property",
- "value_type": "integer",
- "is_list": False,
- }
- },
- "PDZYS": {
- "metadata": {
- "node_label": "PDZYS",
- "node_name": "派对总预算",
- "node_type": "property",
- "value_type": "float",
- "is_list": False,
- }
- },
- "SFBA": {
- "metadata": {
- "node_label": "SFBA",
- "node_name": "是否备案",
- "node_type": "property",
- "value_type": "boolean",
- "is_list": False,
- }
- },
- },
- },
- "RYXX": {
- "metadata": {
- "node_label": "RYXX",
- "node_name": "人员信息",
- "node_type": "concept",
- },
- "subnodes": {
- "ZCH": {
- "metadata": {
- "node_label": "ZCH",
- "node_name": "总策划",
- "node_type": "property",
- "value_type": "class",
- "is_list": False,
- },
- "subnodes": {
- "XM": {
- "metadata": {
- "node_label": "XM",
- "node_name": "姓名",
- "node_type": "property",
- "value_type": "string",
- "is_list": False,
- }
- },
- "XB": {
- "metadata": {
- "node_label": "XB",
- "node_name": "性别",
- "node_type": "property",
- "value_type": "string",
- "is_list": False,
- }
- },
- },
- },
- "RYQD": {
- "metadata": {
- "node_label": "RYQD",
- "node_name": "人员清单",
- "node_type": "property",
- "value_type": "class",
- "is_list": True,
- },
- "subnodes": {
- "XM": {
- "metadata": {
- "node_label": "XM",
- "node_name": "姓名",
- "node_type": "property",
- "value_type": "string",
- "is_list": False,
- }
- },
- "XB": {
- "metadata": {
- "node_label": "XB",
- "node_name": "性别",
- "node_type": "property",
- "value_type": "string",
- "is_list": False,
- }
- },
- },
- },
- },
- },
- "HDXX": {
- "metadata": {
- "node_label": "HDXX",
- "node_name": "活动信息",
- "node_type": "concept",
- },
- "subnodes": {
- "PBYXQD": {
- "metadata": {
- "node_label": "PBYXQD",
- "node_name": "破冰游戏清单",
- "node_type": "property",
- "value_type": "string",
- "is_list": True,
- }
- }
- },
- },
- },
- }
- def main() -> None:
- # 初始化提取器
- # 方式 1: 使用环境变量(OPENAI_API_KEY, OPENAI_BASE_URL)
- # 方式 2: 直接传入参数
- extractor = InfoExtractor(
- model_name=os.getenv("MODEL_NAME", "gpt-4o"),
- api_key=os.getenv("OPENAI_API_KEY"),
- base_url=os.getenv("OPENAI_BASE_URL"),
- temperature=0,
- max_retries=3,
- )
- # 解析命令行参数
- args = sys.argv[1:]
- mode = "single_phase"
- debug = os.getenv("DEBUG", "").lower() in ("1", "true", "yes")
- for arg in args:
- if arg == "--debug":
- debug = True
- elif arg in ("single_phase", "two_phase"):
- mode = arg
- logger.info(f"使用 {mode} 模式提取信息 (debug={debug})")
- # 执行提取(含标注)
- result = extractor.extract(
- article=SAMPLE_ARTICLE,
- definition=SAMPLE_DEFINITION,
- mode=mode,
- annotate=True,
- debug=debug,
- )
- # 输出提取结果
- print("\n" + "=" * 60)
- print("提取结果:")
- print("=" * 60)
- print(json.dumps(result["instance"], ensure_ascii=False, indent=2))
- # 输出标注后的文章
- print("\n" + "=" * 60)
- print("标注后的文章:")
- print("=" * 60)
- print(result["annotated_text"])
- if __name__ == "__main__":
- main()
|