Skip to content

[bug] PostgreSQL 控制面下 harness-memory 0.9.7 记忆管道(GC/召回/提取)使用 SQLite-only SQL,长期记忆完全不可用 #457

Description

@yawner-droid

问题描述

控制面使用 PostgreSQL(官方支持的标准配置,见 docs/configuration.md §"Agent memory vs control plane" 与 ADR 002)时,agent 记忆按默认规则自动指向同一 PG DSN(octop/infra/agents/memory_backend.pyuse_control_plane_dsn 路径)。此时 harness-memory 的整条记忆管道静默失效:capture / recall / extract / GC 全部失败,memory_search 恒空,长期跨会话记忆实际不可用,且每条消息都会触发一批必然失败的 PG 查询(日志噪音 + 额外延迟)。

PG 中 harness_memory schema 12 张表 DDL 正常创建,但所有表 0 行——从未有数据写入成功。

环境

  • Octop: 0.9.28(官方安装脚本)
  • Python: 3.12
  • harness-memory: 0.9.7(PyPI 最新版)
  • 控制面: PostgreSQL(12 表 schema 正常创建)
  • OS: Ubuntu (Linux x86_64)

最小复现

  1. 控制面选择 PostgreSQL(setup 向导或 OCTOP_DATABASE_* 环境变量)。
  2. 保持 agent 记忆默认启用(不设置 memory.backend → 自动走 PG 控制面 DSN)。
  3. 正常对话若干轮。
  4. 检查 PG:SELECT count(*) FROM harness_memory.atoms; → 0;memory_search 工具无任何结果;日志中记忆管道持续报错。

根因分析

存储层(storage/backends/postgres.py)是完整的:独立 DDL + 全套公共 API(save/list/search/delete raw/atom/candidate/node 等)。问题在 lifecycle 管道层直接绕过存储层公共 API、硬编码 SQLite 方言

  1. pipeline/lifecycle/gc.py:285-291_sqlite_conn(memory) 读取 SQLite 后端私有属性 backend._conn(PG 后端无此语义),随后:

    • L242: conn.execute(f"SELECT quote_event_id, raw_event_ids FROM {ns}_atoms")
    • L247: conn.execute(f"SELECT raw_event_ids FROM {ns}_candidates")
    • L305: conn.execute(f"DELETE FROM {ns}_atoms WHERE id = ?", (atom_id,))

    两处 SQLite-only 假设:{ns}_ 表前缀是 SQLite 的命名空间机制(PG 后端用独立 schema 隔离);? 占位符在 psycopg(%s)下无效。

  2. pipeline/lifecycle/maintenance.py:300-307conn.in_transaction(aiosqlite API)+ PRAGMA wal_checkpoint(TRUNCATE)(SQLite 专属 PRAGMA,PG 下直接报错)。

  3. pipeline/lifecycle/vacuum.py — SQLite VACUUM 语句(PG 的 autovacuum 机制完全不同)。

  4. pipeline/lifecycle/checkpoint_gc.py — 同类问题。

影响面

  • 所有 PG 控制面部署(文档支持的配置)记忆系统整体不可用,不是部分降级。
  • 每条消息都触发确定性失败的 PG 查询:日志噪音 + 可避免的延迟。
  • 用户无法从表象判断是"记忆没生效"还是"后端坏了"(静默失败,无显著报错)。

建议修复方向

  1. lifecycle 管道改为只走 backend 公共 API(list_atoms / list_candidates / 删除接口等),不访问 backend._conn
  2. PRAGMA/VACUUM 类操作做后端类型判断,PG 下跳过(autovacuum 兜底);
  3. 参照控制面的做法增加 PG 集成测试(@pytest.mark.postgresql + OCTOP_TEST_DATABASE_URL gating),覆盖 capture → extract → recall → GC 全链路。

临时规避(已验证)

docs/configuration.md 在 agent 配置中设置:

"memory": { "backend": { "type": "sqlite" } }

记忆回落到 {workspace}/memory.sqlite,管道恢复正常。注意:checkpointer 与记忆后端同库(harness_agent/agent.py _resolve_checkpointer),切换后端会使旧线程的模型侧上下文重置(会话 JSONL 历史保留)。

附注

PyPI harness-memory 元数据指向的仓库 https://github.com/TencentCloud/harness-memory 当前 404(API 与网页均确认,GitHub 全站搜索无同名仓库),故在此仓库提报。

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions