OpenViking隐私系统:如何识别并脱敏Agent上下文中的敏感信息
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
OpenViking 是一个面向 AI Agent 的自进化上下文数据库(Self-evolving Context Database),统一管理 Agent 的记忆、知识 RAG 与技能。随着 Agent 能力变强,它的上下文里越来越多地出现 API Key、数据库密码、内部 endpoint 这类敏感信息。OpenViking 的隐私系统(Privacy System)专门解决这个问题:写入时自动识别并脱敏敏感信息,读取时按需还原,让密钥不再以明文躺在技能文档里。
Agent 上下文里,哪些信息算"敏感"?
在 OpenViking 里,Agent 的技能(Skill)以SKILL.md文件形式存储,里面可能包含用户自己维护的配置。隐私系统的提取规则把这些字段归纳为 4 类:
| 类型 | 典型字段 | 示例 |
|---|---|---|
| 🔑 密钥凭证 | api_key、token、secret_key、client_secret | sk-9f86d081881c... |
| 🌐 服务端点 | base_url、endpoint、host | https://api.example.com/v1 |
| 🗄️ 资源标识 | project、resource_id、database、collection | my_prod_db |
| 👤 账户信息 | username、password | 个人账号密码 |
完整的识别规则写在 skill/privacy_extraction.yaml 这份提示词模板里,并明确了三条边界:
- 既抽"已有值",也抽"预期值":即使文档里只写了"需要配置 access_key"而没有真实值,也会登记该字段(值为空字符串),避免漏管;
- 不编造值:模型严禁虚构密钥,只会抽取文档中真实出现的内容;
- 忽略一次性业务参数:
query、limit这类临时查询输入不算敏感配置,不会误伤。
第一步:让模型来"识别"敏感信息
OpenViking 没有用一堆正则表达式硬匹配,而是把识别工作交给大模型。当你通过add_skill写入一个技能时,会触发隐私提取流程:
核心调用在 skill_extractor.py 的extract_skill_privacy_values函数中:渲染提示词 → 调用模型 → 解析 JSON 输出,得到形如{"api_key": "sk-xxx", "base_url": "https://..."}的结构化键值对。
这套方式的好处是语义理解:文档里哪怕用中文写着"访问密钥:sk-xxx",或者字段名大小写混乱,模型也能归一化成snake_case标准字段名(如 "Access Key" →access_key),这比纯规则方案稳健得多。
第二步:占位符脱敏,明文不再落盘
识别出敏感值后,OpenViking 会做一件关键的事:把正文中的明文替换成占位符,磁盘上只保存占位符版本。替换逻辑在 skill_placeholder.py:
脱敏前:
api_key: sk-9f86d081881c4a2bb36e6f89388e3e57脱敏后:
api_key: {{ov_privacy:skill:my_skill:api_key}}占位符的格式是{{ov_privacy:skill:<技能名>:<字段名>}},它同时携带了"属于哪个技能、对应哪个字段"两个信息,为读取时精确还原提供依据。替换时还会智能处理 JSON 引号、key=value、key: value等多种写法,确保配置文件结构不被破坏。
💡 替换顺序有个小细节:系统按值长度从长到短替换,避免短值是长值的子串时产生误替换。
敏感值存到哪里?版本化的隐私配置仓库
被抽走的敏感值不会丢,它们被存入用户空间下的隐私配置仓库,由 service.py 中的UserPrivacyConfigService统一管理,存储结构如下:
viking://user/{user_space}/privacy/skill/{skill_name}/ ├── .meta.json # 元信息:当前生效版本、最新版本、标签等 ├── current.json # 当前生效版本的完整快照 └── history/ ├── version_1.json └── version_2.json版本化带来两个实用能力:
- 密钥轮换可追溯:每次更新密钥都会生成新版本并记录
change_reason(变更原因),审计有据可查; - 一键回滚:如果发现新密钥配错了,执行
activate即可切回历史版本,无需重新编辑技能文档。
第三步:读取时自动"还原",对调用方透明
脱敏的意义在于:Agent 真正要用这个技能时,还得能拿到可用内容。OpenViking 的解法是读取时还原——当读取SKILL.md时,fs_service.py 会自动识别 URI 中的技能名,查询当前生效的隐私配置,再由 skill_restore.py 的restore_skill_content函数把占位符替换回真实值。
还原过程还内置了三种异常处理,保证"缺配置"不会静默失败:
- 占位符有对应值→ 直接还原,调用方拿到完整可执行内容;
- 占位符存在但值缺失→ 保留占位符并在文末追加
[Privacy Config Notice],明确告知哪些配置缺失; - 配置了但正文未引用→ 追加提示"Configured but not referenced in content",帮助排查。
对上层 Agent 来说这一切完全透明:一次普通的read调用,拿到的就是还原后的技能文本,不需要关心背后发生过脱敏和还原。
如何用 CLI 管理隐私配置
管理面通过 API 和 CLI 暴露,端点定义在 privacy_configs.py,常用命令如下:
# 查看所有隐私配置类别 openviking privacy categories # 列出 skill 类别下所有目标 openviking privacy list skill # 更新某技能的敏感值(生成新版本) openviking privacy upsert skill my_skill \ --values-json '{"api_key":"sk-new-key"}' # 回滚到历史版本 openviking privacy activate skill my_skill 1 # 读取技能(占位符自动还原) openviking read viking://user/default/skills/my_skill/SKILL.md这套隐私设计带来了什么
| 收益 | 说明 |
|---|---|
| 🛡️ 降低泄露面 | SKILL.md里不再有任何明文密钥,备份、同步、审计都安全 |
| 🔄 密钥轮换零成本 | 换密钥只需更新隐私配置,技能正文不用改 |
| ⏪ 快速回滚 | 版本化快照 +activate一键切回 |
| 👀 透明无感 | 读取自动还原,上层 Agent 完全无感知 |
| 🔍 可观测 | 缺失/多余配置都会显式提示,排障不抓瞎 |
对新手来说,最简单的理解方式是:OpenViking 隐私系统 = 大模型识别 + 占位符脱敏 + 版本化金库 + 读取时自动还原。它让"Agent 上下文里的敏感信息"从散落各处的明文,变成了集中管理、可审计、可随时回滚的配置项。
延伸阅读
- 官方概念文档:docs/zh/concepts/13-privacy.md(含完整链路图)
- 隐私系统源码目录:openviking/privacy/
- 隐私配置 API 文档:docs/zh/api/10-privacy.md
- 隐私服务测试用例:tests/server/test_privacy_config_service.py
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考