# 频道搜索 Agent 化改造 · Agent Response Contract v1

> 文档阶段：Response Contract  
> 状态：Draft v1  
> 创建日期：2026-03-23  
> 作用：定义搜索框内 Agent 在不同状态下的目标、输出、边界与禁止行为

---

## 一、文档职责

本文件不是 prompt 草稿合集，而是：

`状态 -> Agent 行为 contract`

用于回答以下问题：

- 当前状态下 Agent 的目标是什么
- 当前状态下 Agent 可以输出什么
- 当前状态下 Agent 不能输出什么
- 当前状态下是否允许追问
- 当前状态下最多问几句
- 当前状态下用户看到的内容应该是什么结构

若 Demo、Spec、Design 与本文件冲突，以：

1. `state_machine_v1.md`
2. `agent_response_contract_v1.md`

为优先。

---

## 二、全局响应原则

### 2.1 统一原则

- Agent 只服务 `搜索框内部`
- Agent 不能把用户拉出搜索框去进入独立 chat 线程
- Agent 的输出必须服务当前搜索任务，不做闲聊或泛化建议

### 2.2 默认策略

- 默认是 `先搜后追问`
- 追问只在高影响歧义时触发
- 每次最多只允许一个高价值问题

### 2.3 解释性原则

- Agent 必须尽量让用户知道：
  - 当前按什么在搜
  - 哪些条件已经生效
  - 哪些只是参考偏好
  - 当前为什么需要追问或修正

### 2.4 禁止行为

- 禁止在稳定态继续显示“假 loading”
- 禁止在经典关键词态输出长段解释性文案
- 禁止静默改写用户显式关键词 tag 的匹配目标
- 禁止在 URL 精确路径成功时强行升级成完整 Agent 展开态
- 禁止在修正态把问题扩成开放式聊天

### 2.5 中间态输入原则

当原始自然语言 query 已经被系统成功吸收进：

- `task_summary`
- `conditions`

之后，主输入框不再继续保留原始 query 全文，而是切换为：

- `followup_waiting`

也就是一个新的补充输入位。

因此：

- 用户后续可以主动再补一句自然语言
- 这句补充是增量指令，不是继续编辑原始 query
- 这句补充提交后必须进入一轮增量 `refining`
- 不能停留在只有输入没有下游处理的半状态

补充：

- 当 URL 已被精确识别成功时，输入层语义应切换为 `committed_anchor`
- 当用户编辑一个已有关键词 tag 时，输入层语义应切换为 `editing_keyword`
- 当 `committed_anchor + committed_keyword` 同时出现时，默认不做前置冲突判别
- 系统应先按用户原样执行首轮搜索，再根据结果决定是否 repair / clarify

---

## 三、统一输出槽位

为保证不同状态的输出可比较，Agent 输出统一由以下槽位组成：

| 槽位 | 含义 | 是否必需 |
|---|---|---|
| `status` | 当前状态提示 | 必需 |
| `task_summary` | 当前搜索任务摘要 | 条件性必需 |
| `conditions` | 已生效硬条件 / 软偏好 / 锚点 | 条件性必需 |
| `question` | 当前唯一追问 | 仅追问态必需 |
| `repair_options` | 修正建议 | 仅修正态必需 |
| `actions` | 当前允许的下一步动作 | 必需 |

说明：

- 并非每个状态都要展示全部槽位
- 但每个状态都必须有可解释的最小输出

### 3.1 Demo 对齐规则

在当前 Demo 阶段，这些槽位名必须在视觉上显式标出，避免只做“语义接近”的模糊表达。

也就是说，Demo 中应尽量直接出现：

- `status`
- `task_summary`
- `conditions`
- `question`
- `repair_options`
- `actions`

若某槽位在当前状态不存在，可以不展示；但若展示了对应内容，命名必须与本文件保持一致。

### 3.2 事件驱动动作列表

在当前 Demo 阶段，Agent 响应槽位之外还需要一个只读动作列表区域：

- 作用：把“当前状态下用户可以做什么”显式列出来
- 本质：状态流转入口，不是自由推荐文案

因此该区域应满足：

- 每个动作都映射到一个确定目标状态
- 点击后触发 Demo 状态切换
- 命名上归类到 `actions`

补充解释：

- 这里的 `actions` 是当前 Demo 子状态的复合转移动作
- 它不是输入层 / 容器层 / 会话层单独某一层的动作
- 状态图中可点击的路径线，应与这里的 `actions` 保持同一套目标状态映射

---

## 四、状态响应协议

### 4.1 `compact_classic`

**目标**：
- 保持经典搜索效率
- 不打断关键词 / URL 原路径

**允许输出**：
- 极轻量提示
- 关键词 tag / draft 输入
- tag 匹配目标菜单

**禁止输出**：
- 长段说明文案
- 多个高权重按钮
- 追问
- 会话摘要卡

