diff --git a/agentmain.py b/agentmain.py index 303daf8..08e083c 100644 --- a/agentmain.py +++ b/agentmain.py @@ -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 '' in full_response: full_response = full_response.replace('', '\n\n') if '' in full_response: full_response = re.sub(r'\s*(.*?)\s*', r'\n````\n\n\1\n\n````', full_response, flags=re.DOTALL) self.display_queue.put({'done': full_response, 'source': source}) diff --git a/memory/memory_management_sop.md b/memory/memory_management_sop.md index 56207a7..84ca911 100644 --- a/memory/memory_management_sop.md +++ b/memory/memory_management_sop.md @@ -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 文件 - 临时实验 → 删除 diff --git a/sidercall.py b/sidercall.py index 3f88c7b..01d3d98 100644 --- a/sidercall.py +++ b/sidercall.py @@ -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. **思考**: 在 `` 标签中先进行思考,分析现状和策略。 2. **总结**: 在 `` 中输出*极为简短*的高度概括的单行(<30字)物理快照,包括上次工具调用结果获取的新信息+本次工具调用意图和预期。此内容将进入长期工作记忆,记录关键信息,严禁输出无实际信息增量的描述。 3. **行动**: 如果需要调用工具,请在回复正文之后输出一个 **块**,然后结束,我会稍后给你返回块。