← 返回 Semantica 专题首页 🌱 SEMANTICA · COOKBOOK · 入门系列

上下文模块 — 实用指南

Semantica 官方 Cookbook 中文翻译 · 第 19 / 37 篇

📦 semantica 🕸️ 知识图谱 🔎 GraphRAG

Semantica 的 context 模块是让智能体变得"有状态"的那一层。它结合了:

  • 记忆(短期 + 长期),通过 AgentMemory
  • 图谱上下文,通过 ContextGraph
  • 混合检索(向量 + 记忆 + 图谱),通过 ContextRetriever
  • 高层 UX,通过 AgentContext(推荐的入口点)
  • 实体链接,通过 EntityLinker
  • 可扩展性 + 配置,通过 registryconfig

本 notebook 专注于小而可运行的示例,并将导入限定在每个单元格内。

# 安装 semantica 包
!pip install -q semantica

11) 向量存储(用于长期记忆)

VectorStore 可以通过其内部嵌入器生成嵌入。如果你的环境中没有可用的嵌入器,它会回退到随机向量,以便 API 在演示中仍可使用。

# 创建内存向量存储,用于长期记忆
from semantica.vector_store import VectorStore

# 创建内存后端、384 维的向量存储
vs = VectorStore(backend="inmemory", dimension=384)

# 若存在嵌入器,则配置为 fastembed 文本模型
if getattr(vs, "embedder", None) and hasattr(vs.embedder, "set_text_model"):
    vs.embedder.set_text_model(method="fastembed", model_name="BAAI/bge-small-en-v1.5")

# 查看后端类型与维度
vs.backend, vs.dimension

22) 使用 `AgentContext` 快速开始(推荐)

AgentContext 是用户友好的接口,将记忆、向量存储和图谱绑定在一起。如果你传入一个 ContextGraph,系统就可以进行 GraphRAG 风格的检索。

# 通过 AgentContext 绑定向量存储与上下文图谱
from semantica.context import AgentContext, ContextGraph

# 创建上下文图谱
kg = ContextGraph()
# 将向量存储与图谱绑定到 AgentContext
context = AgentContext(vector_store=vs, knowledge_graph=kg)

# 查看默认配置
context.config

33) 存储和检索记忆

单个字符串被视为一条记忆项。你可以通过对元数据友好的参数附加 conversation_iduser_id

# 存储一条记忆项并按其 ID 检索
# 存储带会话与用户元数据的记忆
memory_id = context.store(
    "User prefers short answers about Python.",
    conversation_id="conv_1",
    user_id="user_1",
    metadata={"type": "preference"},
)

# 按记忆 ID 获取记忆内容
context.get_memory(memory_id)
# 再存一条记忆,并基于语义检索相关记忆
# 存储另一条会话记忆
context.store(
    "User is working on Semantica context module examples.",
    conversation_id="conv_1",
    user_id="user_1",
    metadata={"type": "note"},
)

# 检索与查询最相关的记忆
context.retrieve("Python answers", max_results=3)
# 获取指定会话的最近记忆列表
context.conversation("conv_1", max_items=10)

44) 导出、保存、加载

AgentContext 包含简单的持久化辅助方法。此示例使用一个临时目录。

# 将会话记忆导出为 JSON 并预览前 300 个字符
export_json = context.export(conversation_id="conv_1", format="json")
export_json[:300]
# 使用临时目录测试上下文的保存与加载
import tempfile

# 在临时目录中保存并重新加载上下文
with tempfile.TemporaryDirectory() as d:
    context.save(d)
    context.load(d)

# 生成会话摘要
context.conversation_summary("conv_1")

55) 存储文档并构建上下文图谱

如果你存储一个列表,AgentContext.store(...) 会将其视为文档。为了让本 notebook 保持轻量且确定,我们为每个文档传入预先抽取好的实体和关系。

