如何编写Raven插件:MemoryBackend契约与四源发现机制开发者完全指南
【免费下载链接】RavenThe Harness of Harnesses: a trusted, persistent, self-evolving multi-agent ecosystem for all-domain collaboration.项目地址: https://gitcode.com/gh_mirrors/raven35/Raven
Raven 是一个可信、持久、自我进化的多智能体生态系统,而它的插件体系是扩展能力的关键:你不需要修改任何宿主代码,只要实现一套 MemoryBackend 契约、写一份插件清单,就能把自己的记忆后端接入 Raven。本文是一份面向新手的完整指南,带你快速吃透编写 Raven 插件的两把钥匙——MemoryBackend 契约与四源发现机制,并给出一份可直接落地的开发清单 🧭
🗺️ 30 秒看懂:契约 + 发现 = 免改动接入
Raven 的插件框架只有两个核心部件:
| 部件 | 位置 | 作用 |
|---|---|---|
| MemoryBackend 契约 | raven/contracts/memory.py | 定义所有记忆插件必须实现的 8 个方法 |
| 四源发现机制 | raven/plugins/discover.py | 从 4 个来源扫描插件清单,按优先级去重 |
理解这两个部件,你就理解了整套插件架构。官方架构文档在 docs/memory-plugin-architecture.md,建议作为进阶读物。
📜 第一步:读懂 MemoryBackend 契约
契约是一个@runtime_checkable的 Protocol(见 raven/contracts/memory.py#L142-L332),共8 个方法,按"热路径"优先级排列:
| 方法 | 何时被调用 | 可以偷懒吗? |
|---|---|---|
recall | 每一轮对话组装上下文时 | ❌ 核心方法 |
store | 每轮对话结束后持久化 | ❌ 核心方法 |
feedback | 技能被注入后回收信号 | ✅ 允许空实现 |
start/stop | 启动 / 关闭生命周期 | 需幂等 |
health | raven doctor诊断时 | 可返回None |
delete | 用户删除某条记忆时 | 可返回False |
recall_session | 子代理运行后回读其记忆 | 可返回[] |
规则一:recall的"双轨 XOR"
recall要求user_id与agent_id恰好设置一个(raven/contracts/memory.py#L166-L191):
- 双轨后端(如 EverOS):把设置的那个 id 路由到对应存储——用户侧存"情节/画像",代理侧存"案例/技能";
- 扁平后端(如 mem0):用
user_id正常工作,收到agent_id调用时直接返回[]。
两个都没传、或都传了?那是调用方的 bug,你返回[]即可。
规则二:store只认"显式 False"
store返回bool表示这次写入是否落地。只有显式返回False才算写入失败——宿主会据此带退避重试;而返回None等假值会被当作"已落地"。所以请谨慎处理返回值。另外,metadata中有两个值得尊重的约定键:
flush: True:对话已结束,立即从切片中提取,别等自己的提取周期;user_id/agent_id:仅代表本次调用为谁写入(子代理场景),不要当成默认身份。
规则三:失败契约——宿主会替你兜底,但别依赖它
宿主(AgentLoop、TUI、网关、raven serve)会把每次调用的异常当作"丢失这一次调用":recall计为无命中、store计为未落地、start失败则本会话没有长期记忆。能识别的失败(超时、连接被拒)应尽量自己捕获并降级,返回空结果比抛异常更优雅。
📦 第二步:写好raven-plugin.toml清单
清单是发现机制唯一的"入口",解析规则在 raven/plugins/manifest.py。最小可用的记忆后端清单长这样:
[plugin] id = "my-memory" version = "1.0.0" [[plugin.contributes.memory_backends]] name = "mybackend" factory = "my_package.backend:make_backend"三个容易踩的坑 ⚠️:
factory必须是module.path:callable格式,写错会在启动时立刻报错(这是好事,好过激活时才炸);- 后端
name会成为技能命名空间(技能 id 形如<name>/<id>),所以不能含斜杠,且local、hub两个名字被保留,不能占用; - 插件
__init__.py必须保持空或极轻——entry-points 发现会通过资源解析导入它,重依赖放这里会违背"只读清单"的承诺。
参考一个真实成品:plugins-dist/everos-memory/raven_everos/raven-plugin.toml,它还展示了onboard(引导向导步骤)、tools(注册代理工具)和config_schema(对plugins.config配置切片做入门类型校验)三类可选贡献点。
🔍 第三步:四源发现机制如何找到你
PluginDiscovery.discover()会扫描4 个来源并按插件 id 去重(raven/plugins/discover.py#L86-L108)。来源即优先级,数字大者胜出:
| 优先级 | 来源 | 位置 | 适用人群 |
|---|---|---|---|
| 4 | BUNDLED | 随 Raven 分发的内置目录 | 第一方插件 |
| 3 | USER | ~/.raven/plugins/<id>/ | 本地放一个目录即用 |
| 2 | PROJECT | ./.raven/plugins/<id>/及plugins.dirs配置的目录 | 随项目提交 |
| 1 | ENTRY_POINTS | pip 包,entry-points 组名raven.plugins | 第三方分发(推荐) |
两条关键设计:
- 内置遮蔽规则:
bundled > user > project > entry_points,内置插件永远不会被同名的本地/pip 副本悄悄盖掉;不同 id 的插件则和平共处,由配置项memory.backend决定激活哪一个; - 只读清单,永不导入:发现阶段只解析 TOML,绝不 import 后端代码。所以某个后端缺了重量级依赖(lancedb、mem0ai)也拖不垮其他后端;工厂模块只有在你选中该后端时才被导入——"默认自带"不等于"默认付出启动成本"。
选中的插件会收到一个 PluginContext(配置切片 +ServiceLocator+ 带插件前缀的 logger),你的make_backend(ctx)工厂函数只需基于它返回一个结构上符合MemoryBackend的对象。身份 id(user_id/agent_id)统一由宿主经ctx.services下发,不要从自己的plugins.config切片里另读一份——两处存同一个值,就是"改了一边、读写永久分裂"事故的根源。
✅ 第四步:上线前检查清单
- 8 个方法齐全,
recall/recall_session遵守 XOR 规则,neither/both 时返回[] store仅在明确失败时返回False,传输/鉴权错误不抛异常start幂等,且recall/store能容忍在start未完成时被调用(答"无命中/未落地"即可)stop可在start失败后安全调用health如实报告:只有真故障才是missing,"按需启动、尚未运行"应报ok加提示- 清单 id/version 齐全,
name不含斜杠、不占用保留名 - 包
__init__.py保持空/轻
跑通测试再发布:
uv run pytest tests/test_memory_backend_protocol.py tests/test_memory_backend_contract.py -q契约测试与发现测试分别在 tests/test_memory_backend_contract.py 和 tests/test_everos_plugin_discovery.py,可作为编写自家后端的活模板。
📚 延伸阅读
| 资料 | 说明 |
|---|---|
| raven/contracts/memory.py | 契约全文,注释即最佳实践 |
| raven/plugins/discover.py | 四源扫描与冲突消解实现 |
| raven/plugins/bootstrap.py | 发现 → 激活的一站式装配 |
| docs/memory-plugin-architecture.md | 完整架构设计与 mem0 接入示例 |
掌握了契约与发现机制,你离"给 Raven 装上一个自己设计的记忆"只差一个make_backend的距离 🚀
【免费下载链接】RavenThe Harness of Harnesses: a trusted, persistent, self-evolving multi-agent ecosystem for all-domain collaboration.项目地址: https://gitcode.com/gh_mirrors/raven35/Raven
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考