feat: 实现深度模式质检员功能
- 新增质检阶段 (inspect):生成初稿后根据专家指令逐条检查 - AI 输出 JSON 格式质检报告,包含每项检查的 pass/warning/fail 状态 - MainContent.vue:新增质检报告卡片,可折叠展示检查结果 - 质检报告显示整体评价(通过/需关注/未通过)和详细评语 - 生成阶段指示器新增 inspect 状态(琥珀色)
This commit is contained in:
@@ -70,11 +70,64 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 质检报告卡片(深度模式 + 范式预设时显示) -->
|
||||||
|
<div v-if="qualityReport" class="bg-slate-800/50 rounded-lg border border-slate-600 overflow-hidden">
|
||||||
|
<div class="px-4 py-3 border-b border-slate-700 flex items-center justify-between">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="text-lg">🔍</span>
|
||||||
|
<span class="text-sm font-medium text-slate-200">质检报告</span>
|
||||||
|
<span
|
||||||
|
class="text-xs px-2 py-0.5 rounded"
|
||||||
|
:class="{
|
||||||
|
'bg-green-500/20 text-green-400': qualityReport.overall === 'pass',
|
||||||
|
'bg-yellow-500/20 text-yellow-400': qualityReport.overall === 'warning',
|
||||||
|
'bg-red-500/20 text-red-400': qualityReport.overall === 'fail'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ qualityReport.overall === 'pass' ? '通过' : qualityReport.overall === 'warning' ? '需关注' : '未通过' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
@click="isQualityReportExpanded = !isQualityReportExpanded"
|
||||||
|
class="text-slate-400 hover:text-white transition"
|
||||||
|
>
|
||||||
|
<span class="transition-transform inline-block" :class="{ 'rotate-180': isQualityReportExpanded }">▼</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="isQualityReportExpanded" class="p-4 space-y-3">
|
||||||
|
<div
|
||||||
|
v-for="check in qualityReport.checks"
|
||||||
|
:key="check.key"
|
||||||
|
class="flex items-start gap-3 text-sm"
|
||||||
|
>
|
||||||
|
<span class="shrink-0 mt-0.5">
|
||||||
|
<span v-if="check.status === 'pass'" class="text-green-400">✅</span>
|
||||||
|
<span v-else-if="check.status === 'warning'" class="text-yellow-400">⚠️</span>
|
||||||
|
<span v-else class="text-red-400">❌</span>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<span class="font-medium" :class="{
|
||||||
|
'text-green-300': check.status === 'pass',
|
||||||
|
'text-yellow-300': check.status === 'warning',
|
||||||
|
'text-red-300': check.status === 'fail'
|
||||||
|
}">{{ check.title }}</span>
|
||||||
|
<p class="text-xs text-slate-500 mt-0.5">{{ check.message }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="qualityReport.summary" class="pt-3 border-t border-slate-700">
|
||||||
|
<p class="text-xs text-slate-400 italic">📝 {{ qualityReport.summary }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 生成阶段指示器 -->
|
<!-- 生成阶段指示器 -->
|
||||||
<div v-if="isGenerating && generationStage" class="flex items-center gap-2 text-xs text-slate-500">
|
<div v-if="isGenerating && generationStage" class="flex items-center gap-2 text-xs text-slate-500">
|
||||||
<span class="w-2 h-2 rounded-full animate-pulse" :class="{
|
<span class="w-2 h-2 rounded-full animate-pulse" :class="{
|
||||||
'bg-indigo-500': generationStage === 'thinking',
|
'bg-indigo-500': generationStage === 'thinking',
|
||||||
'bg-blue-500': generationStage === 'draft',
|
'bg-blue-500': generationStage === 'draft',
|
||||||
|
'bg-amber-500': generationStage === 'inspect',
|
||||||
'bg-yellow-500': generationStage === 'critique',
|
'bg-yellow-500': generationStage === 'critique',
|
||||||
'bg-green-500': generationStage === 'refine'
|
'bg-green-500': generationStage === 'refine'
|
||||||
}"></span>
|
}"></span>
|
||||||
@@ -178,6 +231,7 @@ const {
|
|||||||
generatedContent,
|
generatedContent,
|
||||||
thinkingContent,
|
thinkingContent,
|
||||||
generationStage,
|
generationStage,
|
||||||
|
qualityReport,
|
||||||
isGenerating,
|
isGenerating,
|
||||||
analysisResult,
|
analysisResult,
|
||||||
inputTask,
|
inputTask,
|
||||||
@@ -189,6 +243,7 @@ const {
|
|||||||
// AI 思考过程折叠状态
|
// AI 思考过程折叠状态
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
const isThinkingExpanded = ref(false)
|
const isThinkingExpanded = ref(false)
|
||||||
|
const isQualityReportExpanded = ref(true) // 质检报告默认展开
|
||||||
|
|
||||||
// 范式定义
|
// 范式定义
|
||||||
const paradigms = [
|
const paradigms = [
|
||||||
@@ -272,6 +327,7 @@ const stageLabel = computed(() => {
|
|||||||
const labels = {
|
const labels = {
|
||||||
'thinking': '🧠 风格解构 & 大纲规划中...',
|
'thinking': '🧠 风格解构 & 大纲规划中...',
|
||||||
'draft': '✍️ 正在撰写初稿...',
|
'draft': '✍️ 正在撰写初稿...',
|
||||||
|
'inspect': '🔍 正在进行质量检查...',
|
||||||
'critique': '💡 AI 深度反思中...',
|
'critique': '💡 AI 深度反思中...',
|
||||||
'refine': '✨ 深度润色中...'
|
'refine': '✨ 深度润色中...'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,63 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
|
|
||||||
// 如果是深度模式,进入 Agentic Workflow
|
// 如果是深度模式,进入 Agentic Workflow
|
||||||
if (isDeepMode.value) {
|
if (isDeepMode.value) {
|
||||||
// 2. 批判阶段
|
// 2. 质检阶段(如果有专家指令)
|
||||||
|
if (activeParadigm.value && expertGuidelines.value.length > 0) {
|
||||||
|
generationStage.value = 'inspect'
|
||||||
|
console.log('Store: 进入质检阶段...')
|
||||||
|
|
||||||
|
// 构建质检 Prompt
|
||||||
|
const guidelinesText = expertGuidelines.value
|
||||||
|
.map((g, i) => `${i + 1}. 【${g.title}】${g.description}`)
|
||||||
|
.join('\n')
|
||||||
|
|
||||||
|
const inspectPrompt = `你是一名严格的质检专家。请根据以下专家评价标准,逐条检查这篇文章的质量。
|
||||||
|
|
||||||
|
# 专家评价标准
|
||||||
|
${guidelinesText}
|
||||||
|
|
||||||
|
# 待检查的文章
|
||||||
|
${draft}
|
||||||
|
|
||||||
|
# 输出要求
|
||||||
|
请严格按照以下 JSON 格式输出检查结果(不要输出其他内容):
|
||||||
|
{
|
||||||
|
"checks": [
|
||||||
|
{"key": "对应的检查项英文key", "title": "检查项标题", "status": "pass|warning|fail", "message": "具体评价说明"}
|
||||||
|
],
|
||||||
|
"overall": "pass|warning|fail",
|
||||||
|
"summary": "整体评价总结(一句话)"
|
||||||
|
}`
|
||||||
|
|
||||||
|
let inspectResult = ''
|
||||||
|
await api.generateContent(inspectPrompt, (content) => {
|
||||||
|
inspectResult += content
|
||||||
|
}, { temperature: 0.3 })
|
||||||
|
|
||||||
|
// 解析质检结果
|
||||||
|
try {
|
||||||
|
// 提取 JSON(可能被包裹在 markdown 代码块中)
|
||||||
|
const jsonMatch = inspectResult.match(/\{[\s\S]*\}/)
|
||||||
|
if (jsonMatch) {
|
||||||
|
qualityReport.value = JSON.parse(jsonMatch[0])
|
||||||
|
console.log('Store: 质检完成', qualityReport.value)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Store: 质检结果解析失败', e)
|
||||||
|
qualityReport.value = {
|
||||||
|
checks: expertGuidelines.value.map(g => ({
|
||||||
|
key: g.checkKey,
|
||||||
|
title: g.title,
|
||||||
|
status: 'warning',
|
||||||
|
message: '质检解析异常,请人工复核'
|
||||||
|
})),
|
||||||
|
overall: 'warning',
|
||||||
|
summary: '质检结果解析失败,建议人工复核'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 批判阶段
|
||||||
generationStage.value = 'critique'
|
generationStage.value = 'critique'
|
||||||
console.log('Store: 进入批判阶段...')
|
console.log('Store: 进入批判阶段...')
|
||||||
generatedContent.value += '\n\n---\n\n💡 **AI 深度反思 (Critique Stage)**:\n正在分析逻辑漏洞与改进空间...\n\n'
|
generatedContent.value += '\n\n---\n\n💡 **AI 深度反思 (Critique Stage)**:\n正在分析逻辑漏洞与改进空间...\n\n'
|
||||||
@@ -189,7 +245,7 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
critiqueContent += content
|
critiqueContent += content
|
||||||
})
|
})
|
||||||
|
|
||||||
// 3. 修正阶段
|
// 4. 修正阶段
|
||||||
generationStage.value = 'refine'
|
generationStage.value = 'refine'
|
||||||
console.log('Store: 进入修正阶段...')
|
console.log('Store: 进入修正阶段...')
|
||||||
generatedContent.value += '\n\n---\n\n✨ **深度润色 (Refinement Stage)**:\n正在根据反思意见重写...\n\n'
|
generatedContent.value += '\n\n---\n\n✨ **深度润色 (Refinement Stage)**:\n正在根据反思意见重写...\n\n'
|
||||||
|
|||||||
Reference in New Issue
Block a user