Refine memory SOP and LLM session behaviour

This commit is contained in:
Liang Jiaqing
2026-02-04 21:29:59 +08:00
parent a9209daaf7
commit 16bf93dafa
3 changed files with 47 additions and 40 deletions

View File

@@ -83,7 +83,7 @@ class GeneraticAgent:
for chunk in gen:
if self.stop_sig: break
full_response += chunk
self.display_queue.put({'next': full_response, 'source': source})
self.display_queue.put({'next': f'{full_response}', 'source': source})
if '</summary>' in full_response: full_response = full_response.replace('</summary>', '</summary>\n\n')
if '</file_content>' in full_response: full_response = re.sub(r'<file_content>\s*(.*?)\s*</file_content>', r'\n````\n<file_content>\n\1\n</file_content>\n````', full_response, flags=re.DOTALL)
self.display_queue.put({'done': full_response, 'source': source})

View File

@@ -1,8 +1,29 @@
L1: global_mem_insight.txt (极简索引层 - 严格控制 ≤50 行)
↓ 导航指向
L2: global_mem.txt (事实库层 - 现短但会膨胀)
↓ 详细引用
L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
## 0. 核心公理 (Core Axioms - 最高优先级)
1. **行动验证原则 (Action-Verified Only)**
* **定义**:任何写入 L1/L2/L3 的信息,必须源自**成功的工具调用结果**(如 `shell` 执行成功、`file_read` 确认内容存在、代码运行通过)。
* **禁止**:严禁将模型的“固有知识”、“推理猜测”、“未执行的计划”或“未验证的假设”作为事实写入。
* **口号****No Execution, No Memory. (无行动,不记忆)**
2. **神圣不可删改性 (Sanctity of Verified Data)**
* **定义**凡是经过行动验证的有效配置、避坑指南、关键路径在重构Refactoring/GC时**严禁丢弃**。
* **操作**:可以压缩文字、可以迁移层级(从 L2 移到 L3但绝不能丢失信息的准确性和可追溯性。
3. **禁止存储易变状态 (No Volatile State)**
* **定义**:严禁存储随时间/会话高频变化的数据。
* **示例**:当前时间戳、临时 Session ID、正在运行的 PID、某个具体绝对路径、连接的设备信息
---
## 记忆层级架构
```
L1: global_mem_insight.txt (极简索引层 - 严格控制 ≤50 行)
↓ 导航指向 (Pointer)
L2: global_mem.txt (事实库层 - 现短但会膨胀)
↓ 详细引用 (Reference)
L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
```
---
@@ -15,51 +36,37 @@ L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
**特征**
- 体积限制:≤ 50 行(硬约束)
- 内容CONSTITUTION、STORES、ACCESS、TOPICS、LESSONS_LEARNED
- 更新L2 有新增/删除事实时同步;发现通用规律时追加 LESSONS
- 更新L2 有新增/删除事实时同步;发现通用且极其重要的规律时追加 LESSONS
**禁止**详细说明、过程记录、单次修复日志
**禁止**严禁在此层直接写入 IP、密码、完整路径、API Key。L1 只能是索引指针,不能是数据容器。不写 "How to" 或详细解释。
---
### L2全局事实库 (global_mem.txt)
**职责**:存储全局环性事实(路径、凭证、配置等)。
**职责**:存储全局环性事实(路径、凭证、配置、常量等)。
**特征**
- 趋势:随环境扩展而膨胀(可接受)
- 内容:按 `## [SECTION]` 组织的事实条目
- 同步:变化时更新 L1 的相应 TOPIC 导航行
**禁止**:禁止存储易变状态、禁止存储猜测
---
### L3详细记录库 (../memory/)
### L3任务级精简记录库 (../memory/)
**职责**:存储所有 L1/L2 无法容纳的详细信息
职责:补充 L1/L2 无法容纳、但对**特定任务**未来复用至关重要的少量详细信息。内容必须在满足复用需求的前提下**尽可能短**
**特征**
- 文件类型:.md、.py 等各类文件均可
- 膨胀容限:无限制
- 组织按功能分类mail/、vision/ 等或文件类型SOP、工具脚本、日志
- 文件命名:*_sop.md流程、*_log.md日志、.py工具脚本
**管理**
- 工具脚本 + 详细 SOP → L3 对应文件
- 维护日志、过程记录 → L3 maintenance_log.md
- 单次修复、实验 → L3 存放或删除,不入 L1 LESSONS
**L3 中 SOP 与工具脚本的分工**
- SOP*_sop.md
- 主要用途:记录**坑**。
- 重点写:以后再做同类任务时最容易出问题的环节、前置条件、环境/配置坑,以及当前已验证有效的解决办法和排查思路。
- 何时记录步骤:
- 只有在任务是**复杂、多步、长链路**时,才顺带把关键步骤流程写清楚,方便整体复现;
- 对于简单、直观、模型按常识就能完成的任务,**不需要在 SOP 里记完整步骤**。
- 工具脚本 / util*.py 等)
- 前提:只有当某块逻辑具备**清晰边界和函数独立性**,且**有明显复用价值**时,才封装成工具脚本。
- 典型用途:
- 像自定义 Python 包那样,把稳定功能做成可多次调用的函数 / 模块;
- 当某任务“坑太多、文字 SOP 难以说清”时,把稳定的处理逻辑直接写成代码函数,让上层只需调用,不必每次重新踩坑。
原则
- 只记录:跨会话仍重要、且难以通过少量 file_read / web_scan / 简单脚本快速重建的要点。
- 优先写:该任务特有的隐藏前置条件、典型易踩坑点,一旦遗忘会导致高成本重试的信息。
- 不记录:普通操作步骤、可在几步探测中重新获得的路径或状态信息。
形式:
- SOP*_sop.md为单一任务或小类任务保留极简的「关键前置 + 典型坑」清单,避免长篇教程。
- 工具脚本(*.py仅封装高复用、逻辑相对复杂且不希望每次都重新推理的处理流程。
---
## L1 ↔ L2 同步规则
@@ -77,7 +84,7 @@ L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
```
"这条信息该放哪层?"
是『全局环保事实』? (IP、路径、凭证、ID、API 密钥等)
是『全局事实』? (IP、重要路径特征、凭证、ID、API 密钥等)
├─ YES → L2 (global_mem.txt)
│ 然后 → L1 [TOPICS.GLOBAL_MEM] 添加导航行
@@ -88,7 +95,6 @@ L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
│ 并可在 L3 写详细解释
└─ NO → L3 (../memory/)
- 过程/日志 → maintenance_log.md
- 工具文档 → *_sop.md
- 可复用代码函数 → .py 文件
- 临时实验 → 删除

View File

@@ -20,7 +20,7 @@ class SiderLLMSession:
return ''.join(list(gen))
class LLMSession:
def __init__(self, api_key=oai_apikey, api_base=oai_apibase, model=oai_model, context_win=16000):
def __init__(self, api_key=oai_apikey, api_base=oai_apibase, model=oai_model, context_win=12000):
self.api_key = api_key
self.api_base = api_base
self.raw_msgs = []
@@ -84,7 +84,8 @@ class LLMSession:
self.raw_msgs.append({"role": "user", "prompt": prompt, "image": image_base64})
messages = self.make_messages(self.raw_msgs[:-1], omit_images=True)
messages += self.make_messages([self.raw_msgs[-1]], omit_images=False)
total_len = sum(2000 if isinstance(m["content"], list) else len(str(m["content"]))//4 for m in messages) # estimate token count
msg_lens = [1000 if isinstance(m["content"], list) else len(str(m["content"]))//4 for m in messages]
total_len = sum(msg_lens) # estimate token count
gen = self.raw_ask(messages, model)
def _ask_gen():
content = ''
@@ -92,7 +93,7 @@ class LLMSession:
content += chunk; yield chunk
if not content.startswith("Error:"):
self.raw_msgs.append({"role": "assistant", "prompt": content, "image": None})
if total_len > 5000: print(f"[Debug] Whole context length {total_len}.")
if total_len > 5000: print(f"[Debug] Whole context length {total_len} {str(msg_lens)}.")
if total_len > self.context_win: self.summary_history()
if stream: return _ask_gen()
return ''.join(list(_ask_gen()))
@@ -147,7 +148,7 @@ class ToolClient:
tools_json = json.dumps(tools, ensure_ascii=False, separators=(',', ':'))
tool_instruction = f"""
### 交互协议 (必须严格遵守)
请按照以下步骤思考并行动:
请按照以下步骤思考并行动,标签之间需要回车换行
1. **思考**: 在 `<thinking>` 标签中先进行思考,分析现状和策略。
2. **总结**: 在 `<summary>` 中输出*极为简短*的高度概括的单行(<30字物理快照包括上次工具调用结果获取的新信息+本次工具调用意图和预期。此内容将进入长期工作记忆,记录关键信息,严禁输出无实际信息增量的描述。
3. **行动**: 如果需要调用工具,请在回复正文之后输出一个 **<tool_use>块**,然后结束,我会稍后给你返回<tool_result>块。