模块二,Agent知识图谱的工具链思考

📋 本文目录


一、前言

1.1 简化实现的知识图谱

为了降低学习门槛,本模块使用字典模拟知识图谱,无需安装 Neo4j 等外部数据库。虽然简单,但核心概念是一样的:实体、关系、查询。

1.2 你将学到什么?

  • ✅ 实现知识抽取工具

  • ✅ 实现图谱构建工具

  • ✅ 实现知识查询工具

  • ✅ 实现图谱管理工具


二、工具概览

2.1 4个工具

工具 功能
知识抽取器 从文本抽取实体和关系
图谱构建器 构建和更新知识图谱
知识查询器 基于图谱查询知识
图谱管理器 管理和导出图谱

2.2 文件结构

复制代码
08_knowledge_graph/
├── shared_graph_store.py      # 共享存储
├── tool_1_knowledge_extractor.py
├── tool_2_graph_builder.py
├── tool_3_graph_query.py
├── tool_4_graph_manager.py
├── knowledge_graph_demo.py    # 工具链演示
├── knowledge_graph_agent.py   # Agent演示
└── sample_texts.json          # 示例数据

三、工具详解

3.1 知识抽取器

功能说明:从文本中抽取实体和关系,支持两种风格:简单抽取(实体+关系)和丰富抽取(带类型和属性)。

3.2 完整代码

复制代码
from langchain.tools import tool
import sys
import os

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from shared_graph_store import add_entity, add_relation, add_comparison


@tool
def knowledge_extractor(text: str, extract_style: str = "simple"):
    """知识抽取器 - 从文本中抽取实体和关系

    参数:
        text: 要抽取知识的文本
        extract_style: 抽取风格 (simple/rich)

    返回:
        抽取结果
    """
    from langchain_openai import ChatOpenAI
    from langchain_core.prompts import ChatPromptTemplate

    # 初始化LLM
    try:
        llm = ChatOpenAI(
            base_url="http://localhost:11434/v1",
            api_key="ollama",
            model="qwen2.5:3b-instruct",
            temperature=0.7
        )
    except Exception as e:
        return f"[ERROR] LLM初始化失败: {e}"

    # 不同抽取风格的提示
    if extract_style == "simple":
        prompt = ChatPromptTemplate.from_messages([
            ("system", """你是一个知识抽取专家。请从给定文本中抽取实体和关系。

请用以下格式输出:

【实体】
- 实体1
- 实体2
- 实体3

【关系】
- 实体1 -[关系]-> 实体2
- 实体2 -[关系]-> 实体3

只抽取明确的关系,不要添加推测内容。"""),
            ("user", "文本:{text}")
        ])
    else:
        prompt = ChatPromptTemplate.from_messages([
            ("system", """你是一个知识抽取专家。请从给定文本中抽取尽可能多的实体和关系。

请用以下格式输出:

【实体】
- 实体1(类型:人物/地点/事物等)
- 实体2(类型:人物/地点/事物等)

【关系】
- 实体1 -[关系类型]-> 实体2
- 实体2 -[关系类型]-> 实体3

【属性】
- 实体1: 属性1=值1, 属性2=值2

请尽量详细地抽取信息。"""),
            ("user", "文本:{text}")
        ])

    chain = prompt | llm
    result = chain.invoke({"text": text})

    output = []
    output.append("=" * 80)
    output.append("【知识抽取器】")
    output.append("=" * 80)
    output.append(f"\n原始文本:{text[:100]}..." if len(text) > 100 else f"\n原始文本:{text}")
    output.append(f"抽取风格:{extract_style}")
    output.append("\n" + "=" * 80)
    output.append("【抽取结果】")
    output.append("=" * 80)
    output.append(result.content)
    output.append("\n" + "=" * 80)
    output.append("[TIP] 抽取的知识可以用于构建知识图谱")
    output.append("=" * 80)

    return "\n".join(output)

3.3 使用示例

复制代码
test_text = "小明是一名28岁的软件工程师,他在北京工作,喜欢吃苹果。"
result = knowledge_extractor.invoke({"text": test_text, "extract_style": "simple"})
print(result)

3.2 图谱构建器

功能说明:构建和更新知识图谱,支持两种模式:直接模式(使用示例数据)和文本模式(从文本解析)。

完整代码

复制代码
from langchain.tools import tool
import sys
import os

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from shared_graph_store import add_entity, add_relation, get_entity, get_all_entities, get_all_relations


