实用指南:MetaChat产品级创新互动设计 知识问答闯关( 出题/判题 + 成就系统)
产品地址:DevUI
体验地址:MateChat
使用说明:MateChat - 轻松构建你的AI应用
前言
区别于传统问答工具,“知识问答闯关” 是基于 MateChat - 轻松构建你的AI应用 构建的游戏化学习系统。核心通过「出题 / 判题插件」与「成就激励插件」的深度集成,将零散的知识问答转化为 “关卡进阶 + 即时反馈 + 成长可视化” 的闯关体验,既借助 MateChat 原生的可读化交互呈现答题逻辑,又通过插件化扩展实现 “从知识点测评到能力认证” 的全链路覆盖,适配 K12 学科巩固、职业技能考核、企业内训闯关等多元场景,让学习从 “被动应答” 变为 “主动挑战”。
案例代码仓库地址:AtomGit | GitCode - 全球开发者的开源社区,开源代码托管平台


什么是MateChat


MateChat是一个面向研发和知识协作的聊天 UI/交互套件,提供开箱即用的聊天界面、消息渲染、思考内容(reasoning)展示、历史记录等能力。其核心价值是将大模型的问答过程以可读、可操作的界面呈现出来,并支持插件化扩展(题库、工具、面板)。
官方网站:MateChat
什么是 DevUI

DevUI是华为云的企业级前端设计体系与组件库,提供规范化的主题变量(颜色、圆角、阴影、字号等)和一致的交互组件(按钮、输入、选择器、布局等)。本项目中所有卡片、进度条、气泡等都遵循 DevUI 的主题变量和样式规范,保证整站风格统一。
官方网站:DevUI
怎么接入 AI(OpenAI 兼容层)

Deepseek apikey获取:DeepSeek
项目内包含OpenAI兼容实现,支持通过配置不同的提供方(如 SiliconFlow/DeepSeek/Qwen)来进行对话。
关键实现(src/models/openai.ts):
// src/models/openai.ts(节选)
export class OpenAiService implements LLMService {
private client: OpenAI;
private currentModel = useChatModelStore().currentModel;
constructor(providerKey: string) {
const defaultModelConfig = LLM_MODELS.find(m => m.providerKey === providerKey);
const custom = useChatModelStore().customAPIKey.find(item => providerKey === item.providerKey);
this.client = new OpenAI({
baseURL: defaultModelConfig?.apiPath,
apiKey: custom?.apiKey ? custom.apiKey : defaultModelConfig?.apiKey,
dangerouslyAllowBrowser: true,
});
}
chat(request: ChatRequest): Promise {
return MODEL_CONFIGS.stream ? this.chatStream(request) : this.chatBatch(request);
}
async chatStream(request: ChatRequest): Promise {
// 流式返回,增量拼接 reasoning 与 content,并回调 onMessage/onComplete
}
}
接入步骤:
在 src/models/config.ts 中配置提供方 apiPath 与 apiKey,或通过界面输入自定义 API Key
选择模型后,将 MODEL_CONFIGS.enableMock=false 切换为真实调用(默认演示为 mock)
使用 OpenAiService.chat() 进行批量或流式对话(支持展示 reasoning_content)
注:当前演示版以本地题库和确定性判题为主,用于保证“每题必须明确对/错”的体验。切换为真实 AI 后,仍可保持由本地标准答案进行判分,以确保准确性。
闯关玩法与要求
题目以助手消息推送到聊天流;用户在输入框回答,随后助手判定“回答正确/错误”,附正确答案与解析、并更新积分
连胜与积分到达阈值触发成就;成绩可在“成就”面板查看

支持通过对话表达意图(如“做
Vue困难题”),自动解析方向/难度并开始闯关判题后自动进入下一题,顶部进度条与数值带动效(缩放/脉冲)
关键代码(节选)

