重新梳理所有提示词职责

This commit is contained in:
hc 2026-04-13 14:35:22 +08:00
parent a3256d15f4
commit 33e8704458
5 changed files with 98 additions and 83 deletions

View File

@ -1,79 +1,39 @@
# AGENTS.md
你是 `cc-slim`,一个只能基于当前仓库与用户输入行动的本地极简代理
这是当前 workspace 的项目级规则文件
## 行动边界
## 工作区规则
- 你只能依据以下信息行动:
- 当前仓库中的文件
- 当前用户输入
- 工具返回的结果
- 不要假设任何尚未看到的文件、命令、接口、配置或能力存在。
- 信息缺失时,采用最小默认策略,并在最终回答里简短说明该默认策略。
- 当前 workspace 是默认操作边界,不应主动读写工作区外文件,也不应主动探索无关路径。
- `AGENTS.md`、`SKILLS/` 与代码文件都属于当前 workspace 输入,不属于程序内置 prompt。
- 行动时必须以运行时注入的环境信息为准特别是平台、shell、workspace 和可用工具列表。
- 当前 harness 是极简实现,优先最小动作,不做不必要的重复试错。
## 默认策略
## 交互规则
当用户请求处理仓库内任务时,按以下最小闭环执行:
- REPL 内所有 slash command 由程序直接处理,不进入 agent loop。
- REPL 会显示当前模式提示符,例如 `build >``plan >`
- `/clear` 是清空当前上下文的主别名,等价于 `/new`
1. 先判断运行时状态、已有上下文和当前用户输入是否已经足以决定下一步。
2. 只有在减少不确定性或执行动作确有必要时,才检查最相关的文件或调用工具。
3. 选择最小的下一步动作。
4. 使用工具后重新判断结果。
5. 持续循环,直到得到最终答案或出现必须由用户补充的信息。
## 模式与权限
当前 harness 是极简实现,优先最小动作,不做不必要的重复试错。
- 支持 `/mode build``/mode plan` 两种模式,`plan` 为只读规划模式。
- 写操作和 Bash 默认需要确认,可通过 `--auto-approve``/permissions auto-on` 跳过。
- 工作区外访问和 `plan` 模式限制属于硬性边界,不通过审批放行。
行动时必须以运行时注入的环境信息为准特别是平台、shell、工作目录和可用工具列表。
## Memory 与验证
当前 workspace 是默认操作边界,不应主动读写工作区外文件,也不应主动探索无关路径。
- 当前项目支持最小 memory使用 `/remember` 保存长期信息,使用 `/memory` 查看。
- session 是原始对话历史,不直接拼进 system promptmemory 才作为长期补充进入 prompt。
- 默认语言:中文优先。
- 默认验证:优先做最小可验证检查,不夸大成功状态。
REPL 内的会话管理命令优先使用 slash command。
## 工具偏好
REPL 内所有 slash command 由程序直接处理,不进入 agent loop。
REPL 会显示当前模式提示符,例如 `build >``plan >`
当前项目支持最小 memory使用 `/remember` 保存长期信息,使用 `/memory` 查看。
写操作和 Bash 默认需要确认,可通过 `--auto-approve``/permissions auto-on` 跳过。
工作区外访问和 `plan` 模式限制属于硬性边界,不通过审批放行。
支持 `/mode build``/mode plan` 两种模式,`plan` 为只读规划模式。
`/clear` 是清空当前上下文的主别名,等价于 `/new`
未明确说明时,使用以下默认值:
- 工作目录:当前进程目录
- 文件编码:`utf-8`
- Shell 执行:按原样执行单条命令
- 输出风格:简洁、直接
- 路径不明确:先检查再操作
- 需求有歧义:采用仍能推进任务的最窄解释
## 工具使用规则
- `Read`:用于读取文件内容。
- 需要按文件名或路径模式查找时,优先使用 `Glob`
- 需要搜索文件内容时,优先使用 `Grep`
- 默认只应在当前 workspace 内读写和执行与项目相关的操作。
- 修改已有文件内容时,优先使用 `Edit` 工具。
- 创建新文件时,优先使用 `Write` 工具。
- `Bash`:用于执行必须通过 shell 完成的最小命令。
- 只有在确实需要复杂 shell 特性时才使用 Bash。
- 不要用 Bash 拼接文件内容。
- 修改已有文件内容时,优先使用 `Edit`
- 创建新文件时,优先使用 `Write`
- 只有在确实需要复杂 shell 特性时才使用 `Bash`
- 不要用 `Bash` 拼接文件内容。
- Windows 环境下优先使用兼容写法,不默认使用 `cat <<EOF`、`ls -la` 等 Unix 风格写法。
- 同一写入或创建目标,最多尝试 2 种不同 Bash 方案。
- 如果两次 Bash 方案失败,应立即收敛:
- 先检查路径、文件状态、shell 兼容性。
- 如仍不确定,则询问用户,而不是继续盲试。
- 不能虚构工具输出。
- 不能在未验证前声称文件存在、命令成功或修改已生效。
## 回答规则
- 对不确定性保持诚实。
- 需要时引用具体文件或命令。
- 输出保持简短直接,不夸大成功状态。
- 若受阻,只询问当前缺失的关键信息。

View File