@tool
def graph_builder(entities_text: str = None, relations_text: str = None, direct_mode: bool = False):
    """图谱构建器 - 构建和更新知识图谱

    参数:
        entities_text: 实体文本(每行一个实体)
        relations_text: 关系文本(每行格式: 实体1,关系,实体2)
        direct_mode: 直接模式(直接解析预定义的简单文本)

    返回:
        构建结果
    """
    output = []
    output.append("=" * 80)
    output.append("【图谱构建器】")
    output.append("=" * 80)

    if direct_mode:
        # 直接模式:使用简单的示例数据
        output.append("\n使用直接模式构建示例图谱...")

        # 添加示例实体
        sample_entities = ["小明", "北京", "软件工程师", "苹果"]
        for entity in sample_entities:
            add_entity(entity)
        output.append(f"  [OK] 添加了 {len(sample_entities)} 个实体")

        # 添加示例关系
        sample_relations = [
            ("小明", "工作于", "北京"),
            ("小明", "职业是", "软件工程师"),
            ("小明", "喜欢吃", "苹果")
        ]
        for source, relation, target in sample_relations:
            add_relation(source, target, relation)
        output.append(f"  [OK] 添加了 {len(sample_relations)} 个关系")

    elif entities_text or relations_text:
        # 从文本构建
        if entities_text:
            output.append("\n从文本添加实体...")
            entities = [e.strip() for e in entities_text.split("\n") if e.strip()]
            for entity in entities:
                add_entity(entity)
            output.append(f"  [OK] 添加了 {len(entities)} 个实体")

        if relations_text:
            output.append("\n从文本添加关系...")
            lines = [l.strip() for l in relations_text.split("\n") if l.strip()]
            added = 0
            for line in lines:
                parts = line.split(",")
                if len(parts) >= 3:
                    source, relation, target = parts[0].strip(), parts[1].strip(), parts[2].strip()
                    add_relation(source, target, relation)
                    added += 1
            output.append(f"  [OK] 添加了 {added} 个关系")

    else:
        output.append("\n请提供实体或关系数据,或使用 direct_mode=True 构建示例")

    # 显示当前图谱摘要
    output.append("\n" + "=" * 80)
    entities = get_all_entities()
    relations = get_all_relations()
    output.append(f"【当前图谱】实体: {len(entities)} 个, 关系: {len(relations)} 个")

    if entities:
        output.append("\n实体列表:")
        for entity in entities:
            output.append(f"  - {entity['name']}")

    if relations:
        output.append("\n关系列表:")
        for rel in relations:
            output.append(f"  - {rel['source']} -[{rel['relation']}]-> {rel['target']}")

    output.append("\n" + "=" * 80)
    output.append("[TIP] 构建好的图谱可以用于知识查询")
    output.append("=" * 80)

    return "\n".join(output)

4.3 使用示例

复制代码
result = graph_builder.invoke({"direct_mode": True})
print(result)

3.3 知识查询器

功能说明:基于知识图谱回答问题,支持关键词匹配查询。答案可追溯,因为你可以看到具体用了哪些实体和关系。

完整代码

复制代码
from langchain.tools import tool
import sys
import os

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from shared_graph_store import get_entity, get_relations, get_all_entities, get_all_relations


@tool
def graph_query(question: str, query_mode: str = "simple"):
    """知识查询器 - 基于知识图谱回答问题

    参数:
        question: 要查询的问题
        query_mode: 查询模式 (simple/advanced)

    返回:
        查询结果
    """
    output = []
    output.append("=" * 80)
    output.append("【知识查询器】")
    output.append("=" * 80)
    output.append(f"\n问题:{question}")
    output.append(f"查询模式:{query_mode}")
    output.append("\n" + "=" * 80)

    entities = get_all_entities()
    relations = get_all_relations()

    if not entities and not relations:
        output.append("【查询结果】")
        output.append("图谱中暂无知识,请先使用图谱构建器添加知识")
        output.append("=" * 80)
        return "\n".join(output)

    output.append("【查询结果】")
    output.append("=" * 80)

    # 简单查询:关键词匹配
    found_entities = []
    for entity in entities:
        if entity["name"] in question:
            found_entities.append(entity)

    found_relations = []
    for rel in relations:
        if rel["source"] in question or rel["target"] in question or rel["relation"] in question:
            found_relations.append(rel)

    if found_entities or found_relations:
        if found_entities:
            output.append("\n找到相关实体:")
            for entity in found_entities:
                output.append(f"  - {entity['name']}")

        if found_relations:
            output.append("\n找到相关关系:")
            for rel in found_relations:
                output.append(f"  - {rel['source']} -[{rel['relation']}]-> {rel['target']}")

        # 尝试回答问题
        output.append("\n基于图谱的回答:")
        if "小明" in question and ("工作" in question or "哪里" in question):
            output.append("  小明在北京工作")
        elif "小明" in question and "职业" in question:
            output.append("  小明的职业是软件工程师")
        elif "小明" in question and "喜欢" in question:
            output.append("  小明喜欢吃苹果")
        else:
            output.append("  可以尝试查询更具体的问题,或查看上述相关知识")

    else:
        output.append("\n在当前图谱中未找到直接相关的知识")
        output.append("\n【当前图谱知识】")
        entity_names = [e["name"] for e in entities]
        relation_strings = [f"{r['source']}-{r['relation']}->{r['target']}" for r in relations]
        output.append(f"实体: {entity_names}")
        output.append(f"关系: {relation_strings}")

    output.append("\n" + "=" * 80)
    output.append("[TIP] 知识图谱让回答更准确和可追溯")
    output.append("=" * 80)

    return "\n".join(output)

