跳到正文

DeepSeek Harness 集成 ​

Patchouli 的高层 API 只在 DSH 进程内提供。外部应用和其他 Harness 需要各自的适配器; Patchouli 不通过外部 Bridge 暴露 Memory Service。

统一 Memory Service ​

ctx.patchouli 提供三种操作:

  • update:向注册插件提交待吸收的信息;
  • retrieve:向注册插件查询相关信息;
  • subscribe:将插件拥有的变更推送给响应式 Consumer。

每次调用都有 meta 和插件定义的 JSON data。服务按插件注册的过滤器分发调用, 每个匹配插件各自返回结果。调用方不能直接点名内部插件。

Agent Loop 适配器 ​

官方适配器会发送每个启用 Hook 点能看到的完整数据。它不添加检索提示词,不总结事件, 也不替插件决定如何形成记忆。

yaml
- id: patchouli-agent-loop
  config:
    retrieve:
      sessionStart: false
      preStep: true
      turnStopping: false
      toolPostExecute: false
    store:
      agentCreated: false
      agentDisposed: false
      requestError: false
      agentError: false
      turnEnd: true
      toolResult: false
    modelTools:
      retrieve: true
      update: true

默认策略在每个 Agent Step 前检索、保存每个已提交 Turn,并向模型暴露 memory_retrieve 和 memory_update。其他 Hook 点位需显式开启。 agent/session-start 是非等待通知,所以这里的检索采用尽力而为;其他等待型 Hook 仍按官方 Agent Loop 的方式同步等待。

memory_update 可以提交工作区文件,而不必先把文件字节读入模型调用:

json
{
  "resources": [
    {
      "kind": "workspace-file",
      "path": "notes/decision.md",
      "mediaType": "text/markdown",
      "role": "reference"
    }
  ]
}

Artifact Ingestor 在当前 Session 工作区内解析路径,并通过 ctx.patchouliStorage 上传 字节;图片附件也经过同一条托管 Artifact 链路。

响应式 Consumer ​

订阅前先绑定持久化游标命名空间:

ts
const scope = '/workspace/example'
const cursorStore = ctx.patchouliCursors.bind({
  consumerId: 'knowledge-index',
  subscriptionKey: 'live-memory',
  scope,
})

const subscription = await ctx.patchouli.subscribe(
  {
    meta: {
      source: { type: 'consumer', id: 'knowledge-index' },
      scope,
    },
  },
  async ({ pluginId, cursor, memoryId, metadata }) => {
    await applyChangeIdempotently({ pluginId, cursor, memoryId, metadata })
  },
  {
    cursorStore,
    signal,
    onError({ pluginId, error }) {
      reportSubscriptionFailure(pluginId, error)
    },
  },
)

每个插件按顺序处理事件,只有 Handler 成功后才推进游标;不同插件互不阻塞。 标记为可重试的失败从最后一个持久化游标恢复,未知失败和 resetRequired 会停止 对应插件 Worker,交由 Consumer 显式执行快照或重新同步。

subscription.unsubscribe() 可重复调用,会取消重试、关闭底层订阅并等待已接收 的 Handler 完成。Handler 必须保持幂等,因为进程可能在副作用完成、游标写入前停止。

基于 MIT License 发布。源自 Minecraft 的图标素材另有声明。