@ -28,7 +28,7 @@
- 长期有价值的项目约束或偏好,优先使用 `/remember` 保存
- 高风险操作会触发确认,优先先读再改,减少无意义审批
- 复杂任务可先切换到 `/mode plan` 进行规划,再切换回 `/mode build` 执行
- 先在 workspace 内定位和操作,避免无关路径探索
- workspace 是当前默认操作边界,先在 workspace 内定位和操作,避免无关路径探索
- Windows 下先验证 shell 兼容性,再选择命令写法
## 沟通风格

View File

@ -157,23 +157,45 @@ class Agent:
def _build_system_prompt(self, workspace: Path) -> str:
parts: list[str] = []
parts.append(self._load_builtin_system_prompt())
parts.append(self._build_runtime_summary(workspace))
agents = workspace / "AGENTS.md"
if agents.exists():
parts.append(agents.read_text(encoding="utf-8"))
workspace_agents = self._load_workspace_agents(workspace)
if workspace_agents:
parts.append(workspace_agents)
skills_dir = workspace / "SKILLS"
if skills_dir.exists():
for path in sorted(skills_dir.glob("*.md"), key=lambda p: p.name):
parts.append(path.read_text(encoding="utf-8"))
parts.extend(self._load_workspace_skills(workspace))
memory = MemoryStore(workspace).read()
if memory:
parts.append(f"# Memory\n\n{memory}")
memory_prompt = self._load_memory_prompt(workspace)
if memory_prompt:
parts.append(memory_prompt)
return "\n\n".join(part.strip() for part in parts if part.strip())
def _load_builtin_system_prompt(self) -> str:
return (Path(__file__).resolve().parent / "system.md").read_text(encoding="utf-8")
def _load_workspace_agents(self, workspace: Path) -> str:
agents = workspace / "AGENTS.md"
if not agents.exists():
return ""
return agents.read_text(encoding="utf-8")
def _load_workspace_skills(self, workspace: Path) -> list[str]:
skills: list[str] = []
skills_dir = workspace / "SKILLS"
if not skills_dir.exists():
return skills
for path in sorted(skills_dir.glob("*.md"), key=lambda p: p.name):
skills.append(path.read_text(encoding="utf-8"))
return skills
def _load_memory_prompt(self, workspace: Path) -> str:
memory = MemoryStore(workspace).read()
if not memory:
return ""
return f"# Memory\n\n{memory}"
def _build_runtime_summary(self, workspace: Path) -> str:
tool_names = ", ".join(self.tools.keys()) or "(none)"
shell_name = self._detect_shell()

View File

@ -106,24 +106,24 @@ def run(
model: Optional[str] = typer.Option(None, help="模型名称"),
api_key: Optional[str] = typer.Option(None, help="API Key优先级最高"),
base_url: Optional[str] = typer.Option(None, help="可选的 API Base URL"),
cwd: Path = typer.Option(Path("."), help="工作区根目录"),
workspace: Path = typer.Option(Path("."), "--workspace", help="要操作的工作区根目录"),
max_turns: Optional[int] = typer.Option(None, help="最大工具循环轮数"),
history: bool = typer.Option(False, "--history", help="列出当前工作目录的历史 session"),
resume: Optional[str] = typer.Option(None, "--resume", help="按 session id 或序号恢复历史 session"),
auto_approve: bool = typer.Option(False, "--auto-approve", help="跳过高风险工具确认"),
) -> None:
root = cwd.resolve()
store = SessionStore(root)
memory = MemoryStore(root)
workspace_root = workspace.resolve()
store = SessionStore(workspace_root)
memory = MemoryStore(workspace_root)
mode = ModeState()
permissions = PermissionChecker(root, auto_approve=auto_approve)
permissions = PermissionChecker(workspace_root, auto_approve=auto_approve)
permissions.set_mode(mode.mode)
if history:
render_history(store)
return
config = resolve_config(
root,
workspace_root,
{
"provider": provider,
"model": model,
@ -142,7 +142,7 @@ def run(
else:
session_meta = store.create_session(config.model)
agent = build_agent(root, config, store, permissions, session_meta, restored_history)
agent = build_agent(workspace_root, config, store, permissions, session_meta, restored_history)
if prompt:
render_stream(agent, prompt)
@ -166,7 +166,7 @@ def run(
agent = handle_command(
user_input,
console=console,
root=root,
root=workspace_root,
config=config,
store=store,
memory=memory,

33
src/cc_slim/system.md Normal file
View File

@ -0,0 +1,33 @@
# cc-slim System
你是 `cc-slim`,一个本地极简代理。
## 基本原则
- 只能依据以下信息行动:
- 当前用户输入
- 当前仓库文件
- 工具返回结果
- 不要假设任何尚未看到的文件、命令、接口、配置或能力存在。
- 信息缺失时,采用最小默认策略,并在最终回答中简短说明。
## 工具原则
- 只有在减少不确定性或执行动作确有必要时才使用工具。
- 优先选择更小、更直接的动作。
- 不能虚构工具输出。
- 不能在未验证前声称文件存在、命令成功或修改已生效。
## 行动策略
1. 先判断当前上下文是否已经足够决定下一步。
2. 如需减少不确定性,读取最相关的文件或调用最小工具。
3. 执行最小下一步动作。
4. 根据结果重新判断。
5. 持续循环,直到得到最终答案或出现必须由用户补充的信息。
## 输出风格
- 保持简洁、直接、可验证。
- 优先给出事实,而不是泛泛解释。
- 对不确定性保持诚实。