Skip to content
Closed
752 changes: 752 additions & 0 deletions docs/comparison/qwen-code-improvement-report-p1-arch.md

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions docs/comparison/qwen-code-improvement-report-p1-command-namespace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Qwen Code 改进建议 — P1 命令命名空间治理

> 命令系统改进项:当 built-in commands、文件命令、extension commands、MCP prompt commands 同时存在时,除了“能加载”,还需要解决命名冲突、来源隔离、前缀策略与治理边界。
>
> 返回 [改进建议总览](./qwen-code-improvement-report.md)

---

<a id="item-1"></a>

### 1. Slash Command Namespace Governance / 命令命名空间治理(P1)

**思路**:Qwen Code 的 slash command 系统已经进入“平台化”阶段,而不再只是几十个内置命令。当前至少有四类来源会往命令空间里注入名字:

1. built-in commands
2. user / project 文件命令
3. extension commands
4. MCP prompt commands

当来源越来越多时,真正的挑战不再是“怎么加载命令”,而是:

- 谁可以占用顶级命令名?
- 重名时谁覆盖谁?
- extension 是否必须带命名空间前缀?
- MCP prompt 暴露成 slash command 时,是否应默认隔离到 server namespace?
- 用户如何知道某个命令来自 built-in、extension 还是 MCP?
- 团队/企业如何禁用某些来源或保留关键命令名?

Claude Code 在这方面采取的是更保守的合并策略:命令合并时倾向于保持稳定、可预测的名字集合;插件命令则走独立管理路径。Qwen Code 当前虽然有基础冲突处理,但规则仍偏“实现导向”,还没有发展成完整的 namespace governance。

**Claude Code 源码索引**:

| 文件 | 关键函数/常量 |
|------|-------------|
| `hooks/useMergedCommands.ts` | `uniqBy([...initialCommands, ...mcpCommands], 'name')`,保持命令名唯一 |
| `services/plugins/pluginCliCommands.ts` | 插件命令走独立 CLI 管理入口(install/uninstall/enable/disable/update) |
| `commands.ts` | 命令总表与内置命令体系 |

**Qwen Code 现状**:`packages/cli/src/services/CommandService.ts` 会并行加载所有 loader 返回的命令,然后统一放入一个 `Map<string, SlashCommand>`。当前冲突规则是:

- 如果是 extension command 且名字冲突,则自动改名为 `extensionName.commandName`,必要时再追加数字后缀;
- 非 extension commands(built-in / user / project / MCP prompt)则按 loader 顺序“后者覆盖前者”;
- `packages/cli/src/services/McpPromptLoader.ts` 会把 MCP prompt 直接暴露为 slash command 名,不默认带 server namespace。

这套策略“能工作”,但存在几个隐患:

1. **顶级命令名竞争**:MCP prompt 与 user/project 命令都可能占用短名字;
2. **来源不透明**:用户看到 `/deploy`,并不知道它来自 project file command、某个 MCP server prompt,还是 extension;
3. **覆盖策略不够显式**:非 extension 冲突靠 loader 顺序决定,行为可预测但不够易理解;
4. **治理能力不足**:缺少 reserved names、per-source enable/disable、source visibility 等平台机制。

**Qwen Code 修改方向**:
1. 为 slash command 引入显式 `source namespace` 概念,例如:
- built-in: `/model`
- extension: `/ext.foo.bar`
- MCP prompt: `/mcp.github.review`
- file command: `/local.deploy`
2. 对用户常用命令保留短别名,但短别名应由治理层决定,而不是“谁最后加载谁赢”;
3. 在补全列表与帮助界面中显示命令来源(built-in / extension / MCP / local);
4. 增加 reserved name 策略,防止扩展或 MCP prompt 抢占关键命令;
5. 增加 per-source enable/disable 配置,方便团队/企业限制命令暴露面;
6. 对 MCP prompt 默认使用 `serverName.promptName` 命名,避免直接污染顶级命令空间。

**实现成本评估**:
- 涉及文件:~4 个
- 新增代码:~220 行
- 开发周期:~3 天(1 人)
- 难点:兼容现有短命令习惯,避免破坏已有用户工作流

**改进前后对比**:
- **改进前**:所有来源往同一个命令表注册——extension 有改名兜底,但 user/project/MCP prompt 之间仍可能靠加载顺序决定覆盖关系
- **改进后**:每类命令先进入各自 namespace,再由治理层决定哪些短别名暴露到顶级空间——冲突规则清晰、来源可见、企业可控