挑战状态管理与判题(src/store/challenge-store.ts)
// 初始化状态
const active = ref(false);
const questions = ref(QUESTIONS);
const currentIndex = ref(0);
const score = ref(0);
const streak = ref(0);
const achievements = ref([]);
const awaitingAnswer = ref(false);
// 开始/结束/下一题
const start = () => {
active.value = true;
reset();
initQuestions();
awaitingAnswer.value = true;
useChatStatusStore().startChat = true;
presentQuestionMessage();
save();
};
const next = () => {
if (currentIndex.value < questions.value.length - 1) {
currentIndex.value++;
awaitingAnswer.value = true;
presentQuestionMessage();
save();
} else {
awaitingAnswer.value = false;
save();
}
};
// 判题与积分/连胜/成就
const submitAnswer = (val: string) => {
if (!active.value || !awaitingAnswer.value) return;
const q = currentQuestion.value;
const correct = isCorrect(val, q);
const chatMessageStore = useChatMessageStore();
if (correct) { score.value += q.points; streak.value += 1; } else { streak.value = 0; }
checkAchievements();
const summary = correct
? `回答正确 ✅ +${q.points}分\n题目:${q.title}\n解析:${q.explanation}\n当前积分:${score.value}`
: `回答错误 ❌\n题目:${q.title}\n正确答案:${q.answers.join(' / ')}\n解析:${q.explanation}\n当前积分:${score.value}`;
chatMessageStore.ask(val, summary);
awaitingAnswer.value = false;
save();
next(); // 自动进入下一题,刷新进度
};
// 出题消息推送到聊天流
const presentQuestionMessage = () => {
const chatMessageStore = useChatMessageStore();
const q = currentQuestion.value;
const choicesText = q.choices?.length ? q.choices.map(c => `${c.key}. ${c.text}`).join('\n') : '';
const content = `第${currentIndex.value + 1}题:${q.title}\n${q.content}${choicesText ? '\n' + choicesText : ''}`;
chatMessageStore.messages.push({ from: 'assistant', content, reasoning_content: '', avatarPosition: 'side-left', avatarConfig: { ...aiModelAvatar }, loading: false, complete: true });
chatMessageStore.messageChangeCount++;
};
// 题库筛选(方向/难度/题量)
const setCategories = (arr: string[]) => { selectedCategories.value = arr || []; };
const setLevels = (arr: Array<'easy'|'medium'|'hard'>|string[]) => { selectedLevels.value = (arr as any) || []; };
const setQuestionCount = (n?: number) => { questionCount.value = n; };
const initQuestions = () => { /* 根据筛选生成题序列 */ };
对话渲染(左右气泡 + 思考折叠)(src/view/challenge/chat-feed.vue)
{{ msg.content ? ($t('chat.thinkingComplete') + $t('chat.thinkingTime',{time:getThinkingTime(msg)})) : $t('chat.thinking') }}
顶部统计与进度(带动效)(src/view/challenge/challenge-layout.vue)

积分{{ challenge.score }}连胜{{ challenge.streak }}
输入意图解析(对话式选择方向/难度)(src/view/input/input.vue)
const detectPrefs = (text: string) => {
const lowers = text.toLowerCase();
const cats = QUESTION_CATEGORIES.filter(c => lowers.includes(c.toLowerCase()));
const lvls: string[] = [];
if (/(困难|hard)/i.test(text)) lvls.push('hard');
if (/(中等|medium)/i.test(text)) lvls.push('medium');
if (/(简单|easy)/i.test(text)) lvls.push('easy');
return { cats, lvls };
};
const onSubmit = (val: string) => {
if (!val) return;
if (challengeStore.active && challengeStore.awaitingAnswer) {
challengeStore.submitAnswer(val);
} else {
const prefs = detectPrefs(val);
if (prefs.cats.length || prefs.lvls.length) {
challengeStore.setCategories?.(prefs.cats);
challengeStore.setLevels?.(prefs.lvls);
challengeStore.start();
}
chatMessageStore.ask(val);
}
};
总结
通过 DevUI 的统一样式和 MateChat的聊天交互基础,结合本地题库与确定性判题,项目实现了“知识问答闯关”的高确定性体验。若需要切换到真实 AI,对接 OpenAiService 并保持本地标准答案判分即可在保证准确性的同时提升题面/解析的丰富度。

浙公网安备 33010602011771号