Files
zk-data-agent/docs/technical-architecture/05-workspace-memory-observability.md
2026-05-18 19:28:02 +08:00

4.8 KiB
Raw Permalink Blame History

05. 会话工作区、运行态和记忆

会话工作区、运行态和记忆

1. 会话工作区

每个用户、每个会话都有独立目录:

.port_sessions/accounts/<account_id>/sessions/<session_id>/
  input/
  scratchpad/
  output/
  session.json

目录职责:

input/
  用户上传或明确提供的输入资料。

scratchpad/
  临时脚本、中间文件、抽样缓存、断点记录。

output/
  最终交付产物。

session.json
  会话消息、工具调用、usage、events、file_history、runtime metadata。

2. 工作区路径路由

路径解析实现:

src/agent_tools.py:1658 _session_logical_path

逻辑路径:

output/...     -> session/output/...
outputs/...    -> session/output/...
scratchpad/... -> session/scratchpad/...
scratch/...    -> session/scratchpad/...
input/...      -> session/input/...
inputs/...     -> session/input/...

Python 执行 cwd

src/agent_tools.py:1685 _execution_cwd

优先使用当前 session scratchpad。这是为了避免临时脚本和缓存污染项目根目录。

3. 平台代码写保护

相关实现:

src/agent_tools.py:1118 _PLATFORM_READONLY_DIRS
src/agent_tools.py:1698 _is_platform_code_path
src/agent_tools.py:1708 _ensure_not_platform_code_write

当前平台目录:

src
backend
frontend
scripts

在数据 Agent 会话中默认视为只读。除非用户明确进入平台开发任务,否则业务任务不应修改平台代码。

4. Run 状态和活动区

后端在 /api/chat 运行时创建 run record

backend/api/server.py:1720 run_record = state.run_manager.start(...)
backend/api/server.py:1722 state.run_state_store.start(...)

运行事件通过 emit_agent_event 记录:

backend/api/server.py:1751 emit_agent_event
backend/api/server.py:1756 run_manager.record_event
backend/api/server.py:1758 run_state_store.record_event

返回前端:

backend/api/server.py:2034 StreamingResponse

前端活动区看到的内容主要来自:

  • run_started
  • tool_start
  • tool_result
  • 模型阶段说明
  • final text stream events
  • run finish/error/cancel 状态

5. 会话持久化

运行结束后,后端序列化结果:

backend/api/server.py:2056 _serialize_run_result
backend/api/server.py:2069 _normalize_transcript_entry

会话读取:

backend/api/server.py:2094 _serialize_stored_session

agent_runtime 在多个结束路径都会调用:

_persist_session(session, result)

这让刷新后可以恢复:

  • 用户消息。
  • assistant 文本。
  • tool_calls。
  • tool result。
  • elapsed。
  • file_history。

6. 记忆体系

实现位置:

src/personal_memory.py

6.1 文件和数据库

memory.db
user.md
skills/<skill-name>.md

常量:

src/personal_memory.py:26 MEMORY_DB_FILENAME
src/personal_memory.py:27 USER_MEMORY_FILENAME
src/personal_memory.py:28 SKILL_MEMORY_DIRNAME

6.2 注入逻辑

src/personal_memory.py:102 render_injection

注入规则:

1. 读取 user.md。
2. 根据 enabled_skill_names 读取对应 skills/<skill>.md。
3. 拼成 # 个性化记忆。
4. 如果用户本轮要求冲突,以本轮要求为准。

后端调用:

backend/api/server.py:1739 memory_manager.render_injection(...)

6.3 入队逻辑

运行结束后:

backend/api/server.py:1920 memory_manager.enqueue_interaction(...)

记忆模块内:

src/personal_memory.py:138 enqueue_interaction
src/personal_memory.py:635 detect_memory_signals

会检测:

  • 显式记忆词:记住、以后、下次、默认、总是、不要、应该、固定。
  • 纠错词:不对、不是这样、格式错、之前说过、还是不行。
  • Skill/工具/流程/格式相关表述。
  • 工具参数非法 JSON 等工具经验。

6.4 后台整理

核心逻辑:

src/personal_memory.py:378 _consolidate_events
src/personal_memory.py:419 _generate_memory_updates
src/personal_memory.py:471 _fallback_memory_updates

设计取舍:

  • 主链路不直接生成记忆。
  • 事件先进入 SQLite 队列。
  • 后台 worker 批量整理。
  • LLM 失败时有 fallback 规则。
  • Markdown 是最终可编辑记忆正文。

7. 可观测性设计

当前可观测性来自三个层次:

运行态
  run_manager + run_state_store,支持运行中刷新、停止、恢复活动区。

会话态
  session.json,保存完整消息和工具调用。

产物态
  session/input、scratchpad、output,文件面板可查看和下载。

这个设计让用户不仅看到最终回复,也能看到 Agent 做了什么、文件在哪里、失败在哪个工具或阶段。