news 2026/9/13 17:00:22

Qwen Code Daemon 无会话工作区记忆 API:Sessionless Managed Memory 任务队列的设计与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qwen Code Daemon 无会话工作区记忆 API:Sessionless Managed Memory 任务队列的设计与实现

Qwen Code Daemon 无会话工作区记忆 API:Sessionless Managed Memory 任务队列的设计与实现

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

导读

在 Qwen Code(qwen-code)的 daemon 架构中,托管记忆(managed memory)的自动抽取、dream 压缩等能力此前必须依托一个活跃的聊天会话才能写入。本文基于 daemon-workspace-remember 设计文档,结合仓库中的 workspace-remember.ts、remember.ts 等源码实现,完整讲解这套无会话(sessionless)工作区记忆任务 API:它如何在「不创建、不污染任何可见会话」的前提下完成 remember / forget / dream 三类记忆操作,如何通过串行任务车道(task lane)保证并发安全,以及如何通过 202 + 轮询的异步契约让设置面板、SDK 调用方获得可靠的状态反馈。读完本文,你将掌握这套 API 的完整端点契约、任务生命周期、容量与超时策略、错误码体系,以及从 HTTP 路由到 ACP 子进程、再到核心记忆写入逻辑的完整调用链。


1. 问题背景:为什么记忆写入必须摆脱会话依赖

在引入本设计之前,daemon 的托管记忆系统(自动抽取、dream agent)要求必须存在一个活跃的聊天会话才能写入记忆,这带来了两个现实问题:

  1. 设置面板无法写入记忆——web-shell 的设置界面需要保存用户提供的事实(例如「所有编辑器一律使用 TypeScript strict mode」),但为此创建或污染一个可见的聊天会话显然不合理。
  2. 会话列表被污染——为了执行一次/remember命令而临时创建一个「用完即弃」的会话,会在会话列表里留下大量用户从未主动打开过的「幽灵会话」,造成困惑。

解决思路是一个无会话的工作区级记忆任务 API:它负责排队 remember、forget、dream 三类任务,在不创建可见会话的前提下执行它们,并通过轮询暴露执行状态。

