deepseek-harness/.agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.zh.md
Tianyi Cui 5569f3f8ac docs: repair rewritten rationale and stale claims from the ACP reduction
The automation-only rewrite edited many implemented Agent Notes; several
edits replaced still-live or historical rationale instead of reframing:

- llm-model-catalog: restore the prompt/request consistency section and
  selection-ownership alternatives — installAgentLlmTarget and the TUI
  /model selector still ship that design; only the ACP wire is gone.
- plan-specific-collaboration-state, acp-multi-session, todo-write,
  ask-user-question: link the superseding automation-only note instead
  of silently rewriting the original decision or motivation; drop a
  paragraph duplicating the Web-provider facts stated two paragraphs up.
- sandbox: stop claiming unit coverage for turn-enclosed config writes
  (that mechanism left with the bridge) and retitle the commit-boundary
  paragraph accordingly.
- Fix the missing blank line before '## Consequences' in the
  plugin-command-registration pair, the JSON-RPC/Web render-intent
  consumer misattribution (the second consumer is the host/client
  runtime), stale bash_output/bash_kill names, and 'optional goals' in
  architecture.md.
- examples/acp-agent/README.md: point at the package contract instead
  of restating it; packages/ui/permission and plan-mode READMEs record
  the consumer-less preset service and the exit_plan_mode coverage gap
  under Known Limitations.
- 2026-06-19-acp-snapshot-tests: the new note defers the corpus
  migration rather than committing to it; say so.

Re-record the touched bilingual pairs.
2026-07-24 22:12:23 +08:00

6.1 KiB
Raw Blame History

Agent Note: 建议性 LLM 目录与 ACP 会话级模型选择

Status: implemented

English | 中文

目录决策仍然有效。ACP 会话级模型选择已由 ACP 作为仅面向自动化的协议取代。

问题

基于提供方路由的适配器允许每次请求选择 provider + model,但 LlmService 只暴露路由和流式调用。UI 无法发现已注册的提供方,也无法知道适配器愿意推荐哪些模型。因此,ACP 客户端收不到 model 会话配置项;即使请求接缝已经支持运行时切换,Zed、JetBrains 和 VS Code 集成仍没有模型列表。

模型发现不能变成请求校验。手写 DeepSeek 适配器会把任意模型 ID 原样转发给公开或私有端点,而 pi-ai 的有限安装目录则是其自身请求解析的权威依据。将共享目录视为白名单,会破坏提供方路由需要保留的私有端点能力。

ACP 选择还必须保留提供方维度。同一个模型 ID 可能存在于多个路由下;切换全局适配器或 agent 模板会让一个编辑器会话的选择泄漏到其他会话。Prompt 变量与请求路由必须同时变化;如果选择发生在异步 prompt 组装期间,不能让 {{model}} 表示一个模型、实际请求却到达另一个模型。

决策

提供方无关的建议性发现

LlmAdapter 增加 providerInfo(provider) 与异步 listModels(provider) 方法。其提供方无关结果分别为 LlmProviderInfo { id, name } 和 LlmModelInfo { provider, id, name, description? }。默认实现以路由名称作为提供方名称,并且不展示模型,从而保持现有适配器行为。

LlmService.listProviders() 按注册顺序返回分离后的元数据。LlmService.listModels(provider) 委托给路由所有者,校验非空 ID 和名称,并在提供方不匹配或模型 ID 重复时以 INVALID_CATALOG 失败,最后返回分离后的值。未知提供方仍以 NO_ADAPTER 失败。提供方元数据在 registerAdapter() 期间进行原子校验,错误展示记录不会留下部分注册。

目录成员关系仅提供建议。它驱动选择器与诊断,但不会改变 stream() 路由,也不会拒绝原本有效的请求。提供方所有权仍然具有排他性并绑定生命周期;模型 ID 仍是请求时传给适配器的输入。

dsh-llm-pi-ai 将已配置提供方的安装目录 getModels(provider) 映射为中立目录。其现有请求时目录查询仍是权威依据,未知模型仍以 UNKNOWN_MODEL 失败。dsh-llm-deepseek 接受可选的 models 配置作为展示条目,默认包含 deepseek-v4-flash 和 deepseek-v4-pro。显式列表会替换这些默认值,空列表则关闭发现。这些条目改善已知公开或私有模型的选择体验,而所有未列出的模型 ID 仍会原样透传。

前门内的会话级选择

选择由提供它的前门拥有(今天是 TUI 的 /model 选择器),而不由 LlmService 或 AgentOptions 拥有:它们是部署级或创建级对象,改动它们会把并发会话耦合在一起。每个不透明选项都携带完整的提供方/模型对,因为同一模型 ID 可能出现在多个路由下。

ACP 自动化传输层不是目录消费方。它通过部署配置为新创建的 agent 提供一个可选的提供方/模型目标,不展示模型选择器或配置选项接口。

Prompt/请求一致性与持久化

installAgentLlmTarget(位于 dsh-agent)为前门拥有的目标安装 agent 作用域的 system-prompt/assemble 与 agent/request 监听器。Prompt 组装在每个 step 对所选组合做一次快照,在下游 prompt 监听器之后覆写组装出的 provider 与 model 变量;请求监听器在下游请求监听器之后应用同一快照。因此,发生在异步组装期间的选择会从下一个 step 生效,而不会让 prompt 文本与路由分裂。其他调用配置字段保持不变。

请求头仍是持久化的事实来源。当所选目标真正被使用时,现有的完整 request/header 快照会记录它;前门先从折叠后的最后一个请求头初始化其选择,然后才回退到创建选项。从未被请求使用的选择有意只保留在内存中,因为它从未成为模型可见状态。

考虑过的替代方案

只返回模型字符串。 只有模型的值会丢失提供方路由,一旦两个提供方暴露相同 ID 就会产生歧义。

将目录设为强制白名单。 这与手写适配器的任意模型透传和私有部署冲突。请求的权威校验本就属于被选中的适配器。

把选择存进 AgentOptions 或 LlmService。 它们是创建级或部署级对象。改动它们会把并发会话耦合在一起,并绕过有日志记录的 agent/request 替换路径。

立即持久化一个新的模型选择会话事件。 未被使用的 UI 选择尚未影响任何模型请求。在目标被消费时记录现有请求头,既保持“模型可见当且仅当有日志”的规则,又不会引入第二个事实来源。

结果

  • 任意适配器都能暴露动态模型列表,无需把提供方库类型泄漏到核心接缝。
  • 目录消费者必须把缺失理解为“未展示”,而不是“请求无效”。
  • pi-ai 适配器会暴露其已安装的提供方目录;手写 DeepSeek 部署显式列出已知选项,同时保留对任意模型的支持。
  • 面向人类的目录消费方拥有各自的选择交互。ACP 使用固定部署目标,不会为模型发现扩大协议范围。
  • 请求头与基于提供方路由的会话形态保持兼容;不需要新的 JSONL 事件或格式版本。
  • 目录读取可以是异步的,且每个调用方都会收到分离后的值。

测试

单元测试覆盖目录分离与错误元数据、pi-ai 和 DeepSeek 目录投影、提供方/模型请求路由、prompt 变量对齐,以及按 agent 隔离的目标。ACP 传输测试独立验证固定提供方/模型的转发行为;TUI 套件覆盖选择器交互与基于请求头的恢复。