1. 案例目标
本案例展示了如何使用LlamaCloud套件和Neo4j构建知识图谱,将非结构化的法律文档转换为结构化的知识表示。通过结合LlamaParse、LlamaClassify和LlamaExtract等工具,实现从原始文档到可查询知识图谱的完整流程。
主要目标包括:
- 使用LlamaClassify对合同进行分类(联盟协议或品牌合作协议)
- 利用LlamaExtract从不同类型的合同中提取相关属性
- 将所有结构化信息存储到Neo4j知识图谱中
- 创建一个端到端的工作流程,实现文档处理的自动化
2. 技术栈与核心依赖
LlamaIndex
LlamaCloud Services
Neo4j
OpenAI
Pydantic
Async Programming
核心依赖库:
llama-index-workflows llama-cloud-services jsonschema openai neo4j llama-index-llms-openaiLlamaCloud服务组件:
- LlamaParse:用于解析PDF文档
- LlamaClassify:用于文档分类(目前处于测试阶段)
- LlamaExtract:用于从文档中提取结构化信息
3. 环境配置
API密钥配置
os.environ["LLAMA_CLOUD_API_KEY"] = "your-llama-api-key" os.environ["OPENAI_API_KEY"] = "your-openai-api-key"Neo4j数据库配置
db_url = "your-db-url" username = "neo4j" password = "your-password" neo4j_driver = AsyncGraphDatabase.driver( db_url, auth=(username, password), )推荐使用免费的Aura数据库实例进行设置。
4. 案例实现
4.1 数据准备
从Cuad数据集下载示例PDF合同文档:
!wget https://raw.githubusercontent.com/tomasonjo/blog-datasets/main/CybergyHoldingsInc_Affliate%20Agreement.pdf4.2 文档解析
使用LlamaParse解析PDF文档:
parser = LlamaParse(parse_mode="parse_page_without_llm") pdf_path = "CybergyHoldingsInc_Affliate Agreement.pdf" results = await parser.aparse(pdf_path)4.3 合同分类
定义分类规则并使用LlamaClassify对合同进行分类:
rules = [ ClassifierRule( type="Affiliate Agreements", description="This is a contract that outlines an affiliate agreement", ), ClassifierRule( type="Co Branding", description="This is a contract that outlines a co-branding deal/agreement", ), ] classifier = ClassifyClient( client=AsyncLlamaCloud( base_url="https://api.cloud.llamaindex.ai", token=os.environ["LLAMA_CLOUD_API_KEY"], ) ) result = await classifier.aclassify_file_path( rules=rules, file_input_path="/content/CybergyHoldingsInc_Affliate Agreement.pdf", )4.4 信息提取
为不同类型的合同定义Pydantic模型,并使用LlamaExtract提取结构化信息:
class BaseContract(BaseModel): """Base contract class with common fields.""" parties: Optional[List[Party]] = Field(None, description="All contracting parties") agreement_date: Optional[str] = Field(None, description="Contract signing date. Use YYYY-MM-DD") effective_date: Optional[str] = Field(None, description="When contract becomes effective. Use YYYY-MM-DD") # ... 其他字段 class AffiliateAgreement(BaseContract): """Affiliate Agreement extraction.""" exclusivity: Optional[str] = Field(None, description="Exclusive territory or market rights") non_compete: Optional[str] = Field(None, description="Non-compete restrictions") # ... 其他特定字段 # 根据分类结果选择相应的提取模式 extractor = LlamaExtract() agent = extractor.create_agent( name=f"extraction_workflow_import_{uuid.uuid4()}", data_schema=mapping[classification.type], config=ExtractConfig(extraction_mode=ExtractMode.BALANCED), ) result = await agent.aextract( files=SourceText( text_content=" ".join([el.text for el in results.pages]), filename=pdf_path, ), )4.5 知识图谱构建
将提取的结构化信息导入Neo4j知识图谱:
import_query = """ WITH $contract AS contract MERGE (c:Contract {path: $path}) SET c += apoc.map.clean(contract, ["parties", "agreement_date", "effective_date", "expiration_date"], []) // Cast to date SET c.agreement_date = date(contract.agreement_date), c.effective_date = date(contract.effective_date), c.expiration_date = date(contract.expiration_date) // Create parties with their locations WITH c, contract UNWIND coalesce(contract.parties, []) AS party MERGE (p:Party {name: party.name}) MERGE (c)-[:HAS_PARTY]->(p) // Create location nodes and link to parties WITH p, party WHERE party.location IS NOT NULL MERGE (p)-[:HAS_LOCATION]->(l:Location) SET l += party.location """ response = await neo4j_driver.execute_query( import_query, contract=result.data, path=pdf_path )4.6 工作流程整合
使用LlamaIndex Workflow API将所有步骤整合为一个端到端的工作流程:
class KnowledgeGraphBuilder(Workflow): def __init__( self, classifier: ClassifyClient, rules: List[ClassifierRule], affiliate_extract_agent: LlamaExtract, cobranding_extract_agent: LlamaExtract, **kwargs, ): super().__init__(**kwargs) self.classifier = classifier self.rules = rules self.affiliate_extract_agent = affiliate_extract_agent self.cobranding_extract_agent = cobranding_extract_agent @step async def classify_contract( self, ctx: Context, ev: StartEvent ) -> ExtractAffiliate | ExtractCoBranding | StopEvent: result = await self.classifier.aclassify_file_path( rules=self.rules, file_input_path=ev.pdf_path ) contract_type = result.items[0].result.type print(contract_type) if contract_type == "affiliate_agreements": return ExtractAffiliate(file_path=ev.pdf_path) elif contract_type == "co_branding": return ExtractCoBranding(file_path=ev.pdf_path) else: return StopEvent() # ... 其他步骤方法 # 运行工作流程 knowledge_graph_builder = KnowledgeGraphBuilder( classifier=classifier, rules=rules, affiliate_extract_agent=affiliate_extraction_agent, cobranding_extract_agent=cobranding_extraction_agent, timeout=None, verbose=True, ) response = await knowledge_graph_builder.run( pdf_path="CybergyHoldingsInc_Affliate Agreement.pdf" )5. 案例效果
该案例实现了从原始PDF文档到结构化知识图谱的完整转换流程,具体效果包括:
- 成功解析PDF合同文档,提取文本内容
- 准确识别合同类型(联盟协议或品牌合作协议)
- 根据合同类型提取相应的结构化信息,包括合同方、日期、条款等
- 在Neo4j中构建包含合同、合同方和位置节点的知识图谱
- 建立节点之间的关系,如合同与合同方的关联、合同方与位置的关联
- 通过工作流程实现整个处理流程的自动化
提取的示例数据包括:
- 合同方信息:Birch First Global Investments Inc.和Mount Knowledge Holdings Inc.
- 合同日期:2014年5月8日
- 管辖法律:内华达州
- 收入分享:根据年度购买水平提供15%-25%的购买折扣
- 最低承诺:前六个月内购买至少100个单位
6. 案例实现思路
本案例的实现思路遵循了典型的知识图谱构建流程,将非结构化文档转换为结构化知识表示:
6.1 数据处理流程
- 文档解析:使用LlamaParse将PDF文档转换为可处理的文本内容
- 文档分类:利用LlamaClassify识别文档类型,为后续提取提供上下文
- 信息提取:根据文档类型使用相应的Pydantic模型提取结构化信息
- 知识图谱构建:将提取的信息转换为Neo4j中的节点和关系
6.2 技术架构
案例采用分层架构设计:
- 数据层:PDF文档作为原始数据源
- 处理层:LlamaCloud服务提供解析、分类和提取功能
- 存储层:Neo4j作为知识图谱存储和查询引擎
- 流程层:LlamaIndex Workflow API整合各组件为端到端流程
6.3 关键设计决策
- 异步编程:全面采用异步编程模式提高处理效率
- 类型安全:使用Pydantic模型确保数据提取的结构化和类型安全
- 模块化设计:将不同功能分离为独立组件,提高可维护性
- 动态模式选择:根据文档分类结果动态选择相应的提取模式
7. 扩展建议
1. 扩展文档类型支持
添加更多合同类型的分类规则和提取模式,如保密协议(NDA)、服务协议(SLA)、采购协议等。
2. 增强关系提取
除了提取实体属性外,进一步提取实体间的关系,如公司间的投资关系、人员任职关系等。
3. 集成向量检索
将知识图谱与向量检索结合,实现基于语义相似度和图结构的混合检索。
4. 添加时间维度
增强对合同时间相关信息的处理,如有效期、续约条件、里程碑事件等。
5. 实现问答系统
基于构建的知识图谱开发智能问答系统,支持自然语言查询合同信息。
6. 可视化界面
开发Web界面,支持文档上传、处理进度跟踪和知识图谱可视化。
7. 批量处理能力
优化系统以支持大规模文档批量处理,提高处理效率和可扩展性。
8. 总结
本案例展示了如何利用LlamaCloud服务和Neo4j构建知识图谱的完整流程,实现了从非结构化文档到结构化知识表示的转换。通过结合LlamaParse、LlamaClassify和LlamaExtract等工具,以及LlamaIndex Workflow API,创建了一个端到端的文档处理工作流程。
该案例的价值在于:
- 提供了一种将法律文档转换为可查询知识图谱的实用方法
- 展示了LlamaCloud套件各组件的协同工作方式
- 演示了如何使用工作流API整合多个处理步骤
- 为构建基于知识图谱的智能应用提供了基础
这种方法可以扩展到其他领域,如医疗记录分析、科研论文处理、技术文档管理等,为各种非结构化文档的智能化处理提供了参考框架。