需要说明的是:本文描述的设计方案在仓库中标记为Proposed(PR #5884,分支codex/sessionless-daemon-remember),但对应实现文件已经存在于当前仓库源码中(见下文各小节引用的具体路径),本文以源码现状为准展开讲解。


2. 设计概览:一条从客户端到 ACP 子进程的完整链路

整体架构如下(摘自设计文档):

┌──────────────┐ POST /workspace/memory/{task} ┌─────────────────────────┐ │ SDK / UI │ ─────────────────────────────────► │ workspace-remember.ts │ │ client │ │ (WorkspaceRemember- │ │ │ GET /workspace/memory/{task}/:id │ TaskLane) │ │ │ ─────────────────────────────────► │ │ └──────────────┘ └────────────┬────────────┘ │ bridge.runWorkspaceMemory* ┌────────────▼────────────┐ │ HttpAcpBridge │ │ extMethod( │ │ 'qwen/control/ │ │ workspace/memory/ │ │ {task}') │ └────────────┬────────────┘ │ ACP stdio (JSON-RPC) ┌────────────▼────────────┐ │ qwen --acp child │ │ (QwenAgent.extMethod) │ │ → remember / forget / │ │ dream core logic │ └─────────────────────────┘

这套设计具备四个关键性质:

  • 无需会话(No session required)——bridge 只确保 ACP 子进程被拉起,但绝不创建 / 加载 / 恢复任何 ACP 会话。这一点在 bridgeTypes.ts 的接口注释中明确声明:「必须确保 ACP child 存在,但不得创建/加载/恢复 ACP 会话,也不得触碰按会话的 prompt 队列」。
  • 串行执行(Serial execution)——任务通过一条 promise-chain 车道逐条执行,防止对托管记忆文件系统产生并发写入。
  • 隐藏(Hidden)——remember/dream 通过隐藏 agent 运行,forget 使用隐藏记忆配置,所有操作都不会产生可见会话。
  • 能力广播(Capability-advertised)——daemon 的/capabilities响应中会声明workspace_memory_rememberworkspace_memory_forgetworkspace_memory_dream三项能力;remember 还会附带modes: ['workspace', 'clean']。从 SDK 源码看,还衍生出workspace_memory_remember_project_scopeworkspace_memory_remember_user_scopeworkspace_memory_forget_scope等更细粒度的能力标签,用于旧 daemon 兼容性预检(见 DaemonClient.ts)。

3. HTTP API 端点详解

所有端点都挂在/workspace/memory/{task}路径下,采用「POST 入队 + GET 轮询」的异步任务模式。POST 统一返回202 Accepted与任务快照,客户端随后轮询GET /workspace/memory/{task}/:taskId直到任务进入终态。

3.1POST /workspace/memory/remember—— 入队一个 remember 任务

请求体:

{ "content": "The user prefers dark mode in all editors", "contextMode": "workspace" }
FieldTypeRequiredDescription
contentstringyes要记住的事实。最大64 KiB(UTF-8 字节长度)。
contextModestringno"workspace"(默认)——agent 可看到工作区记忆上下文;"clean"——agent 看不到任何先前的用户记忆。
scopestringno目标范围:"project""user",省略时由 agent 自动选择(源码中新增的可选字段,见 workspace-remember.ts)。

Headers:

  • Authorization: Bearer <token>(必填)
  • X-Qwen-Client-Id: <clientId>(可选——用于限定任务的可见范围)

响应202 Accepted

{ "taskId": "remember-a1b2c3d4-...", "status": "queued", "contextMode": "workspace", "createdAt": "2026-06-01T12:00:00.000Z", "updatedAt": "2026-06-01T12:00:00.000Z" }

错误响应:

StatusCodeCondition
400invalid_contentcontent 缺失、为空或超出 64 KiB
400invalid_context_modecontextMode 不是"workspace""clean"
400invalid_scopescope 不是"project""user"(源码新增)
400invalid_client_idX-Qwen-Client-Id 未在 bridge 注册
403untrusted_workspace工作区未被信任(源码新增防护)
409managed_memory_unavailable该工作区未配置托管记忆
429remember_queue_full已有 16 个待处理任务排队
500remember_failed可用性检查意外抛错

实现细节:路由层在入队前会做多道校验——contenttrim()后必须非空,且Buffer.byteLength(trimmedContent, 'utf8')不得超过常量MAX_REMEMBER_CONTENT_BYTES = 64 * 1024(定义于 workspace-memory-remember-constants.ts);X-Qwen-Client-Id必须存在于bridge.knownClientIds()集合中(workspace-remember.ts);随后调用isWorkspaceMemoryRememberAvailable()做可用性预检,以便在入队前同步返回409(workspace-remember.ts)。

3.2GET /workspace/memory/remember/:taskId—— 轮询 remember 任务

Headers:与 POST 相同;X-Qwen-Client-Id必须与发起方一致才能看到任务。

响应200 OK(queued / running):

{ "taskId": "remember-a1b2c3d4-...", "status": "queued", "contextMode": "workspace", "createdAt": "2026-06-01T12:00:00.000Z", "updatedAt": "2026-06-01T12:00:00.000Z", "result": null, "error": null }
  • status"queued""running",取决于任务是否已开始执行;
  • result仅在status === "completed"时非空;
  • error仅在status === "failed"时非空。

响应200 OK(completed):

{ "taskId": "remember-a1b2c3d4-...", "status": "completed", "contextMode": "workspace", "createdAt": "2026-06-01T12:00:00.000Z", "updatedAt": "2026-06-01T12:00:05.000Z", "result": { "summary": "Saved dark-mode preference to user memory.", "filesTouched": ["~/.qwen/memories/user/user.md"], "touchedScopes": ["user"] } }

响应200 OK(failed):

{ "taskId": "remember-a1b2c3d4-...", "status": "failed", "contextMode": "workspace", "createdAt": "2026-06-01T12:00:00.000Z", "updatedAt": "2026-06-01T12:00:03.000Z", "error": { "code": "remember_path_escape", "message": "Remember agent touched a path outside managed memory." } }

错误响应:

StatusCodeCondition
400invalid_client_idX-Qwen-Client-Id 未注册
404remember_task_not_found任务不存在或属于其他 client

可见性语义(源码印证):任务快照通过lane.get(taskId, requesterClientId, kind)获取(workspace-remember.ts)——若任务携带originatorClientId,则请求方必须与之完全一致;若任务未携带而请求方带了 clientId,同样返回不可见。这保证了任务的多客户端隔离。

3.3POST /workspace/memory/forget—— 入队一个 forget 任务

forget 任务由 daemon 选出匹配的托管自动记忆条目并删除,全程不创建会话。

请求体:

{ "query": "old preference" }
FieldTypeRequiredDescription
querystringyes用自然语言描述要遗忘的内容。最大64 KiB(UTF-8 字节长度)。
scopestringno限定遗忘范围"project"/"user",省略则两边都查(源码新增)。

初始响应为202 Accepted,返回forget-...前缀的 taskId,随后轮询GET /workspace/memory/forget/:taskId直到终态。

completed 结果:

{ "summary": "Forgot 1 memory entry.", "removedEntries": [ { "topic": "project", "summary": "old preference", "filePath": "/path/to/memory.md" } ], "touchedTopics": ["project"], "touchedScopes": ["project"] }

3.4GET /workspace/memory/forget/:taskId

轮询 forget 任务。结构上与 remember 轮询一致,差异在于:没有contextMode字段;未知或未授权的 taskId 返回forget_task_not_found

3.5POST /workspace/memory/dream—— 入队一个 dream 任务

dream 任务执行托管自动记忆的 dream 压缩流程(跨条目去重、汇总),同样不创建会话。

请求体:空 JSON 对象或省略 body。

初始响应为202 Accepted,返回dream-...前缀的 taskId,轮询GET /workspace/memory/dream/:taskId直到终态。

completed 结果:

{ "summary": "Managed auto-memory dream completed.", "touchedTopics": ["project"], "dedupedEntries": 1 }

3.6GET /workspace/memory/dream/:taskId

轮询 dream 任务,结构与 remember 轮询一致,无contextMode字段,未知或未授权的 taskId 返回dream_task_not_found


4. 任务生命周期与容量控制

4.1 状态机

enqueue() │ ▼ ┌─────────────────────┐ │ queued │ (awaiting serial lane slot) └──────────┬──────────┘ │ lane picks up ▼ ┌─────────────────────┐ │ running │ (bridge.runWorkspaceMemoryRemember in progress) └──────────┬──────────┘ │ ┌───────┴────────┐ ▼ ▼ ┌──────────┐ ┌──────────┐ │ completed│ │ failed │ └──────────┘ └──────────┘
  • queued——任务已创建,正在串行车道中等待。
  • running——bridge 调用在途,forked agent 正在执行。
  • completed——agent 成功结束,result已填充。
  • failed——agent 抛错或超时,error已填充。

4.2 容量与保留策略

车道级常量定义在 workspace-remember.ts 的WorkspaceRememberTaskLane中:

常量含义
MAX_TASKS1000车道最多保存1000 条任务记录,达到上限后按 FIFO 逐出终态任务(evictTerminalTasks
TERMINAL_TASK_TTL_MS5 分钟终态任务(completed/failed)超过该 TTL 后也会被清理
MAX_PENDING16同一时刻最多16 条待处理任务(queued + running)
MAX_NON_REMEMBER_PENDING8forget/dream 两类任务合计最多8 条待处理

两级容量设计(assertCapacity,workspace-remember.ts)的意图很明确:forget 和 dream 这类「突发性手工维护」共享较小的子配额,避免突发维护耗尽 remember 自动写入所需的全部车道槽位——例如自动记忆抽取是常态工作负载,不能被一次批量 dream 挤掉。

另外,beginDrain()/dispose()提供了工作区下线语义:dispose()会把所有 queued 任务标记为failedworkspace_removed错误),正在 running 的任务在结束后也会被failRunningTaskAfterRemoval修正为失败(workspace-remember.ts)。


5. 源码级实现剖析

5.1 串行任务车道(WorkspaceRememberTaskLane

车道位于 workspace-remember.ts,核心是一个Map<taskId, TaskRecord>加一条单一 promise 链(this.tail)。每次enqueue()/enqueueForget()/enqueueDream()都会向链尾追加一个run函数,其执行流程为:

  1. 将任务状态置为running
  2. 调用对应的 bridge 方法:runWorkspaceMemoryRemember/runWorkspaceMemoryForget/runWorkspaceMemoryDream
  3. 成功:置为completed,填充result;若任务确实改写了托管记忆,则发布memory_changed事件;
  4. 失败:置为failed,用稳定的公开错误码填充error

三条enqueue*路径还各有额外校验:

  • remember 在result.filesTouched.length === 0时抛remember_no_update(「agent 没有更新任何记忆」);
  • 发布事件前会通过publishManagedMemoryChanged检查touchedScopes非空(workspace-remember.ts)。

车道的本质是严格串行化——任意时刻只有一个工作区记忆任务在执行,从根本上杜绝了对托管记忆文件系统的并发写入(详见第 8 节「为什么串行」)。

5.2 Bridge 层(HttpAcpBridge

工作区记忆方法在BridgeInterface(bridgeTypes.ts)中新增了四个方法:

  • isWorkspaceMemoryRememberAvailable()——调用子进程的qwen/control/workspace/memory/remember/availabilityext-method,返回boolean。用于在入队前快速失败(409)。
  • runWorkspaceMemoryRemember(request)——调用qwen/control/workspace/memory/rememberext-method,超时300 sWORKSPACE_MEMORY_REMEMBER_TIMEOUT_MS)。不创建也不加载会话
  • runWorkspaceMemoryForget(request)——调用qwen/control/workspace/memory/forgetext-method,使用同一 bridge 超时。不创建也不加载会话。
  • runWorkspaceMemoryDream()——调用qwen/control/workspace/memory/dreamext-method,使用同一 bridge 超时。不创建也不加载会话。

这些方法都会调用ensureChannel()(必要时拉起 ACP 子进程),并在没有活跃会话时重启空闲计时器。

5.3 ACP 子进程执行(QwenAgent.extMethod

在 acpAgent.ts 中,workspaceMemoryRemember/workspaceMemoryForget/workspaceMemoryDream的 handler 执行以下步骤:

  1. 校验任务级入参(remember 的content/contextMode/scope,forget 的query);
  2. 检查config.isManagedMemoryAvailable()
  3. 调用对应的核心操作,并携带一个295 s的 abort 信号(WORKSPACE_MEMORY_REMEMBER_CHILD_TIMEOUT_MS = 295_000,见 acpAgent.ts)。forget 场景下该信号会贯穿MemoryManager.forget的条目选择、模型侧查询和落盘文件系统变更全过程。

值得一提的细节:子进程侧使用AbortSignal.timeout()构造超时,超时后错误被映射为remember_timeout等带稳定 code 的错误(acpAgent.ts),而不是传输层超时——这正是第 6 节超时链设计的落地。

5.4 核心 remember 逻辑(packages/core/src/memory/remember.ts

runManagedRememberByAgent()(remember.ts)是 remember 的最终执行者,流程如下:

  1. 通过buildCleanMemorySystemPrompt()从项目的托管记忆索引构建一份干净的记忆系统提示词;
  2. contextMode === 'clean',通过getUserMemory: () => ''剥离先前的用户记忆,实现「白板」写入;同时createHiddenRememberConfig()会禁用聊天记录、转录路径,clean 模式下还会禁用全部 hooks(remember.ts);
  3. 创建memoryScopedAgentConfig(见 5.5),把文件 I/O 严格限制在记忆目录内;
  4. runForkedAgent运行一个forked 无头 agent
    • 名称:managed-auto-memory-remember
    • 工具:read_filegreplswrite_fileedit
    • 最大轮数:6(getMemoryAgentMaxTurns() ?? 6
    • 最大时长:5 分钟(getMemoryAgentTimeoutMinutes() ?? 5
  5. classifyTouchedScopes()校验所有被写入的文件都位于允许的记忆路径内;若 agent 写到了记忆目录之外,抛出remember_path_escape(remember.ts);
  6. 对任何被触碰的 scope 重建记忆索引(rebuildManagedAutoMemoryIndex/rebuildUserAutoMemoryIndex)——这是关键一致性保障:MEMORY.md会逐字加载进每个未来的会话,因此失败、取消的 run 也必须在报错前重建索引,绝不允许把手工写入的索引文件留在磁盘上(见 remember.ts 中覆盖 failed/cancelled/escape/no-update 各路径的重建逻辑);
  7. 返回{ summary, filesTouched, touchedScopes }

此外还有两道额外防线:remember_no_update(agent 完成但未写入任何条目)和remember_scope_mismatch(指定了scope但 agent 写到了范围之外)。

5.5 记忆作用域 agent 配置(memory-scoped-agent-config.ts

createMemoryScopedAgentConfig()(memory-scoped-agent-config.ts)创建一份权限受限的Config包装器,把原PermissionManager替换为MemoryScopedPermissionManager

  • 写工具write_fileedit):仅允许写入项目自动记忆根目录或用户记忆根目录(~/.qwen/memories);
  • 读工具read_filegrepls):当restrictReadsToMemoryPaths为 true 时,仅允许读取记忆目录内;
  • Shell:默认禁用;若allowShell开启,仅允许只读命令(通过isShellCommandReadOnlyASTInDirectory做 AST 级只读判定,memory-scoped-agent-config.ts);
  • Symlink 解析:所有路径判定前先realpath解析,防止通过符号链接逃逸出记忆目录(realpathExistingOrNew/realpathNewPath,memory-scoped-agent-config.ts);
  • Pinned 记忆保护protectPinnedMemory开启时,pinned/目录被声明为只读,任何对其的写入直接deny(memory-scoped-agent-config.ts);
  • 决策合并:作用域决策与基础决策按优先级deny > ask > allow > default合并,bypassBaseAskForScopedPaths开启时允许用allow覆盖基础配置的ask(memory-scoped-agent-config.ts)。

该模块配有独立的单元测试 memory-scoped-agent-config.test.ts,覆盖路径逃逸、pinned 保护、只读 shell 等边界场景。


6. 事件通知:memory_changed(scope:managed

当某个工作区记忆任务成功完成且确实触碰了托管记忆时,daemon 会在 SSE 事件流(GET /session/:id/events)上发布一个memory_changed事件,scopemanaged。订阅了按会话事件流的客户端都会收到该通知。

Payload:

{ "type": "memory_changed", "data": { "scope": "managed", "source": "workspace_memory_remember", "taskId": "remember-a1b2c3d4-...", "touchedScopes": ["user", "project"] } }
FieldTypeDescription
scope"managed"与基于文件的memory_changed事件(scope: 'workspace' | 'global')区分开
sourcestring"workspace_memory_remember""workspace_memory_forget""workspace_memory_dream"
taskIdstring与 POST 返回的任务 ID 关联
touchedScopesstring[]变更了哪些托管记忆 scope:"user""project"

POST 时若提供了originatorClientId,它会被附加到事件信封上,使事件总线能将通知路由回发起方客户端(workspace-remember.ts)。事件只在touchedScopes非空时发布。


7. 错误处理与超时链

7.1 错误码全景

CodeOriginMeaning
invalid_contentHTTP routecontent 缺失、为空或超过 64 KiB
invalid_context_modeHTTP routecontextMode 不是"workspace""clean"
invalid_queryHTTP routeforget query 缺失、为空或超过 64 KiB
invalid_scopeHTTP routescope 不是"project""user"(源码新增)
invalid_client_idHTTP routeClient-Id header 不在 bridge 的已知集合中
managed_memory_unavailableBridge / ACP child工作区未配置托管记忆
remember_queue_fullTask lane达到 16 条待处理任务上限
remember_path_escapeCore remember logicAgent 写到了托管记忆目录之外的路径
remember_scope_mismatchCore remember logicAgent 写到了请求 scope 之外(源码新增)
remember_no_updateCore remember logicAgent 未更新任何记忆(源码新增)
remember_failedCatch-all未分类的 agent 失败、超时或内部错误
remember_task_not_foundHTTP routeGET 未知或未授权的任务 ID
forget_task_not_foundHTTP routeGET 未知或未授权的 forget 任务 ID
dream_task_not_foundHTTP routeGET 未知或未授权的 dream 任务 ID
workspace_removedTask lane工作区运行时被移除(源码新增,dispose路径)
workspace_drainingTask lane工作区运行时正在被移除(源码新增,入队时拒绝)
remember_timeout/forget_timeout/dream_timeoutACP child子进程侧超时(源码新增)

这些错误码的公开消息与 HTTP 状态映射集中在 workspace-remember.ts(publicErrorMessage/publicErrorStatus)以及 workspace-remember-errors.ts(workspaceMemoryFailureCode/workspaceMemoryFailureDiagnostics)中,并配有单元测试 workspace-remember-errors.test.ts。注意部分错误(如remember_path_escape)通过shouldSuppressRememberErrorDetails抑制内部细节外泄,避免把敏感路径暴露给客户端。

7.2 超时链

Agent forked runner: 5 min maxTimeMinutes Child abort signal: 295 s (WORKSPACE_MEMORY_REMEMBER_CHILD_TIMEOUT_MS) Bridge timeout: 300 s (WORKSPACE_MEMORY_REMEMBER_TIMEOUT_MS)

子进程在 bridge 超时之前先 abort,从而保证错误以干净的语义错误(remember_timeout等)向上传播,而不是传输层超时。这条「子进程先于 bridge 兜底」的链式设计,配合任务车道层 5 分钟终态 TTL,构成了完整的超时与资源回收机制。


8. SDK 集成

8.1 TypeScript SDK(@qwen-code/sdk-typescript

DaemonClient上暴露了对应方法(DaemonClient.ts):

// Queue a remember task const task = await client.rememberWorkspaceMemory( 'The project uses pnpm workspaces', { contextMode: 'workspace' }, ); // task.taskId, task.status === 'queued' // Poll until terminal const result = await client.getWorkspaceMemoryRememberTask(task.taskId); // result.status === 'completed' | 'failed' const forget = await client.forgetWorkspaceMemory('old preference'); const forgetResult = await client.getWorkspaceMemoryForgetTask(forget.taskId); const dream = await client.dreamWorkspaceMemory(); const dreamResult = await client.getWorkspaceMemoryDreamTask(dream.taskId);

SDK 侧还做了能力预检:当调用方传入scope时,SDK 会先通过requireCapability()检查对应能力标签(workspace_memory_remember_project_scope/workspace_memory_remember_user_scope/workspace_memory_forget_scope),因为旧版 daemon 会静默忽略scope参数——预检把「静默降级」变成「响亮的错误」,避免无 scope 的 forget 误删两个存储中的条目(DaemonClient.ts)。这些方法在 DaemonClient.test.ts 中有完整的单测覆盖。

8.2 UI 事件规范化

SDK 的 normalizer 把原始 SSE 的memory_changedscope: 'managed')事件映射为DaemonUiWorkspaceMemoryChangedEvent(normalizer.ts、types.ts):

{ type: 'workspace.memory.changed', scope: 'managed', source: 'workspace_memory_remember', taskId: 'remember-...', touchedScopes: ['user', 'project'] }

这是对既有workspace.memory.changed事件类型的扩展——该事件此前只承载scope: 'workspace' | 'global'(基于文件的 QWEN.md 写入),如今新增'managed'分支。事件在 UI 层的terminal.tstranscript.ts中按新分支分发,并有 daemonUi.test.ts 验证。


9. 设计权衡:为什么这样设计

为什么无会话(Why sessionless)?

CLI 中的/remember斜杠命令本身已经能在会话内工作,但设置面板和程序化 SDK 调用方不应该为了持久化一条事实而创建一个会话。会话意味着对话历史、回合跟踪和在会话列表中的可见性——这些对一个「即发即忘」的记忆写入来说全部是多余的负担。无会话 API 让记忆写入成为一等公民操作,与聊天会话完全解耦。

为什么串行执行(Why serial execution)?

托管记忆系统把事实存储在带索引的 markdown 文件中。多个 remember 任务并发写入可能损坏索引或产生合并冲突——单线程车道是最简单且正确的解法(结合 5.1 节可知,这是由一条 promise 链this.tail保证的硬性串行约束)。

为什么用任务队列而非同步执行(Why a task queue)?

记忆写入涉及 LLM agent 决定「在哪里、如何存」这条事实(在 user 与 project scope 之间选择、挑选正确的文件、格式化),通常耗时2–30 秒。同步 HTTP 请求要么超时、要么阻塞客户端。异步「队列 + 轮询」模式保持了 HTTP 契约的简洁,也让客户端能展示进度 UI。

为什么需要contextMode

  • "workspace"(默认)——remember agent 能看到既有记忆作为上下文,从而对已有条目去重或更新;
  • "clean"——agent 看不到任何先前的用户记忆,适合调用方希望强制全新写入、跳过去重逻辑的场景(例如批量导入)。

为什么限制读取路径(Why restrict reads to memory paths)?

remember agent 只应读写托管记忆目录内的内容。这能阻止一类提示注入攻击:精心构造的content诱导 agent 去读取敏感的项目文件并把内容泄漏进记忆条目。restrictReadsToMemoryPaths配合 symlink 解析(5.5 节)从权限层面对此做了硬性封堵。


10. 延伸阅读

  • 设计文档原文:daemon-workspace-remember.md
  • 车道与路由实现:workspace-remember.ts 及其测试 workspace-remember.test.ts
  • 错误码与诊断:workspace-remember-errors.ts
  • 核心 remember 逻辑:remember.ts 及其测试 remember.test.ts
  • 记忆作用域权限包装器:memory-scoped-agent-config.ts
  • Bridge 接口定义:bridgeTypes.ts
  • ACP 子进程 ext-method 处理:acpAgent.ts
  • SDK 客户端方法与 UI 事件规范化:DaemonClient.ts、normalizer.ts
  • 相关设计背景(托管记忆体系):managed-memory-microcompaction、auto-memory 设计目录

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 16:59:24

SVPWM过调制:提升母线电压利用率的关键技术

FOC电机控制做到一定程度&#xff0c;大家都会碰到一个绕不开的问题&#xff1a;母线电压利用率。明明电池电压或者母线电压摆在那里&#xff0c;电机高速的时候就是感觉“使不上劲”&#xff0c;转速上不去&#xff0c;力矩又掉得厉害。有人第一反应是换更高电压的平台&#x…

作者头像 李华
网站建设 2026/9/13 16:58:32

Python毫秒级时间戳获取全攻略:time模块精度与性能深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 16:56:55

CAN自定义协议设计:从物理层约束到应用层状态机

1. 为什么“CAN自定义协议”不是选修课&#xff0c;而是嵌入式系统工程师的必修硬技能在汽车电子、工业控制、智能农机、新能源电池管理系统&#xff08;BMS&#xff09;这些领域里&#xff0c;CAN总线早已不是“能通就行”的玩具级通信手段。我做过7个量产级车载ECU项目&#…

作者头像 李华
网站建设 2026/9/13 16:56:44

DAM0808B工业继电器模块:30A大功率RS485远程控制实战指南

1. 这不是普通继电器——DAM0808B是工业现场的“电力调度员” 你手上那台刚拆封的DAM0808B模块&#xff0c;外壳上印着“30A”三个字&#xff0c;不是装饰。它真正能扛住30安培持续电流——相当于同时驱动6台1.5匹空调压缩机&#xff0c;或点亮150盏LED工矿灯&#xff0c;或控制…

作者头像 李华
网站建设 2026/9/13 16:56:23

STM32F103多传感器融合与EC800-4G稳定上云实战

简介&#xff1a;本资源是一套面向嵌入式物联网开发者的STM32F103单片机实战项目例程&#xff0c;聚焦于GNSS定位与多传感器数据采集、4G远程上传及云平台指令响应全流程实现&#xff0c;适用于高校电子类课程设计、毕业设计及初/中级工程师快速原型开发。压缩包共245个文件&am…

作者头像 李华
网站建设 2026/9/13 16:56:17

基于Python的无人机集群编队飞行:从原理到工程实践

简介&#xff1a;一套基于Python的无人机集群编队飞行项目资料&#xff0c;面向毕业设计、课程设计与项目开发人群&#xff0c;围绕集中式、分布式与混合式三种典型控制结构展开方案分析&#xff0c;并配有源码解析、项目文档解析、运行教程与设计说明。压缩包内共39个文件&…

作者头像 李华