# 存储文档并构建上下文图谱(使用预抽取的实体与关系)
# 定义两个带预抽取实体与关系的文档
documents = [
    {
        "id": "doc_1",
        "content": "Python is used for machine learning.",
        "metadata": {"source": "docs"},
        "entities": [
            {"id": "e_python", "text": "Python", "type": "PROGRAMMING_LANGUAGE"},
            {"id": "e_ml", "text": "Machine Learning", "type": "CONCEPT"},
        ],
        "relationships": [
            {
                "source_id": "e_python",
                "target_id": "e_ml",
                "type": "used_for",
                "confidence": 0.9,
            }
        ],
    },
    {
        "id": "doc_2",
        "content": "PyTorch is a machine learning framework.",
        "metadata": {"source": "docs"},
        "entities": [
            {"id": "e_pytorch", "text": "PyTorch", "type": "FRAMEWORK"},
            {"id": "e_ml", "text": "Machine Learning", "type": "CONCEPT"},
        ],
        "relationships": [
            {
                "source_id": "e_pytorch",
                "target_id": "e_ml",
                "type": "implements",
                "confidence": 0.95,
            }
        ],
    },
]

# 存储文档:跳过抽取,仅做实体链接
stats = context.store(
    documents,
    extract_entities=False,
    extract_relationships=False,
    link_entities=True,
)

# 查看存储统计信息
stats
# 查看上下文图谱的统计信息
kg.stats()

66) 使用 `ContextGraph` 探索图谱

该图谱支持关键词查询和邻居扩展。

# 在上下文图谱中执行关键词查询
kg.query("machine learning")
# 获取节点 e_python 两跳以内的邻居
kg.get_neighbors("e_python", hops=2)

77) 使用 `EntityLinker` 进行实体链接

EntityLinker 分配稳定的 URI,并可以跨来源链接相关或重复的实体。

# 使用 EntityLinker 将文本中的实体链接到稳定 URI
from semantica.context import EntityLinker

# 创建链接器并传入已有实体作为知识库
linker = EntityLinker(knowledge_graph={"entities": [{"id": "e_py", "text": "Python", "type": "PROGRAMMING_LANGUAGE"}]})

# 待链接的候选实体列表
entities = [
    {"id": "e1", "text": "Python", "type": "PROGRAMMING_LANGUAGE"},
    {"id": "e2", "text": "PyTorch", "type": "FRAMEWORK"},
]

# 链接文本中的实体并展示 URI 与关联实体数
linked = linker.link("Python and PyTorch", entities=entities)
[(e.entity_id, e.uri, len(e.linked_entities)) for e in linked]
# 手动建立实体间链接并查询已有链接
linker.link_entities("e1", "e2", link_type="related_to", confidence=0.8)
linker.get_entity_links("e1")[:2]
# 构建实体网络并查看统计信息
linker.build_entity_web()["statistics"]

88) 底层构建块:`AgentMemory` 和 `ContextRetriever`

如果你想要比 AgentContext 更多的控制,可以直接连接各个部分。

# 直接组合 AgentMemory 与 ContextRetriever 进行混合检索
from semantica.context import AgentMemory, ContextRetriever

# 创建无保留限制的记忆存储并写入一条事实
memory = AgentMemory(vector_store=vs, knowledge_graph=kg, retention_policy="unlimited")
memory.store("Python powers Semantica.", metadata={"type": "fact", "conversation_id": "conv_2"})

# 创建检索器,融合记忆、图谱与向量存储
retriever = ContextRetriever(memory_store=memory, knowledge_graph=kg, vector_store=vs)
results = retriever.retrieve("Python Semantica", max_results=5)

# 展示检索结果的内容、来源与分数
[(r.content, r.source, round(r.score, 3)) for r in results]

99) 方法、注册表和配置

methods 层暴露便捷函数,而 registry 让你插入自己的实现。config 提供运行时配置。

# 通过全局配置对象调整运行时配置
from semantica.context.config import context_config

# 设置保留策略为 7 天
context_config.set("retention_policy", "7_days")
# 读取当前保留策略
context_config.get("retention_policy")
# 注册自定义图谱构建方法到注册表
from semantica.context.methods import build_context_graph
from semantica.context.registry import method_registry

# 定义自定义图谱构建方法(此处返回空图)
def custom_graph_method(entities, relationships, conversations=None, **kwargs):
    return {
        "nodes": [],
        "edges": [],
        "statistics": {"node_count": 0, "edge_count": 0},
    }

# 注册自定义方法并列出所有已注册方法
method_registry.register("graph", "custom_demo", custom_graph_method)
method_registry.list_all("graph")
# 调用自定义方法构建上下文图谱
build_context_graph(
    entities=[{"id": "e1", "text": "Python", "type": "PROGRAMMING_LANGUAGE"}],
    relationships=[{"source_id": "e1", "target_id": "e2", "type": "related_to"}],
    method="custom_demo",
)