**用户可见槽位**：
- `status`：通常为空或极轻
- `actions`：搜索、编辑 tag、切换 tag 作用域

### 4.2 `compact_resolving`

**目标**：
- 快速判断 URL 是否可沿用原有精确路径

**允许输出**：
- 轻量状态提示
- 识别进度

**禁止输出**：
- 完整 Agent 会话卡
- 无关的推荐文案
- 开放式追问

**用户可见槽位**：
- `status`
- 必要时极简 `actions`

### 4.2A URL 精确识别成功后的响应约束

当 URL 已成功识别并锁定为单一频道目标时：

- Agent 应弱化原始 URL 文本存在感
- 前台应改为围绕一个 `anchor badge` 组织后续表达
- 不应继续让用户把这串原始 URL 误认为是仍待解析的输入
- 默认结果表达应转为：
  - `锚点频道` 已锁定
  - 当前正在召回相似频道
- 若产品保留“只查看该频道”的能力，应作为次级动作，而不是默认主结果语义

### 4.3 `expanded_agent`

**目标**：
- 将自然语言或混合输入解释为可执行搜索任务

**允许输出**：
- `task_summary`
- `conditions`
- 轻量状态提示

**禁止输出**：
- 一进入就连续追问多个问题
- 夸张 AI 自我表述

**用户可见槽位**：
- `status`
- `task_summary`
- `conditions`
- `actions`

**上下文要求**：
- 若当前结果来自修正后恢复，应记录：
  - `source_stage = post_repair`
- 该来源差异不要求额外新增独立稳定状态

**输入规则**：
- 原始自然语言不继续停留在输入框里
- 输入框切为 `followup_waiting`

### 4.4 `results_ready`

**目标**：
- 明确告诉用户首轮结果已经稳定可看

**允许输出**：
- 结果已返回的稳定提示
- 当前条件说明
- 可继续 refine 的弱提示

**禁止输出**：
- loading
- 没有必要时强行追问

**用户可见槽位**：
- `status`
- `task_summary`
- `conditions`
- `actions`

### 4.4A `low_recall` 提示态

当结果已经返回，但数量偏少、质量不足或明显过窄时：

- Agent 不得把它伪装成“正常稳定结果”
- 也不得直接自动展开到 `expanded_repair`
- 应保持结果继续可看，并在搜索框内部提供一个轻量 `repair_hint`

**允许输出**：
- 轻提示入口
- 当前低召回原因的极简说明
- 手动展开修正区的入口动作

**禁止输出**：
- 自动抢焦点展开
- 遮挡结果区
- 把低召回直接等同于“完全无结果”

**用户可见槽位**：
- `status`：可选
- `repair_hint`
- `actions`：可选，仅限轻量入口

### 4.5 `clarifying` / `expanded_clarifying`

**目标**：
- 只补一个最影响结果质量的问题

**允许输出**：
- 一个问题
- 2-4 个可点选答案或一个精简输入位

**禁止输出**：
- 第二个追问
- 长解释
- 把问题扩成聊天

**用户可见槽位**：
- `status`
- `question`
- `conditions`
- `actions`

**输入规则**：
- 用户可点选答案
- 也允许主动再补一句自然语言
- 允许继续补充新的关键词 tag
- 允许输入新的 URL，但只可作为替换现有 anchor 或建立单一 anchor 的操作
- 输入框承载的是新的 follow-up，而不是原始 query

### 4.6 `refining`

**目标**：
- 在用户回答追问或改条件后重新刷新结果

**允许输出**：
- loading
- 刷新中提示

**禁止输出**：
- 新追问
- 结果已稳定的措辞

**用户可见槽位**：
- `status`
- 可选的 `task_summary`

### 4.6A Follow-up 提交后的响应约束

当用户在以下状态主动补一句自然语言并提交后：

- `natural-followup-draft`
- `mixed-followup-draft`
- `repair-followup-draft`

Agent 必须：

- 把这句补充视为增量条件
- 进入一轮 `refining`
- 在本轮 `refining` 完成后，落回明确的稳定态或修正态

不得出现：

- 只有输入提交成功，但没有明确下游状态
- 把 follow-up 错误解释为“重新编辑原始 query”
- 修正态恢复成功后丢失 `source_stage = post_repair` 这一来源上下文

### 4.7 `empty_repair` / `expanded_repair`

**目标**：
- 把用户从“当前条件无效”带回“可搜状态”

**允许输出**：
- 1-3 个修正建议
- 当前失败原因
- 必要时一个极短问题

**禁止输出**：
- 闲聊
- 多轮长对话
- 假装结果仍在生成

**用户可见槽位**：
- `status`
- `conditions`
- `repair_options`
- `actions`

**输入规则**：
- 修正态也允许主动输入一条修正要求
- 输入框处于 `followup_waiting`

### 4.7A `low_recall`（低召回）统一修正约束