**意义**:命令系统一旦可扩展,就必须治理命名空间。
**缺失后果**:命令来源越多,顶级命令空间越混乱——冲突、覆盖、误调用会越来越频繁。
**改进收益**:命令来源透明 + 冲突策略清晰 + 保留字治理,让 slash command 系统从“加载器集合”升级为“可管理的平台能力”。

---

## 为什么这不是现有 slash command / MCP 文档的重复

- 现有 slash command 对比更多回答“有哪些命令”;
- MCP 集成对比更多回答“能否接入 MCP”;
- 本文讨论的是:**当命令来源变多后,命令名如何治理、如何隔离、如何防冲突**。

也就是说,它关注的是 **命令平台治理**,不是命令功能列表。

---

## 可分阶段演进路径

| 阶段 | 能力 | 说明 |
|------|------|------|
| Stage 1 | source 可视化 | 补全列表/帮助页展示命令来源 |
| Stage 2 | MCP / extension 默认命名空间 | 避免顶级命令空间污染 |
| Stage 3 | reserved names + alias policy | 保留关键短命令,统一别名分配 |
| Stage 4 | team policy | 团队/企业按来源禁用命令或限定前缀 |

这样 Qwen Code 的命令系统才能在继续开放扩展的同时保持可预测性。

---

## 相关文章

- [内置命令总览](./slash-commands-deep-dive.md)
- [MCP 集成深度对比](./mcp-integration-deep-dive.md)
- [Qwen Code 改进建议总览](./qwen-code-improvement-report.md)
78 changes: 78 additions & 0 deletions docs/comparison/qwen-code-improvement-report-p1-hooks-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Qwen Code 改进建议 — P1 Hook Runtime 扩展

> Hook 运行时改进项:从 shell command-only 扩展到多后端执行模型,支持 Prompt Hook、异步 Hook 编排与更强的语义策略能力。
>
> 返回 [改进建议总览](./qwen-code-improvement-report.md)

---

<a id="item-1"></a>

### 1. Prompt Hooks / LLM 语义 Hook(P1)

**思路**:当前 Qwen Code 的 Hook 已有较完整的事件总线(`PreToolUse`、`PostToolUse`、`Notification`、`SessionStart` 等),但执行器本质上仍只有 `type: "command"`——所有 Hook 都必须落到 shell 命令。这样虽然足够通用,却不适合“语义判断”类场景:例如“这次 `git push` 是否违反团队发布策略?”、“本次工具调用是否与当前任务目标冲突?”、“这段用户输入是否包含敏感数据,应该先二次确认?”。

Claude Code 在 shell / HTTP 之外,还支持 **Prompt Hook**:把 Hook prompt 连同当前上下文交给一个小模型执行,要求模型返回严格 JSON(`{ok:true}` 或 `{ok:false, reason:"..."}`)。这使 Hook 从“脚本式规则”扩展为“语义策略判断器”。适合 shell/regex 难以表达的治理场景。

**Claude Code 源码索引**:

| 文件 | 关键函数/常量 |
|------|-------------|
| `utils/hooks/execPromptHook.ts` | `execPromptHook()`,调用小模型执行 Hook prompt,强制 `json_schema` 输出 |
| `types/hooks.ts` | Hook 类型体系、sync/async JSON 响应协议、Prompt/Callback Hook 类型定义 |
| `utils/hooks/AsyncHookRegistry.ts` | 异步 Hook 注册、进度轮询、stdout JSON 响应解析 |

**Qwen Code 现状**:Hook 类型仍是单一 `command`。`packages/core/src/hooks/types.ts` 中 `HookType` 仅有 `Command`,`HookConfig = CommandHookConfig`;`packages/core/src/hooks/hookRunner.ts` 也只实现 `executeCommandHook()`。这意味着即使事件体系很丰富,运行时仍局限于 shell 脚本 + stdin/stdout JSON。

**Qwen Code 修改方向**:
1. `packages/core/src/hooks/types.ts` 扩展 `HookType`:在 `command` 之外新增 `prompt`(后续也可继续扩展 `http`、`callback`);
2. 新建 `packages/core/src/hooks/execPromptHook.ts`:复用现有模型调用栈,采用小模型执行 Hook prompt;
3. 要求 Prompt Hook 输出严格 JSON Schema,避免自由文本导致的不确定性;
4. 在 `hookRunner.ts` 增加分发逻辑:`type === 'prompt'` 时走 LLM Hook 分支;
5. 在 `hooksCommand.ts` / Hook UI 中展示 Hook 类型、模型、超时与阻断原因。

