Files
IC-Coder-Plugin/docs/AskUserQuestion-API设计.md

5.0 KiB
Raw Blame History

AskUserQuestion 多选支持 - API 设计文档

问题描述

当前 AI 询问用户问题时存在以下问题:

  1. 后端返回的选项不准确
  2. 多个问题只给几个选项
  3. 不支持多选方式

需求

实现一个问题对应多个选项,支持多选的方式。

数据结构设计

后端返回格式

后端通过 SSE 的 ask_user 事件返回以下格式:

{
  "askId": "ask_1234567890",
  "questions": [
    {
      "question": "请确认 SPI 控制器的配置需求:工作模式?",
      "options": [
        "Master/8位/模式0/固定分频/需要CS",
        "Master/可配置位宽/可配置模式/需要CS",
        "Slave模式"
      ],
      "multiSelect": false
    },
    {
      "question": "数据位宽?",
      "options": [
        "8位 还是其他?"
      ],
      "multiSelect": false
    },
    {
      "question": "时钟极性和相位?",
      "options": [
        "CPOL=0/CPHA=0 (模式0) 还是其他模式?"
      ],
      "multiSelect": false
    },
    {
      "question": "时钟分频?",
      "options": [
        "需要可配置的分频比吗?"
      ],
      "multiSelect": false
    },
    {
      "question": "是否需要芯片选信号 (CS) 控制?",
      "options": [
        "是",
        "否"
      ],
      "multiSelect": false
    }
  ]
}

前端数据结构

1. API 类型定义 (src/types/api.ts)

/** ask_user 事件数据 */
export interface AskUserEvent {
  askId: string;
  questions: QuestionItem[];
}

/** 单个问题项 */
export interface QuestionItem {
  question: string;
  options: string[];
  multiSelect?: boolean; // 是否支持多选,默认 false
}

2. MessageSegment 类型 (src/services/dialogService.ts)

export interface MessageSegment {
  type: "text" | "tool" | "question" | "agent" | "plan" | "progress";
  // ... 其他字段
  askId?: string;
  questions?: QuestionItem[]; // 改为问题数组
}

3. 用户回答格式 (src/types/api.ts)

export interface AnswerRequest {
  taskId: string;
  askId: string;
  answers: {
    [questionIndex: number]: string[]; // 每个问题的答案数组(支持多选)
  };
}

前端实现要点

1. 显示多个问题

// 遍历 questions 数组,为每个问题生成 UI
segment.questions?.forEach((q, index) => {
  // 显示问题标题
  // 显示选项(单选或多选)
  // 收集答案
});

2. 多选支持

if (q.multiSelect) {
  // 渲染复选框
  // 允许选择多个选项
} else {
  // 渲染单选按钮
  // 只允许选择一个选项
}

3. 提交答案

const answers = {
  0: ["Master/8位/模式0/固定分频/需要CS"], // 第1个问题的答案
  1: ["8位 还是其他?"],                    // 第2个问题的答案
  2: ["CPOL=0/CPHA=0 (模式0) 还是其他模式?"], // 第3个问题的答案
  // ...
};

vscode.postMessage({
  command: 'userAnswer',
  askId: 'ask_1234567890',
  answers: answers
});

后端需要做的修改

1. 修改 AskUserQuestion 工具的返回格式

从:

{
  "askId": "xxx",
  "question": "单个问题",
  "options": ["选项1", "选项2"]
}

改为:

{
  "askId": "xxx",
  "questions": [
    {
      "question": "问题1",
      "options": ["选项1", "选项2"],
      "multiSelect": false
    },
    {
      "question": "问题2",
      "options": ["选项A", "选项B", "选项C"],
      "multiSelect": true
    }
  ]
}

2. 接收答案的格式

从:

{
  "taskId": "xxx",
  "askId": "xxx",
  "selected": ["选项1"],
  "customInput": "自定义输入"
}

改为:

{
  "taskId": "xxx",
  "askId": "xxx",
  "answers": {
    "0": ["选项1"],           // 第1个问题的答案
    "1": ["选项A", "选项B"]   // 第2个问题的答案多选
  }
}

示例场景

场景SPI 控制器配置

后端发送:

{
  "askId": "ask_spi_config",
  "questions": [
    {
      "question": "工作模式?",
      "options": [
        "Master/8位/模式0/固定分频/需要CS",
        "Master/可配置位宽/可配置模式/需要CS",
        "Slave模式"
      ],
      "multiSelect": false
    },
    {
      "question": "需要哪些功能?",
      "options": [
        "可配置时钟分频",
        "可配置数据位宽",
        "支持多个CS",
        "DMA支持"
      ],
      "multiSelect": true
    }
  ]
}

用户选择:

  • 问题1选择 "Master/8位/模式0/固定分频/需要CS"
  • 问题2选择 "可配置时钟分频" 和 "可配置数据位宽"

前端提交:

{
  "taskId": "task_xxx",
  "askId": "ask_spi_config",
  "answers": {
    "0": ["Master/8位/模式0/固定分频/需要CS"],
    "1": ["可配置时钟分频", "可配置数据位宽"]
  }
}

总结

这个设计方案:

  1. 支持多个问题
  2. 每个问题有多个选项
  3. 支持单选和多选
  4. 数据结构清晰,易于扩展
  5. 向后兼容(可以只有一个问题)