问题背景与适用场景
在构建企业级知识图谱问答系统时,传统 RAG(检索增强生成)常面临多跳推理能力不足、跨文档关联缺失的问题。GraphRAG 通过将文本实体与关系建模为图结构,显著提升了复杂查询的准确性。本指南详解如何基于 HolySheep AI API 实现完整的 GraphRAG 流程,涵盖实体抽取、图谱构建与智能查询路由三大核心模块。
前置条件
- 已注册 HolySheep 账号并获取 API Key(支持 GPT-4o、Claude-3.5 等多模型)
- Python 3.10+ 环境,建议使用虚拟环境管理依赖
- 具备基础 NLP 知识:命名实体识别(NER)、关系抽取概念
- 准备待处理的文档语料(支持 TXT、PDF、Markdown 格式)
- 安装必要的 Python 库:networkx、openai、langchain-community
配置步骤详解
步骤 1:安装依赖并配置 API 客户端
首先初始化项目结构,配置与 HolySheep 的连接参数。使用环境变量或配置文件管理 API Key 避免硬编码风险。
步骤 2:实现实体抽取模块
利用 LLM 的零样本能力进行实体识别,通过 prompt 工程引导模型输出结构化 JSON 格式的实体与关系列表。
步骤 3:构建知识图谱
将抽取的实体与关系存入图数据库(使用 NetworkX 作为内存图),支持后续的图遍历与社区检测。
步骤 4:实现查询路由
根据用户 query 的复杂度自动选择检索策略:简单问题走向量检索,复杂多跳问题走图遍历。
import os
import json
import networkx as nx
from openai import OpenAI
from typing import List, Dict, Tuple
配置 HolySheep API
client = OpenAI(
api_key=os.environ.get("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY"),
base_url="https://api.holysheep.ai/v1"
)
class EntityExtractor:
"""基于 HolySheep LLM 的实体抽取器"""
SYSTEM_PROMPT = """你是一个专业的知识图谱工程师,负责从文本中抽取实体和关系。
输出格式为严格的 JSON,包含 'entities' 和 'relations' 两个数组。
实体包含: id, name, type (PERSON/ORG/LOCATION/EVENT/CONCEPT)
关系包含: source, target, relation_type"""
EXTRACT_PROMPT = """从以下文本中抽取所有实体和关系:
{text}
只输出 JSON,不要包含任何解释。"""
def __init__(self, model: str = "gpt-4o"):
self.client = client
self.model = model
def extract(self, text: str) -> Dict:
"""执行实体抽取"""
response = self.client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": self.SYSTEM_PROMPT},
{"role": "user", "content": self.EXTRACT_PROMPT.format(text=text)}
],
temperature=0.1,
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
class KnowledgeGraph:
"""基于 NetworkX 的知识图谱构建器"""
def __init__(self):
self.graph = nx.MultiDiGraph()
def add_entities(self, entities: List[Dict]):
"""添加实体到图谱"""
for entity in entities:
self.graph.add_node(
entity["id"],
name=entity["name"],
entity_type=entity["type"]
)
def add_relations(self, relations: List[Dict]):
"""添加关系到图谱"""
for rel in relations:
self.graph.add_edge(
rel["source"],
rel["target"],
relation_type=rel["relation_type"]
)
def get_subgraph(self, center_node: str, depth: int = 2) -> nx.MultiDiGraph:
"""获取指定节点周围深度的子图"""
return nx.ego_graph(self.graph, center_node, radius=depth)
def community_detection(self) -> List[List[str]]:
"""基于 Louvain 算法的社区检测"""
undirected = self.graph.to_undirected()
communities = nx.community.louvain_communities(undirected)
return [list(c) for c in communities]
完整代码示例
以下示例展示完整的 GraphRAG 流程:从文档处理到图谱查询的端到端实现。
安装依赖
pip install openai networkx langchain-community python-dotenv
设置环境变量
export HOLYSHEEP_API_KEY="YOUR_HOLYSHEEP_API_KEY"
运行完整示例(保存为 run_graphrag.py)
python run_graphrag.py --documents ./data/*.txt --query "公司的核心技术团队有哪些成员?"
import argparse
from entity_extractor import EntityExtractor, KnowledgeGraph
class QueryRouter:
"""智能查询路由:根据查询复杂度选择检索策略"""
ROUTING_PROMPT = """分析以下查询的复杂度:
"{query}"
如果是多跳推理、比较分析或需要综合多个实体的问题,返回 "graph"
如果是简单的事实查询,返回 "vector"
只输出一个词:graph 或 vector。"""
def __init__(self):
self.client = client
self.model = "gpt-4o"
def route(self, query: str) -> str:
"""决定检索策略"""
response = self.client.chat.completions.create(
model=self.model,
messages=[
{"role": "user", "content": self.ROUTING_PROMPT.format(query=query)}
],
temperature=0
)
return response.choices[0].message.content.strip()
def graph_retrieval(self, kg: KnowledgeGraph, query: str, top_k: int = 5):
"""图谱检索:提取相关实体并获取子图"""
extractor = EntityExtractor()
result = extractor.extract(query)
relevant_nodes = []
for entity in result.get("entities", []):
if entity["name"] in kg.graph:
relevant_nodes.append(entity["id"])
# 聚合多跳范围内的所有节点
subgraph_nodes = set()
for node in relevant_nodes:
ego_graph = kg.get_subgraph(node, depth=2)
subgraph_nodes.update(ego_graph.nodes())
subgraph = kg.graph.subgraph(subgraph_nodes)
return self._graph_to_context(subgraph)
def _graph_to_context(self, subgraph: nx.MultiDiGraph) -> str:
"""将子图转换为文本上下文"""