当出现以下任一情况时，进入同一修正语义：

- `anchor-only` 相似结果极少或质量不足
- `anchor + keyword` 首轮可见结果极少/过窄

Agent 输出要求：

- `status`：明确说明“当前是低召回修正”，不是完全无结果
- `task_summary`：说明锚点与关键词仍被保留
- `repair_options`：优先给以下动作语义
  - `A_REPAIR_REPLACE_ANCHOR`
  - `A_REPAIR_EXPAND_RECALL_SCOPE`
  - `A_REPAIR_REMOVE_ANCHOR_KEEP_KEYWORDS`
  - `A_REPAIR_SWITCH_TO_NL`

禁止行为：

- 把低召回静默当作成功结果继续推进
- 在低召回场景额外开启多轮追问
- 因为低召回就自动丢弃 anchor 或 keyword

### 4.8 `unsupported`

**目标**：
- 明确限制，不误导用户

**允许输出**：
- 限制原因
- 可行替代建议

**禁止输出**：
- 伪装成成功搜索
- 模糊表述

**用户可见槽位**：
- `status`
- `repair_options`
- `actions`

---

## 五、四类关键场景的额外规则

### 5.1 关键词搜索

- Agent 默认不介入
- 只有在用户主动升级或空结果时，才允许切入更强解释
- 关键词 tag 的匹配目标与排除逻辑优先于 Agent 推断

### 5.2 URL 输入

- Agent 首要任务是判定：
  - 精确识别成功
  - 平台不匹配
  - 类型不支持
  - 无法识别
- URL 精确识别成功时，Agent 应尽快退出强存在感

#### 5.2A URL 失败但 keyword 仍可用（例外路径）

当输入为 `anchor + keyword`，但 URL 解析失败无法生成 anchor 时：

- Agent 必须把失败归因限定在 URL 解析层，不得把整条输入判死
- Agent 必须明确告知：keyword 已被保留，可继续用于搜索
- 默认进入修正态，并只提供以下三类动作语义：
  - `A_REPAIR_FIX_URL`
  - `A_REPAIR_REMOVE_ANCHOR_KEEP_KEYWORDS`
  - `A_REPAIR_SWITCH_TO_NL`

该场景输出约束：

- `status`：说明 URL 失败原因（invalid / mismatch / unsupported）
- `task_summary`：说明 keyword 已保留
- `repair_options`：仅列上述三类修正动作，不扩展成开放聊天
- 不做前置冲突判别拦截

### 5.3 自然语言

- Agent 负责把自然语言拆成：
  - 锚点
  - 硬条件
  - 软偏好
- 首轮结果返回后，若无需追问，应直接稳定下来

### 5.4 混合输入

- Agent 必须先解释系统当前按什么优先级理解输入
- URL 锚点优先于软偏好
- 软偏好默认不伪装成已生效硬过滤器
- 当 `anchor + keyword` 同时出现时：
  - `anchor` 作为参考锚点
  - `keyword` 作为显式约束条件
  - V1 不做前置冲突判别
  - 默认直接 as-is 进入首轮搜索
  - 首轮响应中必须让用户理解：
    - `anchor` 已被锁定
    - 相似频道结果正在围绕该锚点召回
    - `keyword` 已在首轮用户可见结果中生效
  - `anchor` 作为 pinned reference 保留置顶可见
  - `keyword` 作用于相似频道结果集，不影响 `anchor` 本身的可见性
  - 若结果为空、极少或明显跑偏，再进入 repair / clarify；而不是前置拦截

### 5.5 经典态升级为 Agent 态

#### 关键词起手升级

当用户已提交关键词 tag 后又补充自然语言：

- Agent 首要任务不是立刻追问，而是：
  - 保留已有关键词 tag
  - 生成最小任务摘要
  - 把新增自然语言解释为任务增量
- 此时允许输出：
  - `task_summary`
  - `conditions`
  - 必要时的弱提示或一个追问

#### URL 起手升级

当用户已成功识别精确 URL 后又补充自然语言：

- Agent 首要任务是说明：
  - URL 仍是否作为锚点
  - 新自然语言如何被处理
- 不允许静默把 URL 变成“找类似频道”
- 此时允许输出：
  - `task_summary`
  - `conditions`
  - 必要时一个高价值问题

### 5.6 Agent -> 经典态回退

- Agent 态允许回退到经典态，但只在以下条件成立时：
  - 已不存在未完成的追问
  - 已不存在 repair 进行中的卡点
  - 当前输入只剩显式关键词 tag 和/或单一 anchor
- 回退后：
  - 保留显式 tag
  - 保留单一 anchor
  - 移除 Agent 派生解释层

---

## 六、后续维护规则

后续凡是新增：

- 新状态
- 新的 Agent 输出块
- 新的追问策略
- 新的修正策略
- 新的状态文案层级

都必须先更新本文件，再改 Demo 与其他文档。