**实现成本评估**:
- 涉及文件:~5 个
- 新增代码:~250 行
- 开发周期:~3 天(1 人)
- 难点:Hook prompt 的安全边界与超时控制

**改进前后对比**:
- **改进前**:Hook 只能执行 shell 命令——复杂语义检查需要开发者自己写脚本、调用外部模型、再拼 JSON 返回
- **改进后**:`type: "prompt"` 直接把语义判断下沉到 Hook Runtime——可用小模型做轻量审批、策略校验、提示增强

**意义**:很多治理策略本质是语义问题,而不是字符串匹配问题。
**缺失后果**:复杂 Hook 只能壳套壳——shell 调脚本,脚本再调模型,配置脆弱且调试困难。
**改进收益**:Prompt Hook 让 Hook 成为一等语义策略层——更适合审批、安全、规范、上下文增强。

---

## 为什么这不是现有“HTTP Hooks / Conditional Hooks”的重复

- **Conditional Hooks** 解决的是“哪些 Hook 应该触发”;
- **HTTP Hooks** 解决的是“Hook 是否可以直接请求远程服务”;
- **Prompt Hooks / Hook Runtime 扩展** 解决的是“Hook Runtime 本身是否支持多执行后端,尤其是 LLM 语义执行”。

三者分别对应 **触发条件**、**传输通道**、**执行模型**,不是同一个层次的问题。

---

## 进一步演进方向

如果后续继续向 Claude Code 靠拢,Qwen Code 的 Hook Runtime 可以按下面路径递进演化:

| 阶段 | 能力 | 说明 |
|------|------|------|
| Stage 1 | `command` + `prompt` | 本地脚本与 LLM 语义判断双后端 |
| Stage 2 | 统一 async registry | 所有 Hook 类型共享异步调度、超时、进度与结果回传 |
| Stage 3 | typed hook backends | `http` / `callback` / `remote-policy` 等可插拔执行器 |
| Stage 4 | explainability | 展示“哪个 Hook 阻断了继续执行、原因是什么、来自哪层策略” |

这样 Hook 系统才能从“事件很多的 shell 执行器”升级为“可扩展的策略运行时”。

---

## 相关文章

