From fd7bf241d04d53a9515728f56c5132905e490154 Mon Sep 17 00:00:00 2001 From: Liang Jiaqing Date: Fri, 13 Mar 2026 13:21:32 +0800 Subject: [PATCH] rename sidercall.py to llmcore.py; add cache-aware cd to compress_history_tags --- README.md | 4 +- agentmain.py | 4 +- assets/SETUP_FEISHU.md | 4 +- assets/make_prompts.py | 2 +- sidercall.py => llmcore.py | 8 ++- memory/autonomous_operation_sop.md | 103 ++++++++--------------------- tgapp.py | 2 +- 7 files changed, 40 insertions(+), 87 deletions(-) rename sidercall.py => llmcore.py (99%) diff --git a/README.md b/README.md index c965b0e..e83d168 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ The agent starts with 7 primitive tools. Through `code_run`, it can install pack **Core engine** (runs the agent): - `agent_loop.py` — Sense-Think-Act loop (92 lines) - `ga.py` — Tool definitions and execution -- `sidercall.py` — LLM communication (multi-backend) +- `llmcore.py` — LLM communication (multi-backend) - `agentmain.py` — Session orchestration **Interface** (talk to the agent): @@ -255,7 +255,7 @@ Agent 拥有 7 个原子工具:`code_run`(执行任意代码)、`file_read **核心引擎**: - `agent_loop.py` — 感知-思考-行动循环(92 行) - `ga.py` — 工具定义与执行 -- `sidercall.py` — LLM 通信(多后端) +- `llmcore.py` — LLM 通信(多后端) - `agentmain.py` — 会话编排 **交互界面**: diff --git a/agentmain.py b/agentmain.py index 64ec7aa..0e55355 100644 --- a/agentmain.py +++ b/agentmain.py @@ -5,7 +5,7 @@ if sys.stderr is None: sys.stderr = open(os.devnull, "w") elif hasattr(sys.stderr, 'reconfigure'): sys.stderr.reconfigure(errors='replace') sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) -from sidercall import SiderLLMSession, LLMSession, ToolClient, ClaudeSession, XaiSession +from llmcore import SiderLLMSession, LLMSession, ToolClient, ClaudeSession, XaiSession from agent_loop import agent_runner_loop, StepOutcome, BaseHandler from ga import GenericAgentHandler, smart_format, get_global_memory, format_error @@ -40,7 +40,7 @@ class GeneraticAgent: script_dir = os.path.dirname(os.path.abspath(__file__)) temp_dir = os.path.join(script_dir, 'temp') if not os.path.exists(temp_dir): os.makedirs(temp_dir) - from sidercall import mykeys + from llmcore import mykeys llm_sessions = [] for k, cfg in mykeys.items(): if not any(x in k for x in ['api', 'config', 'cookie']): continue diff --git a/assets/SETUP_FEISHU.md b/assets/SETUP_FEISHU.md index 3d132aa..f4b8ac3 100644 --- a/assets/SETUP_FEISHU.md +++ b/assets/SETUP_FEISHU.md @@ -22,7 +22,7 @@ - Python 3.8+ - 本项目完整代码 -- LLM API 密钥(Claude/OpenAI 等,已在 `sidercall/mykeys` 中配置) +- LLM API 密钥(Claude/OpenAI 等,已在 `llmcore/mykeys` 中配置) ### 安装依赖 @@ -177,7 +177,7 @@ fs_allowed_users = [ ### 确认 LLM 配置 -确保 `sidercall/mykeys` 中已配置 LLM API 密钥: +确保 `llmcore/mykeys` 中已配置 LLM API 密钥: ```python # 示例:Claude API diff --git a/assets/make_prompts.py b/assets/make_prompts.py index 8669ce6..1a46172 100644 --- a/assets/make_prompts.py +++ b/assets/make_prompts.py @@ -5,7 +5,7 @@ from pathlib import Path import subprocess import tempfile sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) -from sidercall import SiderLLMSession, LLMSession, ToolClient +from llmcore import SiderLLMSession, LLMSession, ToolClient ask = SiderLLMSession().ask diff --git a/sidercall.py b/llmcore.py similarity index 99% rename from sidercall.py rename to llmcore.py index 942dbe8..cb9ea89 100644 --- a/sidercall.py +++ b/llmcore.py @@ -14,8 +14,10 @@ mykeys = _load_mykeys() proxy = mykeys.get("proxy", 'http://127.0.0.1:2082') proxies = {"http": proxy, "https": proxy} if proxy else None -def compress_history_tags(messages, keep_recent=4, max_len=200): +def compress_history_tags(messages, keep_recent=10, max_len=500): """Compress // tags in older messages to save tokens.""" + compress_history_tags._cd = getattr(compress_history_tags, '_cd', 0) + 1 + if compress_history_tags._cd % 5 != 0: return messages for i, msg in enumerate(messages): if i < len(messages) - keep_recent and 'orig' not in msg: msg['orig'] = msg['prompt'] @@ -47,7 +49,7 @@ class SiderLLMSession: return full_text class ClaudeSession: - def __init__(self, api_key, api_base, model="claude-opus", context_win=10000): + def __init__(self, api_key, api_base, model="claude-opus", context_win=12000): self.api_key, self.api_base, self.default_model, self.context_win = api_key, api_base.rstrip('/'), model, context_win self.raw_msgs, self.lock = [], threading.Lock() def _trim_messages(self, messages): @@ -96,7 +98,7 @@ class ClaudeSession: return _ask_gen() if stream else ''.join(list(_ask_gen())) class LLMSession: - def __init__(self, api_key, api_base, model, context_win=12000, proxy=None, api_mode="chat_completions", + def __init__(self, api_key, api_base, model, context_win=16000, proxy=None, api_mode="chat_completions", max_retries=2, connect_timeout=10, read_timeout=120): self.api_key = api_key; self.api_base = api_base.rstrip('/'); self.default_model = model self.context_win = context_win; self.raw_msgs = []; self.messages = [] diff --git a/memory/autonomous_operation_sop.md b/memory/autonomous_operation_sop.md index 5c7f135..324610f 100644 --- a/memory/autonomous_operation_sop.md +++ b/memory/autonomous_operation_sop.md @@ -1,87 +1,38 @@ -# 自主行动 SOP (探测-报告-执行) - -⚠️ **路径警告**:autonomous_reports 在 temp/ 下,用`./autonomous_reports/`访问,**不是**`../memory/autonomous_reports/`或`../autonomous_reports/`! - -授权你进行自主行动,只要不对环境造成副作用都可进行。 -首先根据有无TODO确定**执行模式**或**任务规划模式** -如有TODO,进入**执行模式**,取一条TODO执行,完成后本轮结束(不继续执行下一条); -如果没有TODO,进入**任务规划模式**,深入分析并形成多个有价值的自主探索任务。规划完成后本轮结束,待下次自主行动执行。 +# 自主行动 SOP +⚠️ **路径警告**:autonomous_reports 在 temp/ 下,用`./autonomous_reports/`访问,**不是**`../memory/autonomous_reports/`或`../autonomous_reports/`!TODO在cwd下。 报告存于 `./autonomous_reports/`,文件名 `RXX_简短描述.md`(XX从 history.txt 推断自增)。 -## 任务规划模式 -- **有TODO**:cwd下 `TODO.txt` 有待执行条目 → 直接跳到「执行流程」 +授权你进行自主行动,只要不对环境造成副作用都可进行。 -价值公式:**「AI训练数据无法覆盖」×「对未来协作有持久收益」**。核心产出是记忆——有价值的发现整理为记忆更新提案纳入报告。 +## 任务选择 +- 有 `./TODO.txt`(temp根目录)未完成条目 → 取**一条**,直接进入执行,其他条目下次执行 +- 无 TODO → 读 `autonomous_operation_sop/task_planning.md` 规划,下次执行 +- 不连续两次选相同子任务 -流程入口: -- **无TODO → 进入任务规划模式**(本轮不执行任务,专注规划): - 0. update_working_checkpoint: `规划模式:产出TODO后立即结束本轮,禁止执行任何TODO,等待下次自主行动进入执行模式` - 1. ⚠️ **批判性读history.txt**:90%历史任务是低价值的,读取目的是**识别失败模式并避免**,而非寻找模仿对象 - - 识别低价值模式:浅层验证、无假设巡检、重复探索、泛采集、知名工具基础用法 - - 提炼高价值线索:未跟进的发现、待实测工具、可改进产出 - 2. 反思:为什么这些任务低价值?如何设计才能高价值? - 3. 批判性盘点已有报告和记忆(ls autonomous_reports/ + ../memory),考虑如何发挥更大价值或优化 - 4. 综合以上,产出5-7条TODO写入 `TODO.txt`,TODO已完成内容可压缩丢后面 - 5. 每条格式:`[ ] 类型(产出/冲浪/环境) | 一句话目标 | 验收标准` - 6. 召唤subagent评审TODO:input仅给TODO列表+"读记忆库自行判断,逐条评分1-10并简述理由"(不喂额外先验信息) - 7. 读subagent评分,低分项删除或替换 - 8. 立刻**结束**,下次行动再执行 +价值公式:**「AI训练数据无法覆盖」×「对未来协作有持久收益」** -目标排序(按价值递减): -1. **实用产出与能力扩展**:写工具解决痛点,在已有能力上解锁新能力(能力树每多一个节点,可能性空间变大) -2. **环境发现**:扫描已有但未利用的工具/库/数据源/配置 -3. **小众工具挖掘**:在GitHub/V2EX/吾爱破解/果核剥壳**等**找冷门实用工具,实测AI常推荐但有坑的方案 -4. **了解用户与推荐**:分析老代码/PC文件/书签推断偏好,给出个性化推荐(游戏/视频/工具附理由)(低频) -5. **自身演进**:思考框架不足,提出改进方案 -6. **记忆审查**:修正错误或过时记录 +## 执行 -**大型任务**:允许设计**有价值**的大型任务,将其分解成若干个模块或步骤,写入TODO中,每次自主行动执行处理一个模块。 +**启动**: +- update_working_checkpoint: `自主行动|报告→./autonomous_reports/R{XX}_简短描述.md|≤30回合|收尾:重读sop,写报告+更新history+标记TODO` +- 读 `./autonomous_reports/history.txt` 推断下一编号RXX + 了解历史避免重复 -选择原则:个性化优先(只有探测这台PC才能获得的知识)→ 盲区优先(自身参数无法复现,有一定难度)→ 假设驱动(明确要验证什么,边探测边实验)→ 禁止低价值验证(不验证静态配置、不做无假设巡检、不做你轻易完成的工作) +**执行**: +- ≤30回合,小步快跑,边探测边实验 +- 用临时脚本验证假设;禁只读即下结论,完整验证再写报告 +- 即使失败也记录实验过程和结果,失败报告同样有价值 +- 用户不在线,遇到需要决策的问题写入报告待审,不要卡住 -探测策略(聚焦原则,非菜单): -- **线索驱动**:从近期报告中提炼的后续任务,优先于凭空选题 -- **能力树扩展**:优先能解锁新能力节点的工具/技能(一个节点带来多种可能性) -- **个性化优先**:只有探测这台PC/这个用户才能获得的知识 > 通用知识 -- 冲浪规则:每次≤2话题,必须读正文提炼洞察,禁标题搬运;发现好工具→下轮TODO加实测任务 +**收尾(三件事缺一不可)**: +1. 写报告 `./autonomous_reports/R{XX}_简短描述.md`,格式简洁仅关键发现详述;若有记忆更新建议,附在报告末尾 +2. 更新 `./autonomous_reports/history.txt`(prepend一条:`RXX | 日期 | 类型 | 主题 | 结论`,严格单行,先读此文件头几行了解格式) +3. 在 `./TODO.txt`(temp根目录)中将已完成条目标记为 `[x]` -禁区:❌ Hacker News · 刷新闻头条 · 泛采集标题/无目标刷新闻 · 探索知名工具基础用法 · 调研弱于当前框架的agent · 调研其他web自动化/computer use框架 · 读取自身代码库 +## 权限边界 +- 无需批准:只读探测、cwd内写操作/脚本实验 +- 需写入报告待审:修改 global_mem / memory下SOP、安装软件、外部API调用、删除非临时文件 +- 绝对禁止:读取密钥、修改核心代码库、不可逆危险操作 - -## 执行模式 - -⚠️ **监工原则(硬约束)**:主agent在执行模式中**只当监工**,严禁亲自执行任务的实际工作。 -- ❌ 禁止:主agent自己写脚本跑数据、调API、扫描目录、处理文件等一切「干活」行为 -- ❌ 禁止:主agent以「为subagent准备数据」为由自己先执行部分工作 -- ✅ 允许:选任务、写input.txt(任务描述)、启动subagent、轮询监控、质检验收、更新history -- 原则:所有实际探测/数据收集/脚本编写/API调用都写进input.txt让subagent去做 - -### 执行(有TODO时) -0. 从 `TODO.txt` 取**一条**作为当前任务 -1. update_working_checkpoint: `{选定的当前任务}\n(自主行动时长期保留)subagent任务完成后需重读自主行动sop确定验收流程。每次只执行一个任务!` -2. 按 subagent_sop 召唤 subagent,input 需要包含以下全部内容: - - **任务**:详细介绍和要求深入执行当前任务 + 验收标准 + 一句话预期收益 - - **所有实际工作都由subagent完成**:包括数据收集、目录扫描、API调用、脚本编写等,主agent不做任何准备工作 - - **权限边界**:可执行只读和实验性操作;严禁修改核心记忆/系统设置;严禁读取敏感数据(可检测存在性);控制在30回合内 - - 无需批准:只读探测、cwd 内写操作/脚本实验 - - 需要报告:修改 global_mem.txt / memory/ 下 SOP、安装软件、外部 API 调用、删除非临时文件 - - 绝对禁止:读取密钥、修改核心代码库、不可逆危险操作 - - **报告要求**:完成后写报告到 `./autonomous_reports/R{XX}_简短描述.md`(XX从history.txt推断),格式简洁仅关键发现详述; - - 第一步先将此报告要求update_working_checkpoint进入工作记忆 - - **行动准则**:边探测边实验,用临时脚本测假设;禁只读即下结论,完整验证再写报告 -3. 监控 subagent 执行,质量不佳或跑偏可提前终止放弃(监控≠亲自干活) - -### 质检与验收流程 -4. subagent 完成后,读取报告进行质检: - - 报告是否符合格式(标题/分类/内容质量) - - 发现不合规可修正报告或回滚操作 - - 可通过 reply 机制追问 subagent -5. 更新 `./autonomous_reports/history.txt`(prepend,先读此文件了解填写格式) - - 在 history.txt 首行 prepend 一条:`RXX | 日期 | 类型 | 主题 | 结论`(严格单行)。 -6. 从 `TODO.txt` 移除已完成条目 -7. 若报告含记忆更新建议,评估后决定是否采纳;若发现极有价值高质量报告,可在报告文件名上标记。 -8. 停止,等待下次自主行动 - -### 等待用户审查 -- 用户归来后审查报告,决定批准、修改或拒绝方案 +## 等待用户审查 +- 用户归来后审查报告,决定批准、修改或拒绝方案 \ No newline at end of file diff --git a/tgapp.py b/tgapp.py index 8ccb75d..3064c0e 100644 --- a/tgapp.py +++ b/tgapp.py @@ -8,7 +8,7 @@ try: except: print("Please ask the agent install python-telegram-bot to use telegram module.") sys.exit(1) -from sidercall import mykeys +from llmcore import mykeys agent = GeneraticAgent() agent.verbose = False