4. 知识图谱辅助的大模型推理增强
任务说明
本案例构建一个知识图谱辅助的大模型推理增强系统。系统接收用户自然语言问题,通过命名实体识别与关系映射,从知识图谱中检索相关事实三元组,将检索结果拼接为上下文提示词,调用大模型生成最终答案。目标是通过外部结构化知识弥补大模型参数化知识的不足,提升事实性问题的回答准确率。
系统架构
核心实现
以下代码实现了一个最小可运行的完整闭环:内置小型知识图谱(以Python字典模拟三元组存储),通过基于规则的关键词匹配完成实体识别与关系映射,检索返回匹配的三元组,构造增强提示词后调用大模型API(以兼容接口为例)。
# kg_enhanced_llm.py
"""知识图谱辅助的大模型推理增强 - 最小可运行实现"""
import json
from typing import Dict, List, Tuple, Optional
import requests # 需安装: pip install requests
# ---------- 1. 知识图谱存储(以字典模拟三元组) ----------
# 格式: {(head, relation): [tail1, tail2, ...]}
KNOWLEDGE_GRAPH: Dict[Tuple[str, str], List[str]] = {
("周杰伦", "妻子"): ["昆凌"],
("周杰伦", "出生地"): ["中国台湾省新北市"],
("周杰伦", "职业"): ["歌手", "音乐制作人", "演员"],
("昆凌", "职业"): ["演员", "模特"],
("昆凌", "丈夫"): ["周杰伦"],
("中国台湾省新北市", "所属国家"): ["中国"],
}
# ---------- 2. 实体识别与关系映射(基于规则) ----------
# 实体词典: 别名 → 标准实体名
ENTITY_DICT = {
"周杰伦": "周杰伦", "周董": "周杰伦", "杰伦": "周杰伦",
"昆凌": "昆凌", "Hannah": "昆凌",
"新北市": "中国台湾省新北市", "台湾": "中国台湾省新北市",
}
# 关系词典: 自然语言表达 → 标准关系名
RELATION_DICT = {
"妻子": "妻子", "老婆": "妻子", "配偶": "妻子",
"出生地": "出生地", "出生于": "出生地", "哪里出生": "出生地",
"职业": "职业", "做什么": "职业", "工作": "职业",
"丈夫": "丈夫", "老公": "丈夫",
"国家": "所属国家", "哪个国家": "所属国家",
}
def extract_entities_and_relation(question: str) -> Tuple[Optional[str], Optional[str]]:
"""从问题中提取实体和关系"""
entity = None
for alias, std_name in ENTITY_DICT.items():
if alias in question:
entity = std_name
break
relation = None
for expr, std_rel in RELATION_DICT.items():
if expr in question:
relation = std_rel
break
return entity, relation
# ---------- 3. 知识图谱检索 ----------
def query_kg(entity: str, relation: str) -> List[str]:
"""在知识图谱中查询 (entity, relation) 对应的所有tail值"""
return KNOWLEDGE_GRAPH.get((entity, relation), [])
# ---------- 4. 提示词构造 ----------
def build_prompt(question: str, kg_results: List[str]) -> str:
"""将知识图谱检索结果与原始问题拼接为增强提示词"""
if not kg_results:
return f"请回答以下问题:{question}\n(注意:知识库中未找到相关事实,请基于自身知识回答。)"
knowledge_text = ";".join(kg_results)
prompt = f"""请基于以下已知事实回答问题。
已知事实:{knowledge_text}
问题:{question}
请直接给出答案,不要解释过程。"""
return prompt
# ---------- 5. 大模型调用(兼容接口) ----------
def call_llm(prompt: str, api_url: str, : str, model: str = "-turbo") -> str:
"""调用大模型API,返回生成的文本"""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {}"
}
payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.2
}
try:
resp = requests.post(f"{api_url}/chat/completions", headers=headers, json=payload, timeout=30)
resp.raise_for_status()
data = resp.json()
return data["choices"][0]["message"]["content"].strip()
except Exception as e:
return f"[大模型调用失败: {e}]"
# ---------- 6. 主流程 ----------
def kg_enhanced_qa(question: str, api_url: str, : str, model: str = "-turbo") -> Dict:
"""知识图谱增强的问答主流程"""
# 步骤1: 实体识别与关系映射
entity, relation = extract_entities_and_relation(question)
# 步骤2: 知识图谱检索
kg_results = []
if entity and relation:
kg_results = query_kg(entity, relation)
# 步骤3: 构造提示词
prompt = build_prompt(question, kg_results)
# 步骤4: 调用大模型
answer = call_llm(prompt, api_url, , model)
return {
"question": question,
"entity": entity,
"relation": relation,
"kg_results": kg_results,
"prompt": prompt,
"answer": answer
}
# ---------- 7. 演示入口 ----------
if __name__ == "__main__":
# 配置(请替换为真实API信息)
API_URL = "https://api..com/v1" # 或你的兼容端点
= "sk-your-key-here"
test_questions = [
"周杰伦的妻子是谁?",
"昆凌的职业是什么?",
"周杰伦出生在哪里?",
"周杰伦的宠物叫什么?" # 知识图谱中不存在的事实
]
for q in test_questions:
print(f"\n{'='*50}")
print(f"问题: {q}")
result = kg_enhanced_qa(q, API_URL, )
print(f"识别实体: {result['entity']}")
print(f"识别关系: {result['relation']}")
print(f"图谱检索结果: {result['kg_results']}")
print(f"构造的提示词:\n{result['prompt']}")
print(f"模型回答: {result['answer']}")
运行与验证
依赖安装:
pip install requests
运行方式:将代码保存为 kg_enhanced_llm.py,在文件末尾的 __main__ 块中填入真实的API地址与密钥,然后执行:
python kg_enhanced_llm.py
验证方法与判定标准:
- 实体与关系识别验证:观察输出中“识别实体”和“识别关系”字段。对于问题“周杰伦的妻子是谁?”,应分别输出“周杰伦”和“妻子”。若识别为None,说明词典未覆盖该表达,需扩充
ENTITY_DICT或RELATION_DICT。 - 图谱检索验证:对于上述问题,“图谱检索结果”应输出
['昆凌']。对于知识图谱中不存在的事实(如“周杰伦的宠物”),应输出空列表[],此时提示词会包含“知识库中未找到相关事实”的说明。 - 提示词构造验证:检查“构造的提示词”是否包含检索到的知识文本与原始问题,格式正确。
- 端到端验证:配置真实API后运行,观察“模型回答”字段。对于“周杰伦的妻子是谁?”,若模型输出“昆凌”或包含“昆凌”的表述,则判定通过。对于图谱未覆盖的问题,模型应基于自身知识回答,此时回答质量取决于模型本身能力。
预期输出(确定性部分):在不调用大模型的情况下,前三个测试问题的实体识别、关系映射与图谱检索结果可确定如下:
问题: 周杰伦的妻子是谁?
识别实体: 周杰伦
识别关系: 妻子
图谱检索结果: ['昆凌']
问题: 昆凌的职业是什么?
识别实体: 昆凌
识别关系: 职业
图谱检索结果: ['演员', '模特']
问题: 周杰伦出生在哪里?
识别实体: 周杰伦
识别关系: 出生地
图谱检索结果: ['中国台湾省新北市']
问题: 周杰伦的宠物叫什么?
识别实体: 周杰伦
识别关系: None
图谱检索结果: []
以上为代码逻辑直接推出的确定性结果,不涉及模型输出。模型回答部分需配置真实API后实测验证。