- [Hook/插件扩展深度对比](./hook-plugin-extension-deep-dive.md)
- [Qwen Code 改进建议总览](./qwen-code-improvement-report.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Qwen Code 改进建议 — P1 权限决策可解释性

> 权限系统改进项:不仅要“做出 allow / ask / deny 决策”,还要向用户解释“为什么会这样判定、命中了哪条规则、下一步如何调整”。
>
> 返回 [改进建议总览](./qwen-code-improvement-report.md)

---

<a id="item-1"></a>

### 1. Permission Decision Trace / 权限决策解释链(P1)

**思路**:Qwen Code 这两版在权限引擎层面其实已经不弱:支持 `allow / ask / deny` 三类规则、session/persistent 两级规则、shell compound command 拆分、shell virtual operations 推导(把 `cat` / `curl` / redirect 等映射为 `read_file` / `web_fetch` / `write_file`),还会用 AST 判断 shell 命令是否只读。这意味着它已经能“算出一个合理决策”。

问题在于,**用户几乎看不到这条决策链**。

当一个工具调用被拒绝或要求确认时,用户真正想知道的是:

- 是哪一条规则命中了?
- 是 shell 规则命中,还是 virtual file/web 规则命中?
- 是 `deny` 规则覆盖了 `allow`,还是没有任何规则命中而回退到默认模式?
- 如果我想放行,应该改 `/permissions` 里的哪条规则?
- 如果是 Hook 导致 ask/block,具体是哪一个 Hook?

Claude Code 在这方面明显更成熟:不仅有权限判定,还有一整套 **decision reason → UI explanation → debug info** 链路。它把“结果”与“原因”一起展示,让权限系统从黑盒变成可调试、可学习的交互系统。

**Claude Code 源码索引**:

| 文件 | 关键函数/常量 |
|------|-------------|
| `components/permissions/PermissionDecisionDebugInfo.tsx` | 展示 decision reason、rule/hook/mode/classifier/sandboxOverride/workingDir 等来源 |
| `components/permissions/PermissionRuleExplanation.tsx` | 把 `decisionReason` 转成用户可读解释,并给出 `/permissions` / `/hooks` 调整提示 |
| `components/permissions/PermissionExplanation.tsx` | 懒加载权限解释,展示 risk level / explanation / reasoning |
| `hooks/toolPermission/PermissionContext.ts` | 权限上下文状态 |
| `hooks/toolPermission/permissionLogging.ts` | 权限日志记录 |
| `tools/BashTool/commandSemantics.ts` | shell 语义分类辅助解释 |

**Qwen Code 现状**:权限判定逻辑很强,但可解释性弱。`packages/core/src/permissions/permission-manager.ts` 负责规则优先级计算(`deny > ask > allow > default`),还会结合 `extractShellOperations()` 做 shell virtual operation 判定;但返回结果主要是最终 decision,没有面向 UI 的“命中链路对象”。`packages/cli/src/ui/components/PermissionsDialog.tsx` 更像规则管理器:列出 allow/ask/deny 规则、支持搜索/增删,却不展示“某次具体决策为何发生”。用户能改规则,却不容易理解当前规则系统到底是怎么工作的。

**Qwen Code 修改方向**:
1. 在 `permission-manager.ts` 中新增 explain 模式:除了最终 decision,还返回 `decisionTrace`,至少包括:
- 命中的规则(类型、来源、原始 rule 文本)
- 是否发生 deny/ask 覆盖
- 是否来自 shell virtual operations
- 是否走了默认回退
2. 在 shell 场景下,把 `extractShellOperations()` 的推导结果挂入 trace,让用户知道“`cat foo` 为何等价于 `read_file(foo)`”;
3. 在工具确认 UI 中增加“Why?”/“Explain”视图,展示命中链和建议操作;
4. 在 `/permissions` 界面中增加“最近一次命中示例”或 dry-run tester,方便用户调试规则;
5. 后续可与 Hook Runtime 联动:若是 Hook 导致 ask/block,也统一走同一套 decision trace UI。

**实现成本评估**:
- 涉及文件:~5 个
- 新增代码:~250 行
- 开发周期:~3 天(1 人)
- 难点:在不破坏现有权限 API 的前提下为 UI 暴露结构化 trace

**改进前后对比**:
- **改进前**:用户只看到“被拒绝 / 需要确认”——但不知道是哪条规则、哪个层级、哪种语义命中导致的
- **改进后**:用户可看到完整 decision trace——例如“命中 project deny 规则 `WriteFile(/secrets/**)`,同时 shell 语义推导出 `echo > secrets.txt` 属于写文件操作,因此最终为 deny”

**意义**:权限系统越强,越需要 explainability。否则规则一多,用户只能靠试错。
**缺失后果**:权限引擎是黑盒——用户难以调试规则,常见结果是要么过度放权,要么频繁误拦截。
**改进收益**:decision trace 让权限系统可学习、可调试、可审计——特别适合复杂 shell、团队策略和企业治理场景。

---

## 为什么这不是现有“Denial Tracking / 权限对话框文件预览”的重复

- **Denial Tracking** 解决的是“连续拒绝后如何自动回退模式”;
- **权限对话框文件预览** 解决的是“审批时展示将要修改的文件内容”;
- **Permission Decision Trace** 解决的是“这次 allow / ask / deny 到底是怎么推导出来的”。

三者分别是 **回退策略**、**审批信息展示**、**决策可解释性**,层次不同。

---

## 可分阶段落地的演进路径

| 阶段 | 能力 | 说明 |
|------|------|------|
| Stage 1 | 基础 decision trace | 命中 rule、source、default fallback、virtual ops |
| Stage 2 | 确认 UI explain 面板 | 在工具确认框中展示“为什么 ask/deny” |
| Stage 3 | `/permissions test` dry-run | 给一条工具调用/命令,输出命中链与最终结果 |
| Stage 4 | 审计与导出 | 记录最近 N 次权限判定链,便于排障与企业审计 |

这样 Qwen Code 的权限系统才能从“规则引擎”进一步升级为“可调试的权限平台”。

---

## 相关文章

- [Hook Runtime 扩展](./qwen-code-improvement-report-p1-hooks-runtime.md)
- [Hook/插件扩展深度对比](./hook-plugin-extension-deep-dive.md)
- [Qwen Code 改进建议总览](./qwen-code-improvement-report.md)
Loading