5.0 KiB
5.0 KiB
AskUserQuestion 多选支持 - API 设计文档
问题描述
当前 AI 询问用户问题时存在以下问题:
- 后端返回的选项不准确
- 多个问题只给几个选项
- 不支持多选方式
需求
实现一个问题对应多个选项,支持多选的方式。
数据结构设计
后端返回格式
后端通过 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": ["可配置时钟分频", "可配置数据位宽"]
}
}
总结
这个设计方案:
- ✅ 支持多个问题
- ✅ 每个问题有多个选项
- ✅ 支持单选和多选
- ✅ 数据结构清晰,易于扩展
- ✅ 向后兼容(可以只有一个问题)