渐进式披露:如何用少即是多的理念改进 AI 产品的人机交互
AI 不聪明只是用户给的信息太少了毕竟猜心这种事谁也做不好。这种现象在我们开发 HagiCode 的过程中尤为明显。HagiCode 是一个 AI 驱动的代码助手用户通过自然语言描述需求来创建技术提案和会话。可在实际使用中我们发现用户输入的内容往往存在这些问题输入质量参差不齐有的用户只输入几个字比如优化登录、修复 bug缺乏必要的上下文技术术语不统一不同用户用不同的词说同一件事有人说前端有人说FE缺少结构化信息没有项目背景、没有仓库范围、没有影响范围这些关键信息重复性问题相同类型的需求反复出现每次都要从头解释这些问题导致的直接后果就是AI 理解困难、生成的提案质量不稳定、用户体验差。用户觉得这 AI 不行啊我们也很委屈——你只给一句话让我怎么猜你想要啥其实这也没办法毕竟人和人之间的理解都需要时间更何况是机器呢为了解决这些痛点我们做了一个大胆的决定引入渐进式披露的设计理念来改进人机交互。这个决定带来的变化可能比你想象的还要大只是当时我们也没想到会这么有效罢了。关于 HagiCode本文分享的方案来这套渐进式披露方案是我们在实际开发过程中经过多次迭代和优化总结出来的。如果你觉得这套方案有价值说明我们的工程实力还不错——那么 HagiCode 本身也值得关注一下毕竟好东西是值得分享的。什么是渐进式披露渐进式披露Progressive Disclosure是一个源自 HCI人机交互领域的设计原则核心思想很简单不要一次性把所有信息和选项都展示给用户而是根据用户的操作和需求逐步展示必要的内容。这个原则特别适合 AI 产品因为 AI 交互天然就是渐进式的——用户说一点AI 理解一点然后补充一点再理解更多。就像人与人之间的交流一样总得慢慢来毕竟谁也不能一见面就把心掏出来不是具体到 HagiCode 的场景我们从四个方面实施了渐进式披露1. 描述优化机制让 AI 帮你把话说清楚当用户输入简短描述时我们不是直接让 AI 去理解而是先触发一个描述优化流程。这个流程的核心是结构化输出——把用户的自由文本转化为标准格式。就像把散落一地的珍珠串成项链看起来也就不那么乱了。优化后的描述必须包含以下几个标准章节背景问题背景和上下文分析技术分析和思考过程解决解决方案和实施步骤实践实际代码示例和注意事项同时我们还会自动生成一个 Markdown 表格展示目标仓库、路径、编辑权限等信息方便 AI 后续操作。毕竟有个清晰的目录找起东西来也方便。下面是实际的代码实现// ProposalDescriptionMemoryService.cs 中的核心方法public async Taskstring OptimizeDescriptionAsync(string title,string description,string locale zh-CN,DescriptionOptimizationMemoryContext? memoryContext null,CancellationToken cancellationToken default){// 构建查询参数var queryContext BuildQueryContext(title, description);// 检索历史上下文var memoryContext await RetrieveHistoricalContextAsync(queryContext, cancellationToken);// 生成结构化提示词var prompt await BuildOptimizationPromptAsync(title,description,memoryContext,cancellationToken);// 调用 AI 进行优化return await _aiService.CompleteAsync(prompt, cancellationToken);}这个流程的关键在于记忆注入——我们会把项目惯例、相似案例、负面模式等历史上下文注入到提示词中让 AI 在优化时能够参考过去的经验。毕竟吃一堑长一智过去的经验总不能白白浪费了不是注意事项确保当前输入优先于历史记忆避免覆盖用户显式指定的信息HagIndex 引用必须作为事实来源不得被历史案例修改低置信度的纠错建议不应作为强约束注入2. 语音输入能力说话比打字更自然除了文本输入我们还支持语音输入。这在描述复杂需求时特别有用——你想想打一段技术需求可能要几分钟但说可能几十秒就完事了毕竟嘴总是比手快。语音输入的设计重点是状态管理用户必须清楚当前系统处于什么状态。我们定义了以下几种状态空闲系统就绪可以开始录制等待上游正在连接后端服务录制中正在录制用户语音处理中正在将语音转换为文本错误发生错误需要用户处理前端的状态模型大概是这样的interface VoiceInputState {status: idle | waiting-upstream | recording | processing | error;duration: number;error?: string;deletedSet: Setstring; // 已删除结果的指纹集合}// 开始录制时的状态转换const handleVoiceInputStart async () {// 先进入等待状态显示加载动画setState({ status: waiting-upstream });// 等待后端就绪确认const isReady await waitForBackendReady();if (!isReady) {setState({ status: error, error: 后端服务未就绪 });return;}// 开始录制setState({ status: recording, startTime: Date.now() });};// 处理识别结果const handleRecognitionResult (result: RecognitionResult) {const fingerprint normalizeFingerprint(result.text);// 检查是否已被删除if (state.deletedSet.has(fingerprint)) {return; // 跳过已删除的内容}// 合并结果到文本框appendResult(result);};这里有个细节我们用指纹集合来管理删除同步。当语音识别返回多条结果时用户可能会删除其中一些。我们把已删除内容的指纹存起来后续如果相同内容再出现就自动跳过。这就像记住了哪些菜不爱吃下次就不会再点了毕竟谁也不想被同样的问题困扰两次。3. 提示词管理系统把 AI 的脑子外置HagiCode 有一个灵活的提示词管理系统所有提示词都以文件形式存储prompts/├── metadata/│ ├── optimize-description.zh-CN.json│ └── optimize-description.en-US.json└── templates/├── optimize-description.zh-CN.hbs└── optimize-description.en-US.hbs每个提示词由两部分组成元数据文件.json定义提示词的场景、版本、参数等信息模板文件.hbs使用 Handlebars 语法的实际提示词内容元数据文件的格式是这样的{scenario: optimize-description,locale: zh-CN,version: 1.0.0,syntax: handlebars,syntaxVersion: 1.0,parameters: [{name: title,type: string,required: true,description: 提案标题},{name: description,type: string,required: true,description: 原始描述}],author: HagiCode Team,description: 优化用户输入的技术提案描述,lastModified: 2026-04-05,tags: [optimization, nlp]}模板文件使用 Handlebars 语法支持参数注入你是一个技术提案专家。task根据以下信息生成结构化的技术提案描述。/taskinputtitle{{title}}/titledescription{{description}}/description{{#if memoryContext}}memory_context{{memoryContext}}/memory_context{{/if}}/inputoutput_format## 背景[描述问题背景和上下文包括项目信息、仓库范围等]## 分析[技术分析和思考过程说明为什么需要这个改动]## 解决[解决方案和实施步骤列出关键代码位置]## 实践[实际代码示例和注意事项]/output_format这种设计的好处是提示词可以像代码一样版本管理支持多语言根据用户偏好自动切换参数化设计可以动态注入上下文启动时验证完备性避免运行时出错毕竟脑子里的东西不写下来谁也不知道什么时候就忘了与其到时候懊悔不如一开始就做好记录罢了。4. 渐进式向导复杂任务拆成小步对于复杂任务比如首次安装配置我们使用了多步骤向导的设计。每个步骤只请求必要信息并提供清晰的进度指示。生活也是这样嘛一口吃不成胖子一步一步来反而更稳妥。向导的状态模型interface WizardState {currentStep: number; // 0-3对应 4 个步骤steps: WizardStep[];canGoNext: boolean;canGoBack: boolean;isLoading: boolean;error: string | null;}interface WizardStep {id: number;title: string;description: string;completed: boolean;}// 步骤导航逻辑const goToNextStep () {if (wizardState.currentStep wizardState.steps.length - 1) {// 验证当前步骤的输入if (validateCurrentStep()) {wizardState.currentStep;wizardState.steps[wizardState.currentStep - 1].completed true;}}};const goToPreviousStep () {if (wizardState.currentStep 0) {wizardState.currentStep--;}};每个步骤都有独立的验证逻辑已完成步骤会有清晰的视觉标记。取消操作会弹出确认对话框防止用户误操作丢失进度。毕竟走错路可以回头但如果把路都拆了那就真的没辙了。总结回顾 HagiCode 的渐进式披露实践我们可以总结出几个核心原则分步引导把复杂任务拆成小步每步只请求必要信息智能补全利用历史上下文和项目知识自动补全信息即时反馈每个操作都有清晰的视觉反馈和状态提示容错机制允许用户撤销、重置避免错误造成不可逆损失输入多样化支持文本、语音等多种输入方式这套方案在 HagiCode 中的实际效果是用户输入的平均长度从不到 20 字提升到了结构化的 200-300 字AI 生成的提案质量显著提高用户满意度也跟着上来了。其实这也不奇怪毕竟你给的信息越多AI 理解得越准确返回的结果自然就越好这和人与人之间的交流也没什么两样。如果你也在做 AI 相关的产品希望这些经验能给你带来一些启发。记住用户不是不想给信息而是你还没问对问题。渐进式披露的核心就是找到问问题的最佳时机和方式只是这个时机和方式需要一点耐心去摸索罢了。