5.3 使用示例

复制代码
from tool_2_graph_builder import graph_builder
graph_builder.invoke({"direct_mode": True})

result = graph_query.invoke({"question": "小明在哪里工作?", "query_mode": "simple"})
print(result)

3.4 图谱管理器

功能说明:管理知识图谱:查看内容、获取摘要、清空、导出。

完整代码

复制代码
from langchain.tools import tool
import sys
import os
import json

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from shared_graph_store import (
    get_all_entities, get_all_relations, get_all_comparisons,
    clear_graph_store, format_graph_summary
)


@tool
def graph_manager(command: str, data: dict = None):
    """图谱管理器 - 管理和导出知识图谱

    参数:
        command: 命令类型 (list/summary/clear/export)
        data: 相关数据

    返回:
        操作结果
    """
    if command == "list":
        # 列出图谱内容
        entities = get_all_entities()
        relations = get_all_relations()

        output = ["=" * 80, "【图谱内容】", "=" * 80]
        output.append(f"\n实体 ({len(entities)}):")
        for entity in entities:
            output.append(f"  - {entity['name']}")
            if entity["attributes"]:
                output.append(f"    属性: {entity['attributes']}")

        output.append(f"\n关系 ({len(relations)}):")
        for rel in relations:
            output.append(f"  - {rel['source']} -[{rel['relation']}]-> {rel['target']}")

        output.append("\n" + "=" * 80)
        return "\n".join(output)

    elif command == "summary":
        # 获取摘要
        return format_graph_summary()

    elif command == "clear":
        # 清空
        clear_graph_store()
        return "[OK] 已清空知识图谱"

    elif command == "export":
        # 导出
        data_to_export = {
            "entities": get_all_entities(),
            "relations": get_all_relations()
        }
        output_file = "output_graph_data.json"
        with open(output_file, "w", encoding="utf-8") as f:
            json.dump(data_to_export, f, ensure_ascii=False, indent=2)
        return f"[OK] 已导出到 {output_file}"

    else:
        return f"[ERROR] 未知命令: {command}\n可用命令: list/summary/clear/export"

6.3 使用示例

复制代码
from tool_2_graph_builder import graph_builder
graph_builder.invoke({"direct_mode": True})

result = graph_manager.invoke({"command": "list"})
print(result)

七、完整实战演示

7.1 工具链演示

我们将4个工具组合成完整的知识图谱流程:

复制代码
from tool_1_knowledge_extractor import knowledge_extractor
from tool_2_graph_builder import graph_builder
from tool_3_graph_query import graph_query
from tool_4_graph_manager import graph_manager

# 步骤1:从文本抽取知识
text = "小红是一名教师,她在上海工作,喜欢喝茶。"
extraction_result = knowledge_extractor.invoke({"text": text, "extract_style": "simple"})
print(extraction_result)

# 步骤2:构建图谱(使用直接模式快速演示)
build_result = graph_builder.invoke({"direct_mode": True})
print(build_result)

# 步骤3:查询知识
query_result = graph_query.invoke({"question": "小明的职业是什么?", "query_mode": "simple"})
print(query_result)

# 步骤4:管理图谱
summary = graph_manager.invoke({"command": "summary"})
print(summary)

四、实战案例

4.1 工具链演示

运行完整的工具链演示:

复制代码
cd 08_knowledge_graph
python knowledge_graph_demo.py

4.2 工具功能对比表

工具 核心功能 适用场景 优势
知识抽取器 从文本抽取实体和关系 文本处理 自动化提取
图谱构建器 构建和更新知识图谱 知识存储 结构化管理
知识查询器 基于图谱回答问题 知识检索 可追溯
图谱管理器 管理和导出图谱 运维管理 便于维护

4.3 实际应用案例

案例1:从文本抽取知识

文本:小明是一名28岁的软件工程师,他在北京工作,喜欢吃苹果。

抽取结果

复制代码
【实体】
- 小明(人物)
- 北京(地点)
- 苹果(物品)

【关系】
- 小明 -[职业]-> 软件工程师
- 小明 -[工作地点]-> 北京
- 小明 -[喜欢]-> 苹果

代码调用

复制代码
from tool_1_knowledge_extractor import knowledge_extractor

test_text = "小明是一名28岁的软件工程师,他在北京工作,喜欢吃苹果。"
result = knowledge_extractor.invoke({
    "text": test_text,
    "extract_style": "simple"
})
print(result)
案例2:构建知识图谱

代码调用

复制代码
from tool_2_graph_builder import graph_builder

# 使用直接模式构建示例图谱
result = graph_builder.invoke({"direct_mode": True})
print(result)

# 构建后的图谱结构:
# 小明 -[职业]-> 软件工程师
# 小明 -[工作地点]-> 北京
# 小红 -[职业]-> 教师
# 小红 -[工作地点]-> 上海
案例3:基于图谱查询

查询问题:小明在哪里工作?

查询过程

复制代码
【查询分析】
问题涉及实体:小明
需要查找的关系:工作地点

【查询路径】
小明 -> 工作地点 -> 北京

【答案】
小明在北京工作。

代码调用

复制代码
from tool_3_graph_query import graph_query

result = graph_query.invoke({
    "question": "小明在哪里工作?",
    "query_mode": "simple"
})
print(result)

五、工具链整合

5.1 知识图谱工具链架构

复制代码
文本输入
    ↓
[知识抽取器] 抽取实体和关系
    ↓
[图谱构建器] 构建知识图谱
    ↓
[知识查询器] 基于图谱回答问题
    ↓
[图谱管理器] 管理和维护图谱

5.2 工具协作流程

步骤 工具 作用
1 知识抽取器 从文本提取结构化知识
2 图谱构建器 存储到图谱中
3 知识查询器 回答用户问题
4 图谱管理器 维护图谱数据

六、总结

知识图谱

工具 核心能力 价值
✅ 知识抽取器 从文本抽取实体和关系 自动化提取
✅ 图谱构建器 构建知识图谱 结构化存储
✅ 知识查询器 基于图谱回答问题 可追溯
✅ 图谱管理器 管理图谱生命周期 便于维护

6.2 学习路径建议

阶段 任务 目标
基础 理解知识图谱概念 掌握核心原理
进阶 使用工具构建小型图谱 实践操作
高级 集成到完整Agent 实现智能问答

点赞 + 关注,更新不迷路!🚀

相关推荐
lauo1 小时前
ibbot手机发布:搭载poplang技术 + token节点经济,革新AI手机体验
人工智能·智能手机
咖啡星人k1 小时前
云端开发环境技术架构深度解析:从容器隔离到AI Agent集成
人工智能·架构
袋鼠云数栈1 小时前
从前端到基础设施,ACOS 如何打通企业全链路可观测
运维·前端·人工智能·数据治理·数据智能
piao9618271 小时前
企业级AIOT方案落地实践:2026年线下销售过程管理AI硬件推荐
人工智能·语音识别
智写-AI1 小时前
Turnitin vs GPTZero vs ZeroGPT:三大英文AI检测平台如何选择?
人工智能·aigc·ai写作·ai自动写作
Litluecat2 小时前
2026年6月1日科技热点新闻
大数据·人工智能·科技·推荐·热点·新闻·每日
志栋智能2 小时前
AI驱动无代码:降低巡检超自动化的门槛
大数据·运维·网络·人工智能·自动化
qcx232 小时前
【系统学AI】25 论文导读 ①:两篇改变 AI 的开山之作——Attention Is All You Need & ReAct
前端·人工智能·react.js·transformer
Black蜡笔小新2 小时前
自动化AI算法训练服务器DLTM制造业AI质检工作站助力制造业实现AI智检
人工智能·算法·自动化