diff --git a/assets/sys_prompt.txt b/assets/sys_prompt.txt index de0fc7f93..6e80d52f4 100644 --- a/assets/sys_prompt.txt +++ b/assets/sys_prompt.txt @@ -2,5 +2,7 @@ 你拥有文件读写、脚本执行、用户浏览器JS注入、系统级干预的物理操作权限。禁止推诿"无法操作"——不空想,用工具探测。 ## 行动原则 调用工具前先推演:当前阶段、上步结果是否符合预期、下步策略,必须在回复文本中用输出极简总结。 +- Skill优先:开始任务前先查看系统上下文中的 [Skill/SOP Index]。如果存在相关 skill/SOP,必须先读取对应 `memory/*.md` 文件并按其约束执行;找不到合适 skill 时再自行分析处理。 +- Skill规范:新增或沉淀 `memory/*.md` skill/SOP 时,文件开头必须包含 `name: xxx` 和 `description: xxx` 两行,description 用一句话说明适用场景。 - 探测优先:失败时先充分获取信息(日志/状态/上下文),关键信息存入工作记忆,再决定重试或换方案。不可逆操作先询问用户。 - 失败升级:1次→读错误理解原因,2次→探测环境状态,3次→深度分析后换方案或问用户。禁止无新信息的重复操作。 diff --git a/assets/sys_prompt_en.txt b/assets/sys_prompt_en.txt index c0411ab93..da141796b 100644 --- a/assets/sys_prompt_en.txt +++ b/assets/sys_prompt_en.txt @@ -3,5 +3,7 @@ You have full physical access: file I/O, script execution, browser JS injection, Summarize and reply in user's language or follow user's prompt. ## Action Principles Before each tool call, reason: current phase, whether the last result met expectations, and next strategy and in reply text of each turn. +- Skill first: before starting a task, scan [Skill/SOP Index] in the system context. If a relevant skill/SOP exists, read the corresponding `memory/*.md` file before implementing and follow its constraints; only solve from scratch when no suitable skill exists. +- Skill format: when creating or distilling a new `memory/*.md` skill/SOP, the file must start with `name: xxx` and `description: xxx`; description should state the applicable scenario in one sentence. - Probe first: on failure, gather sufficient info (logs/status/context), store key findings in working memory, then decide to retry or pivot. Ask the user before irreversible operations. - Failure escalation: 1st fail → read error and understand cause; 2nd → probe environment state; 3rd → deep analysis then switch approach or ask user. Never repeat an action without new information. \ No newline at end of file diff --git a/ga.py b/ga.py index c2e5681da..cb1b9612d 100644 --- a/ga.py +++ b/ga.py @@ -575,6 +575,57 @@ def turn_end_callback(self, response, tool_calls, tool_results, turn, next_promp for hook in getattr(self.parent, '_turn_end_hooks', {}).values(): hook(locals()) # current readonly return next_prompt +def _parse_skill_metadata(path): + name = "" + description = "" + fallback_heading = "" + fallback_description = "" + try: + with open(path, 'r', encoding='utf-8', errors='replace') as f: + lines = f.read(2048).splitlines() + except OSError: + return os.path.splitext(os.path.basename(path))[0], "" + + for line in lines[:20]: + stripped = line.strip() + lower = stripped.lower() + if lower.startswith('name:'): + name = stripped.split(':', 1)[1].strip() + elif lower.startswith('description:'): + description = stripped.split(':', 1)[1].strip() + + if stripped.startswith('#') and not fallback_heading: + fallback_heading = stripped.lstrip('#').strip() + elif stripped and not stripped.startswith('#') and not fallback_description: + fallback_description = stripped[:120] + + if name and description: + break + + if not name: + name = fallback_heading or os.path.splitext(os.path.basename(path))[0] + if not description: + description = fallback_description + return name, description + + +def _format_skill_index(): + memory_dir = os.path.join(script_dir, 'memory') + skill_paths = sorted(Path(memory_dir).glob('*.md')) + if not skill_paths: + return "" + + lines = ["\n[Skill/SOP Index] Before acting, scan this index first. If a relevant skill exists, read that file before implementing."] + for path in skill_paths: + name, description = _parse_skill_metadata(str(path)) + relative_path = os.path.relpath(path, script_dir) + if description: + lines.append(f"- {relative_path} | name: {name} | description: {description}") + else: + lines.append(f"- {relative_path} | name: {name} | description: ") + return "\n".join(lines) + "\n" + + def get_global_memory(): prompt = "\n" try: @@ -585,5 +636,6 @@ def get_global_memory(): prompt += f"\n[Memory] (../memory)\n" prompt += structure + '\n../memory/global_mem_insight.txt:\n' prompt += insight + "\n" + prompt += _format_skill_index() except FileNotFoundError: pass return prompt