OpenViking 上下文类型详解:Resource / Memory / Skill 的建模、存储与统一检索实战
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
OpenViking 将 AI Agent 的全部上下文统一抽象为**资源(Resource)、记忆(Memory)、技能(Skill)**三种基本类型,并以目录化的 Viking URI 组织为可检索、可导航的上下文数据库。本文以 docs/zh/concepts/02-context-types.md 为主线,结合 Python SDK 客户端实现、URI 规范 与 检索机制 源码,系统讲解三种上下文类型的设计意图、存储位置、内置记忆类型及完整的增删查实操,读完即可在你的 Agent 应用中正确划分知识、认知与能力三类上下文,并用一次find()完成跨类型统一检索。
概览:三类上下文的本质差异
OpenViking 对人类认知模式做了简化映射与工程化抽象,将上下文分为三类。三者最核心的区别在于谁在维护与生命周期:
| 类型 | 用途 | 生命周期 | 主动性 |
|---|---|---|---|
| Resource | 知识和规则 | 长期,相对静态 | 用户添加 |
| Memory | Agent 的认知 | 长期,动态更新 | Agent 记录 |
| Skill | 可声明的 agent 能动性配置(AgentDefinedContextType) | 长期,静态 | 用户或系统添加 |
从源码层面看,这三种类型在检索侧被建模为ContextType枚举,SDK 与检索链路统一使用字符串值skill/memory/resource:
# openviking/core/context.py class ContextType(str, Enum): """Context type""" SKILL = "skill" MEMORY = "memory" RESOURCE = "resource"同时,openviking_cli/retrieve/types.py中的检索类型定义与此一致,保证 CLI、HTTP API 与 Python SDK 对三种类型的命名完全对齐。这一枚举贯穿 IntentAnalyzer 意图分析 到 层级检索 的整条检索链路,是理解三类上下文如何被"分区检索"的钥匙。
Resource(资源):Agent 可引用的外部知识
特点
- 用户主动:由用户主动添加的资源类信息,用于补充大模型的知识,比如产品手册、代码仓库;
- 静态内容:添加后内容很少发生变化,通常为用户主动修改;
- 结构化存储:按项目或主题以目录层级组织,并提取出多层信息(即 L0/L1/L2,详见上下文层级)。
典型示例
- API 文档、产品手册
- FAQ 数据库、代码仓库
- 研究论文、技术规范
资源默认存放在共享的viking://resources/{project}/命名空间下。值得注意的是,resources作用域只允许存储客观知识类数据(文档、代码、规范、论文等),工具配置、通信端点、支付配置、技能定义等一律禁止放入,必须走viking://agent/作用域——这是 Viking URI 规范 中明确的空间约束。
添加与搜索资源
# 添加资源 client.add_resource( path="https://docs.example.com/api.pdf", options={"reason": "API 文档"}, ) # 搜索资源 results = client.find( query="认证方法", target_uri="viking://resources/", )从 SDK 实现(sdk/python/openviking_sdk/client.py)看,add_resource()支持三种输入形态:
- 传入本地文件路径:SDK 通过 multipart 上传
temp_file_id; - 传入本地目录:SDK 会先压缩为 zip 再上传,保留目录结构;
- 传入URL 或远端地址:作为
path直接交给服务端 ResourceService 抓取解析。
同时add_type与parent不能同时使用,add_type要求精确的to目标,parent则用于自动创建父目录。上传到共享区用to="viking://resources/project/",写入个人私有区用parent="viking://~/resources/project/"。
Memory(记忆):Agent 从交互中习得的持久认知
记忆是 Agent 从交互和任务执行中学到的持久化知识。与资源的关键区别是:记忆由 Agent 主动提取和记录,随交互持续动态更新,并且是个性化的——针对特定用户和稳定 peer 学习记录。
记忆存储在当前用户或 Peer 命名空间下,不使用独立的viking://agent/memories目录,而是落在用户空间,配合~家目录别名访问。
内置记忆类型
OpenViking 内置 9 种记忆类型,每种都有默认存放位置:
| 类型 | 默认位置 | 说明 |
|---|---|---|
| profile | ~/memories/profile.md | 用户基本信息 |
| preferences | ~/memories/preferences/ | 按主题组织的用户偏好 |
| entities | ~/memories/entities/ | 人物、项目、组织等实体知识 |
| events | ~/memories/events/ | 决策、里程碑等事件记录 |
| identity | ~/memories/identity.md | 助手的名称、形象、气质和自我介绍 |
| soul | ~/memories/soul.md | 助手的核心原则、边界、风格和连续性 |
| cases | ~/memories/cases/ | 用于训练和评估的任务案例 |
| trajectories | ~/memories/trajectories/ | 可复用的任务执行轨迹 |
| experiences | ~/memories/experiences/ | 从执行结果中提炼的可复用经验 |
家目录别名~与 Peer 记忆
表中的~/...使用家目录别名viking://~,服务端会按认证身份将其展开为viking://user/{user_id}/...。当记忆策略允许 Peer 记忆时,支持 Peer 的类型会写入viking://user/{user_id}/peers/{peer_id}/memories/...,即关于特定交互对象的记忆会与普通记忆隔离存放。
关于类型扩展的边界(来自 上下文类型文档 与会话管理文档):
- 记忆类型可通过自定义模板扩展或调整;
- Schema 中定义的
memories/tools/和memories/skills/类型已被禁用——它们与存放在viking://user/{user_id}/skills/{skill_name}/SKILL.md下的独立 Skill 不同,后者仍然保留并受支持; - 在
memory_policy.memory_types中,启用experiences会开启完整 Agent Evolution 流程,并自动激活cases和trajectories;若未启用experiences,显式传入的cases/trajectories会被静默忽略而非报错。
记忆的自动提取与检索
记忆在会话提交(session.commit())后由后台任务自动提取,无需用户手动写入:
from openviking_sdk import TextPart # 记忆从会话中自动提取 session_info = await client.create_session() session = client.session(session_id=session_info["session_id"]) await session.add_message( role="user", parts=[TextPart(text="我喜欢深色模式")], ) commit = await session.commit() # 启动后台记忆提取 task = await client.get_task(task_id=commit["task_id"]) # 轮询直到 task["status"] == "completed" # 搜索记忆 results = await client.find( query="用户界面偏好", target_uri="viking://~/memories/" )底层的提取流程(详见会话管理)为:消息 → LLM 提取 → 候选记忆 → 向量预过滤找相似 → LLM 去重决策(skip/create/none + merge/delete)→ 写入 AGFS → 向量化。每次 commit 还会在归档目录写入memory_diff.json记忆变更审计日志,便于回溯与排查。会话存储结构即viking://user/{user_id}/sessions/{session_id}/下含messages.jsonl、.abstract.md、.overview.md、history/、tools/等。
Skill(技能 / AgentDefinedContextType):可声明的 Agent 能动性配置
技能是 Agent 可以调用的能力,属于 AgentDefinedContextType 范畴,包括传统工作流定义、通信端点、工具配置和支付能力等。它们的共同特征是:定义了 agent 如何与外部系统交互;运行时定义相对静态,但调用经验会在 Memory 中更新。
特点
- 定义的能力:用于完成某项工作的工具定义;
- 相对静态:运行时技能定义不变,但和工具相关的使用记忆会在记忆中更新;
- 可调用:Agent 决定何时使用哪种技能。
存储位置
技能有两种存储位置:默认的用户级技能根,以及通过--uri覆盖的全局 agent 技能根:
viking://~/skills/{skill-name}/ # 默认存储路径 ├── .abstract.md # L0: 简短描述 ├── .overview.md # L1: 目录概览(生成后) ├── SKILL.md # L2: 技能定义 └── scripts # L2: 附加实现 viking://agent/skills/{skill-name}/ # 通过 --uri 覆盖,公开共享(account 全局) ├── .abstract.md # L0: 简短描述 ├── .overview.md # L1: 目录概览(生成后) ├── SKILL.md # L2: 技能定义 └── scripts # L2: 附加实现viking://agent/...是全局共享作用域,account 下所有用户均可访问,不通过 agent_id 隔离。每个技能目录由 L0/L1/L2 三层信息组成(.abstract.md/.overview.md/SKILL.md+scripts),支持渐进式加载,节省 Token 消耗。
AgentDefinedContextType 子类型
AgentDefinedContextType 包含以下子类型,均存储于viking://agent/作用域:
| 子类型 | 位置 | 说明 |
|---|---|---|
| Skill | agent/skills/ | 传统工作流定义,如搜索、代码生成 |
| Endpoint | agent/endpoints/ | 通信端点配置(a2a, anp 等)(规划中) |
| Tool | agent/tools/ | 工具配置(mcp 等)(规划中) |
| Payment | agent/payments/ | 支付能力配置(ap2 等)(规划中) |
添加与搜索技能
# 添加技能(默认写入 viking://~/skills/) await client.add_skill( data={ "name": "search-web", "description": "搜索网络获取信息", "content": "# search-web\n...", }, ) # 通过 -p 指定写入全局 agent 技能根(公开共享) ov skills add search-web -p viking://agent/skills # 搜索用户技能 results = await client.find( query="网络搜索", target_uri="viking://~/skills/" ) # 搜索全局 agent 技能 results = await client.find( query="网络搜索", target_uri="viking://agent/skills/", )SDK 中的add_skill()(sdk/python/openviking_sdk/client.py)与add_resource()采用一致的参数处理:传入 dict 则直接作为data提交;传入本地文件/目录路径则自动上传为temp_file_id;target_uri可在 options 中覆盖默认写入位置。同时 SDK 还提供validate_skill()(严格校验)、get_skill()、update_skill()、delete_skill()与find_skills()等技能专用 API,其中find_skills支持level、score_threshold等检索参数。
统一检索:一次 find 跨越三类上下文
OpenViking 的find()支持对三种上下文类型统一搜索。不传target_uri时,服务端会跨 Memory、Resource、Skill 三类返回结果,并按memories/resources/skills分组:
# 跨所有上下文类型搜索 results = await client.find(query="用户认证") for context in results.get("memories", []): print(f"记忆: {context['uri']}") for context in results.get("resources", []): print(f"资源: {context['uri']}") for context in results.get("skills", []): print(f"技能: {context['uri']}")find()的 SDK 签名(sdk/python/openviking_sdk/client.py)为:
async def find( self, query: str = "", target_uri: Union[str, List[str]] = "", limit: int = 10, image: Any = None, options: Optional[FindOptions] = None, ) -> Dict[str, Any]:target_uri支持传单个 URI 或 URI 列表,以此限定检索范围(如只搜viking://resources/或同时搜多个目录);limit控制返回条数;image支持多模态查询。该请求最终打到POST /api/v1/search/find。
指定作用域搜索
日常使用中,配合 Viking URI 可以精确限定检索目标:
# 仅在资源中搜索 results = client.find(query="认证", target_uri="viking://resources/") # 仅在自己的资源中搜索 results = client.find(query="私有项目笔记", target_uri="viking://~/resources/") # 仅在自己的记忆中搜索 results = client.find(query="编码偏好", target_uri="viking://~/memories/") # 仅在自己的技能中搜索 results = client.find(query="网络搜索", target_uri="viking://~/skills/")find() 与 search() 的分工
需要说明的是,无状态find()与有状态的search()是两条不同强度的检索路径(详见检索机制):
| 特性 | find() | search() |
|---|---|---|
| 会话上下文 | 不需要 | 需要 |
| 意图分析 | 不使用 | 使用 LLM 分析 |
| 查询数量 | 单一查询 | 0-5 个 TypedQuery |
| 延迟 | 低 | 较高 |
| 适用场景 | 简单查询 | 复杂任务 |
search()会先由 IntentAnalyzer 基于会话摘要、最近 5 条消息与当前查询生成 0-5 个 TypedQuery(每个 TypedQuery 携带context_type,即 MEMORY / RESOURCE / SKILL 之一),再分别走对应类型的根目录做层级检索,最后经 Rerank 精排返回。因此类型感知贯穿两条链路:find()靠target_uri显式限定,search()靠意图分析自动路由。
实战小结与最佳实践
三类上下文在 OpenViking 中形成了清晰的职责边界:
- 知识放资源:产品手册、API 文档、代码仓库等客观知识,用
add_resource()写入viking://resources/{project}/(共享)或viking://~/resources/(私有),内容静态、用户维护; - 认知靠记忆:用户偏好、实体、事件、经验等由 Agent 在
commit()后台自动提取,写入viking://~/memories/或 peer 命名空间,动态更新、按用户个性化; - 能力定义为技能:工作流、工具、端点、支付等 agent 能动性配置写入
viking://~/skills/或全局共享的viking://agent/skills/,运行时静态、可被 Agent 按需调用; - 检索统一出口:拿不准类型时直接用无
target_uri的find()跨三类搜索;要控制成本与精度时,用target_uri精确限定作用域。
编写代码时还要注意两条易错点:resources作用域禁止存放非知识类配置;记忆类型中的tools/skills子目录已禁用,技能请一律走独立 Skill 目录(SKILL.md)。想进一步了解三层信息模型如何让这些上下文渐进式加载,可继续阅读 上下文层级 L0/L1/L2;想掌握会话提交触发记忆提取的完整机制,可参考 会话管理;整个系统的模块划分与数据流见架构概述。
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考