feat: comprehensive documentation and demo updates

- Update READMEs and docs across multiple languages
- Enhance interactive demos for Agent, LLM, VLM, Audio, Image Gen, Terminal, and Web Basics
- Add new appendix sections for Database and IDE intros
- Update VitePress config, theme, and utility scripts
- Clean up unused assets and components
This commit is contained in:
sanbuphy
2026-01-16 19:10:21 +08:00
parent c8567ce23f
commit 73f4788d7e
150 changed files with 19530 additions and 13401 deletions
@@ -1,256 +1,132 @@
<!--
ChainOfThoughtDemo.vue
先计划再输出演示更易懂版本
注意这里不强调让模型展示冗长推理而是用先列计划/检查点来降低跑偏概率
-->
<template>
<div class="chain-of-thought-demo">
<div class="comparison-container">
<!-- Direct Answer -->
<div class="method-card">
<div class="method-header">
<span class="method-icon"></span>
<span class="method-title">直接回答</span>
</div>
<div class="method-body">
<div class="prompt-box">
<div class="prompt-label">提示词</div>
<div class="prompt-text">
罗杰有 5 个网球他又买了 2 罐网球每罐有 3 个球
现在他总共有多少个网球
</div>
</div>
<div class="arrow"></div>
<div class="result-box">
<div class="result-label">AI 可能的输出</div>
<div class="result-content bad">
"11 个球。"
<br><br>
<span class="badge">错误 </span>
</div>
</div>
</div>
<div class="cot">
<div class="header">
<div>
<div class="title">复杂任务列计划交付结果</div>
<div class="subtitle">你要的是不漏步骤 + 可检查 + 不跑题</div>
</div>
<!-- Chain of Thought -->
<div class="method-card highlight">
<div class="method-header">
<span class="method-icon">🧠</span>
<span class="method-title">思维链 (CoT)</span>
</div>
<div class="method-body">
<div class="prompt-box">
<div class="prompt-label">提示词</div>
<div class="prompt-text">
罗杰有 5 个网球他又买了 2 罐网球每罐有 3 个球
现在他总共有多少个网球
<br><br>
<span class="instruction">请一步步思考</span>
</div>
</div>
<div class="arrow"></div>
<div class="result-box">
<div class="result-label">AI 输出</div>
<div class="result-content good">
<div class="thinking-process">
罗杰原本有 5 个球<br>
他买了 2 每罐 3 2 × 3 = 6 <br>
总共5 + 6 = 11
</div>
<div class="final-answer">
<strong>答案11 个球</strong>
</div>
<span class="badge success">正确 </span>
</div>
</div>
</div>
<div class="controls">
<select v-model="task">
<option value="debug">代码审查</option>
<option value="plan">行程规划</option>
</select>
<button
v-for="m in modes"
:key="m.id"
:class="['mode', { active: mode === m.id }]"
@click="mode = m.id"
>
{{ m.label }}
</button>
</div>
</div>
<div class="explanation">
<div class="exp-item">
<span class="exp-icon">🔍</span>
<span><strong>思维链</strong> AI "展示思考过程"一步步推理问题
对于数学逻辑推理类问题特别有效</span>
<div class="grid">
<div class="panel">
<div class="panel-title">提示词 / Prompt</div>
<pre><code>{{ prompt }}</code></pre>
</div>
<div class="exp-item">
<span class="exp-icon">📝</span>
<span><strong>触发词</strong>使用"请一步步思考""详细说明推理过程"等提示语可以激活 CoT</span>
<div class="panel">
<div class="panel-title">输出示意</div>
<div class="output">{{ output }}</div>
</div>
<div class="exp-item">
<span class="exp-icon">🎯</span>
<span><strong>适用场景</strong>数学计算逻辑推理复杂问题拆解多步骤任务</span>
</div>
<div class="why">
<div class="why-title">为什么这样更稳</div>
<div class="why-grid">
<div class="why-card">
<div class="k"> 不漏步骤</div>
<div class="v">计划就是清单能一项项对照</div>
</div>
<div class="why-card">
<div class="k"> 更好验收</div>
<div class="v">你知道该检查什么而不是只看像不像</div>
</div>
<div class="why-card">
<div class="k"> 更少返工</div>
<div class="v">先对齐方向再生成结果减少来回修</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.chain-of-thought-demo {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
background: var(--vp-c-bg-soft);
margin: 20px 0;
}
<script setup>
import { computed, ref } from 'vue'
.comparison-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
const task = ref('debug')
const mode = ref('plan-first')
@media (max-width: 768px) {
.comparison-container {
grid-template-columns: 1fr;
const modes = [
{ id: 'direct', label: '直接输出' },
{ id: 'plan-first', label: '先列计划再输出' }
]
const prompt = computed(() => {
if (task.value === 'debug') {
if (mode.value === 'direct') {
return '帮我看看这段代码有什么问题,并给修复建议。'
}
return `你是资深前端工程师。\n任务:代码审查。\n要求:\n1) 先列“检查清单”(3-5 项),说明你将检查什么\n2) 再输出问题列表(每条包含:现象/原因/修复)\n3) 最后给一段修复后的代码(仅关键片段)`
}
}
// plan
if (mode.value === 'direct') return '帮我做一个上海三日游行程,越详细越好。'
return `你是旅行规划师。\n任务:上海三日游。\n要求:\n1) 先列“规划原则”(交通/节奏/预算)\n2) 再给 Day1-Day3 行程(每段 3-5 个地点)\n3) 每天最后给一句“备选方案”\n输出:Markdown`
})
.method-card {
background: var(--vp-c-bg);
border: 2px solid var(--vp-c-divider);
border-radius: 8px;
overflow: hidden;
}
const output = computed(() => {
if (task.value === 'debug') {
if (mode.value === 'direct') {
return '代码可能有一些问题,比如命名不规范、性能不佳……(容易泛泛而谈/漏点)'
}
return `检查清单:\n- 边界条件(空值/类型)\n- 异步/错误处理\n- 性能(重复计算/循环)\n- 可读性(命名/拆分)\n\n问题列表:\n1) 现象:…\n 原因:…\n 修复:…\n2) 现象:…\n 原因:…\n 修复:…\n\n修复片段:\n// ...关键修改代码...`
}
if (mode.value === 'direct') {
return 'Day1:外滩…Day2:迪士尼…Day3:田子坊…(可能太散/不成体系)'
}
return `规划原则:\n- 交通:地铁优先\n- 节奏:上午景点,下午咖啡/逛街\n- 预算:人均 300-500/天\n\nDay1:外滩 → 南京路 → 人民广场\n备选:雨天去博物馆\n\nDay2:豫园 → 城隍庙 → 新天地\n备选:改为室内商场+展览\n\nDay3:武康路 → 安福路 → 徐汇滨江\n备选:去书店/美术馆`
})
</script>
.method-card.highlight {
border-color: #22c55e;
}
.method-header {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 15px;
background: var(--vp-c-bg-mute);
}
.method-card.highlight .method-header {
background: rgba(34, 197, 94, 0.1);
}
.method-icon {
font-size: 1.3rem;
}
.method-title {
font-weight: bold;
font-size: 0.95rem;
color: var(--vp-c-text-1);
}
.method-body {
padding: 15px;
}
.prompt-box {
background: var(--vp-c-bg-soft);
<style scoped>
.cot {
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
padding: 12px;
margin-bottom: 15px;
}
.prompt-label {
font-size: 0.75rem;
color: var(--vp-c-text-3);
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: bold;
}
.prompt-text {
font-size: 0.9rem;
color: var(--vp-c-text-1);
line-height: 1.6;
}
.instruction {
color: #22c55e;
font-weight: 600;
}
.arrow {
text-align: center;
font-size: 1.5rem;
color: var(--vp-c-text-3);
margin: 10px 0;
}
.result-box {
border-radius: 12px;
background: var(--vp-c-bg-soft);
border-radius: 6px;
padding: 12px;
}
.result-label {
font-size: 0.75rem;
color: var(--vp-c-text-3);
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: bold;
}
.result-content {
font-size: 0.9rem;
color: var(--vp-c-text-2);
line-height: 1.6;
}
.thinking-process {
background: #000;
border-radius: 4px;
padding: 12px;
margin-bottom: 10px;
font-family: monospace;
font-size: 0.85rem;
color: #a1a1aa;
}
.final-answer {
color: var(--vp-c-text-1);
margin-bottom: 8px;
}
.badge {
display: inline-block;
padding: 4px 10px;
border-radius: 4px;
font-size: 0.8rem;
font-weight: bold;
}
.badge:not(.success) {
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
}
.badge.success {
background: rgba(34, 197, 94, 0.2);
color: #22c55e;
}
.explanation {
padding: 16px;
margin: 20px 0;
display: flex;
flex-direction: column;
gap: 10px;
gap: 12px;
}
.exp-item {
display: flex;
align-items: flex-start;
gap: 10px;
background: var(--vp-c-bg);
padding: 12px;
border-radius: 6px;
font-size: 0.9rem;
color: var(--vp-c-text-2);
line-height: 1.5;
}
.header { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.title { font-weight: 800; }
.subtitle { color: var(--vp-c-text-2); font-size: 13px; }
.exp-icon {
font-size: 1.3rem;
}
.controls { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
select { border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 8px 10px; background: var(--vp-c-bg); color: var(--vp-c-text-1); }
.mode { border: 1px solid var(--vp-c-divider); background: var(--vp-c-bg); padding: 8px 12px; border-radius: 999px; cursor: pointer; }
.mode.active { border-color: var(--vp-c-brand); color: var(--vp-c-brand); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.panel { background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.panel-title { font-weight: 700; }
pre { margin: 0; background: #0b1221; color: #e5e7eb; border-radius: 8px; padding: 12px; font-family: var(--vp-font-family-mono); font-size: 13px; overflow-x: auto; white-space: pre-wrap; }
.output { white-space: pre-wrap; line-height: 1.6; }
.why { background: var(--vp-c-bg); border: 1px dashed var(--vp-c-divider); border-radius: 10px; padding: 12px; }
.why-title { font-weight: 700; margin-bottom: 8px; }
.why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.why-card { border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 10px; background: var(--vp-c-bg-soft); }
.k { font-weight: 800; }
.v { color: var(--vp-c-text-2); font-size: 13px; margin-top: 4px; line-height: 1.5; }
</style>
@@ -1,223 +1,131 @@
<!--
FewShotDemo.vue
Few-shot 速懂不给示例 vs 给示例AI 风格会不会稳定
交互
- 选择目标风格随意/正式
- 选择是否提供示例
- 看提示词和输出如何变化
-->
<template>
<div class="few-shot-demo">
<div class="mode-switch">
<button :class="{ active: mode === 'zero' }" @click="mode = 'zero'">
🎯 Zero-shot零样本
</button>
<button :class="{ active: mode === 'few' }" @click="mode = 'few'">
📚 Few-shot少样本
</button>
</div>
<div class="demo-container">
<!-- Zero-shot -->
<div v-if="mode === 'zero'" class="zero-shot">
<div class="prompt-box">
<div class="prompt-header">提示词</div>
<div class="prompt-content">
<strong>中文</strong>翻译成<strong>英文</strong>
<br><br>
"我很好"
</div>
</div>
<div class="arrow"></div>
<div class="output-box">
<div class="output-header">AI 可能的输出</div>
<div class="output-content">
"I'm fine." "I'm very good." "I am well."
<br><br>
<span class="comment"> 不确定应该用什么语气可能是正式或随意</span>
</div>
</div>
<div class="few">
<div class="header">
<div>
<div class="title">示例的力量让风格跟你走</div>
<div class="subtitle">你不是让 AI 更聪明而是让它更像你要的样子</div>
</div>
<!-- Few-shot -->
<div v-else class="few-shot">
<div class="prompt-box">
<div class="prompt-header">提示词含示例</div>
<div class="prompt-content">
<strong>中文</strong>翻译成<strong>英文</strong>
<br><br>
<div class="examples">
<div class="example-item">
<span class="input">你好</span> <span class="output">Hi!</span>
</div>
<div class="example-item">
<span class="input">谢谢</span> <span class="output">Thanks!</span>
</div>
<div class="example-item">
<span class="input">再见</span> <span class="output">Bye!</span>
</div>
</div>
<div class="task">
<strong>任务</strong>"我很好"
</div>
</div>
</div>
<div class="arrow"></div>
<div class="output-box">
<div class="output-header">AI 输出</div>
<div class="output-content">
"I'm great!"
<br><br>
<span class="comment success"> 通过示例学会了随意的对话风格</span>
</div>
</div>
<div class="controls">
<select v-model="tone">
<option value="casual">随意口语</option>
<option value="formal">正式书面</option>
</select>
<button :class="['toggle', { active: withExamples }]" @click="withExamples = !withExamples">
{{ withExamples ? '已提供示例' : '不提供示例' }}
</button>
</div>
</div>
<div class="explanation">
<div v-if="mode === 'zero'">
<strong>Zero-shot</strong>不给任何示例直接让 AI 完成任务简单但可能不够准确
<div class="grid">
<div class="panel">
<div class="panel-title">提示词 / Prompt</div>
<pre><code>{{ prompt }}</code></pre>
</div>
<div v-else>
<strong>Few-shot</strong>提供几个示例让 AI 学习规律例的质量和数量直接影响输出效果
通常 3-5 个示例就足够了
<div class="panel">
<div class="panel-title">AI 输出</div>
<div class="output">{{ output }}</div>
<div class="hint">{{ hint }}</div>
</div>
</div>
<div class="examples" v-if="withExamples">
<div class="examples-title">示例AI 照着学</div>
<div class="examples-grid">
<div class="ex" v-for="e in examples" :key="e.in">
<div class="in">输入{{ e.in }}</div>
<div class="out">输出{{ e.out }}</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { computed, ref } from 'vue'
const mode = ref('zero')
const tone = ref('casual')
const withExamples = ref(true)
const examples = computed(() => {
if (tone.value === 'casual') {
return [
{ in: '你好', out: 'Hi' },
{ in: '谢谢', out: '谢啦!' },
{ in: '再见', out: '拜拜~' }
]
}
return [
{ in: '你好', out: '您好。' },
{ in: '谢谢', out: '非常感谢。' },
{ in: '再见', out: '再见,祝您一切顺利。' }
]
})
const prompt = computed(() => {
const base = '将中文翻译成英文。'
const task = '输入:我很好'
if (!withExamples.value) return `${base}\n${task}`
const lines = [base, '示例:']
for (const e of examples.value) {
lines.push(`- ${e.in} -> ${e.out}`)
}
lines.push(task)
return lines.join('\n')
})
const output = computed(() => {
if (!withExamples.value) {
return tone.value === 'casual' ? "I'm fine." : 'I am fine.'
}
return tone.value === 'casual' ? "I'm good!" : 'I am doing well.'
})
const hint = computed(() => {
if (!withExamples.value) return '没有示例:AI 可能随便选一种语气。'
return '有示例:AI 更容易“保持同一种语气”。'
})
</script>
<style scoped>
.few-shot-demo {
.few {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
border-radius: 12px;
background: var(--vp-c-bg-soft);
padding: 16px;
margin: 20px 0;
}
.mode-switch {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-direction: column;
gap: 12px;
}
.mode-switch button {
padding: 8px 16px;
border-radius: 20px;
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg);
cursor: pointer;
transition: all 0.2s;
font-size: 0.9em;
}
.header { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.title { font-weight: 800; }
.subtitle { color: var(--vp-c-text-2); font-size: 13px; }
.controls { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
select { border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 8px 10px; background: var(--vp-c-bg); color: var(--vp-c-text-1); }
.toggle { border: 1px solid var(--vp-c-divider); background: var(--vp-c-bg); padding: 8px 12px; border-radius: 999px; cursor: pointer; }
.toggle.active { border-color: var(--vp-c-brand); color: var(--vp-c-brand); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.mode-switch button.active {
background: var(--vp-c-brand);
color: white;
border-color: var(--vp-c-brand);
}
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.panel { background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.panel-title { font-weight: 700; }
pre { margin: 0; background: #0b1221; color: #e5e7eb; border-radius: 8px; padding: 12px; font-family: var(--vp-font-family-mono); font-size: 13px; overflow-x: auto; white-space: pre-wrap; }
.output { white-space: pre-wrap; line-height: 1.6; }
.hint { color: var(--vp-c-text-2); font-size: 13px; }
.demo-container {
background: var(--vp-c-bg);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.prompt-box,
.output-box {
background: var(--vp-c-bg-soft);
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
padding: 15px;
}
.prompt-header,
.output-header {
font-size: 0.8rem;
color: var(--vp-c-text-3);
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: bold;
}
.prompt-content,
.output-content {
font-size: 0.9rem;
color: var(--vp-c-text-1);
line-height: 1.6;
}
.examples {
background: #000;
border-radius: 4px;
padding: 12px;
margin-bottom: 12px;
}
.example-item {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
font-family: monospace;
font-size: 0.85rem;
}
.example-item:last-child {
margin-bottom: 0;
}
.example-item .input {
color: #60a5fa;
}
.example-item .output {
color: #22c55e;
}
.task {
background: var(--vp-c-brand);
color: white;
padding: 10px;
border-radius: 4px;
font-size: 0.9rem;
}
.arrow {
text-align: center;
font-size: 2rem;
color: var(--vp-c-text-3);
margin: 15px 0;
}
.comment {
display: block;
margin-top: 10px;
padding: 8px;
border-radius: 4px;
font-size: 0.8rem;
}
.comment:not(.success) {
background: rgba(239, 68, 68, 0.1);
color: #ef4444;
}
.comment.success {
background: rgba(34, 197, 94, 0.1);
color: #22c55e;
}
.explanation {
padding: 12px;
background: var(--vp-c-bg-mute);
border-radius: 6px;
font-size: 0.9em;
line-height: 1.6;
}
.examples { background: var(--vp-c-bg); border: 1px dashed var(--vp-c-divider); border-radius: 10px; padding: 12px; }
.examples-title { font-weight: 700; margin-bottom: 8px; }
.examples-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
.ex { border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 10px; background: var(--vp-c-bg-soft); }
.in { color: var(--vp-c-text-2); font-size: 13px; }
.out { font-weight: 700; margin-top: 4px; }
</style>
@@ -1,201 +1,204 @@
<!--
PromptComparisonDemo.vue
清晰 vs 模糊对比把一个提示词拆成四块任务/上下文/要求/输出并展示哪些块缺失会导致输出跑偏
-->
<template>
<div class="prompt-comparison">
<div class="comparison-container">
<!-- Bad Prompt -->
<div class="prompt-card bad">
<div class="card-header">
<span class="card-icon"></span>
<span class="card-title">模糊提示词</span>
</div>
<div class="card-body">
<div class="prompt-text">"写个文章"</div>
<div class="result-box">
<div class="result-label">AI 输出</div>
<div class="result-content">
好的这是一篇关于某个主题的文章...
<br><br>
<span class="result-comment"> 不清楚要写什么主题风格长度</span>
</div>
</div>
</div>
<div class="cmp">
<div class="header">
<div>
<div class="title">清晰 vs 模糊差的不是废话而是缺项</div>
<div class="subtitle">勾选你想补充的信息看看输出会怎么变</div>
</div>
<!-- Good Prompt -->
<div class="prompt-card good">
<div class="card-header">
<span class="card-icon"></span>
<span class="card-title">清晰提示词</span>
</div>
<div class="card-body">
<div class="prompt-text">
"请以<strong>技术博客</strong>的形式,写一篇关于<strong>提示词工程</strong>的文章。
目标读者:<strong>初学者</strong>。字数:<strong>800-1000 字</strong>。
包含<strong>3 个实用技巧</strong>和<strong>代码示例</strong>。"
</div>
<div class="result-box">
<div class="result-label">AI 输出</div>
<div class="result-content">
# 提示词工程入门指南
<br><br>
作为 AI 时代的核心技能...
<br><br>
<span class="result-comment success"> 符合所有要求输出精准</span>
</div>
</div>
</div>
<div class="task">
<select v-model="task">
<option value="blog">写一段技术博客开头</option>
<option value="json">把内容输出成 JSON</option>
</select>
</div>
</div>
<div class="key-points">
<div class="point">
<span class="point-icon">🎯</span>
<span><strong>明确目标</strong>说明要做什么写文章写代码分析</span>
<div class="options">
<label><input type="checkbox" v-model="useRole" /> 角色你是谁</label>
<label><input type="checkbox" v-model="useAudience" /> 受众写给谁</label>
<label><input type="checkbox" v-model="useConstraints" /> 约束长度/要点数</label>
<label><input type="checkbox" v-model="useFormat" /> 输出格式JSON/列表</label>
</div>
<div class="grid">
<div class="panel">
<div class="panel-title">你给 AI 的提示词</div>
<pre><code>{{ prompt }}</code></pre>
<div class="checklist">
<div class="item" v-for="i in checklist" :key="i.text">
<span :class="['dot', i.ok ? 'ok' : 'bad']"></span>
<span>{{ i.text }}</span>
</div>
</div>
</div>
<div class="point">
<span class="point-icon">📋</span>
<span><strong>提供细节</strong>主题风格长度格式等具体要求</span>
</div>
<div class="point">
<span class="point-icon">👥</span>
<span><strong>指定受众</strong>说明目标读者初学者/专家/儿童等</span>
<div class="panel">
<div class="panel-title">AI 输出示意</div>
<div class="output">{{ output }}</div>
<div class="warn" v-if="warnings.length">
<div class="warn-title">可能的问题</div>
<ul>
<li v-for="w in warnings" :key="w">{{ w }}</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.prompt-comparison {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
background: var(--vp-c-bg-soft);
margin: 20px 0;
}
<script setup>
import { computed, ref } from 'vue'
.comparison-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
const task = ref('blog')
const useRole = ref(false)
const useAudience = ref(true)
const useConstraints = ref(true)
const useFormat = ref(false)
@media (max-width: 768px) {
.comparison-container {
grid-template-columns: 1fr;
const prompt = computed(() => {
if (task.value === 'blog') {
const lines = []
if (useRole.value) lines.push('你是资深前端工程师。')
lines.push('请写一段技术博客的开头,主题:提示词工程。')
if (useAudience.value) lines.push('目标读者:零基础新手。')
if (useConstraints.value) lines.push('要求:80-120 字,口语化,带一个生活类比。')
if (useFormat.value) lines.push('输出:只输出一段文字,不要标题。')
return lines.join('\n')
}
}
.prompt-card {
background: var(--vp-c-bg);
border: 2px solid var(--vp-c-divider);
border-radius: 8px;
overflow: hidden;
}
// json task
const lines = []
if (useRole.value) lines.push('你是信息抽取助手。')
lines.push('从下面这段文字中提取关键信息。')
if (useAudience.value) lines.push('用途:给产品经理快速阅读。')
if (useConstraints.value) lines.push('要求:提取 3-5 个关键词 + 1 句摘要。')
if (useFormat.value) {
lines.push('输出格式(JSON):')
lines.push('{')
lines.push(' "summary": "...",')
lines.push(' "keywords": ["..."]')
lines.push('}')
}
lines.push('输入:')
lines.push('“提示词工程能显著提升模型输出质量,但需要清晰任务、约束和格式。”')
return lines.join('\n')
})
.prompt-card.bad {
border-color: #ef4444;
}
const checklist = computed(() => [
{ text: '任务清晰(要做什么)', ok: true },
{ text: '角色(用什么口吻)', ok: useRole.value },
{ text: '受众/用途(给谁用)', ok: useAudience.value },
{ text: '约束(长度/数量/范围)', ok: useConstraints.value },
{ text: '输出格式(如何交付)', ok: useFormat.value }
])
.prompt-card.good {
border-color: #22c55e;
}
const warnings = computed(() => {
const w = []
if (!useAudience.value) w.push('语气可能过专业或太泛')
if (!useConstraints.value) w.push('长度/结构可能不稳定')
if (task.value === 'json' && !useFormat.value) w.push('可能输出成一大段话,不是 JSON')
if (task.value === 'blog' && !useFormat.value) w.push('可能加标题/分段,超出预期')
return w
})
.card-header {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 15px;
background: var(--vp-c-bg-mute);
}
const output = computed(() => {
if (task.value === 'blog') {
if (warnings.value.length >= 2) {
return '提示词工程是一种与 AI 沟通的方法,它可以帮助你获得更好的输出......(可能偏长/风格不稳)'
}
return '把 AI 当成新来的同事:你说得越清楚,它越不容易跑偏。提示词工程就是把“要做什么、给谁、怎么交付”一次说明白。'
}
.bad .card-header {
background: rgba(239, 68, 68, 0.1);
}
// json
if (!useFormat.value) {
return '这段文字主要讲提示词工程的重要性,并强调需要清晰任务、约束和格式……(但不是 JSON)'
}
return `{\n \"summary\": \"提示词工程能提升输出质量,关键在于清晰任务、约束与格式。\",\n \"keywords\": [\"提示词工程\", \"任务清晰\", \"约束\", \"格式\"]\n}`
})
</script>
.good .card-header {
background: rgba(34, 197, 94, 0.1);
}
.card-icon {
font-size: 1.3rem;
}
.card-title {
font-weight: bold;
font-size: 0.95rem;
color: var(--vp-c-text-1);
}
.card-body {
padding: 15px;
}
.prompt-text {
background: var(--vp-c-bg-soft);
<style scoped>
.cmp {
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
padding: 12px;
font-family: monospace;
font-size: 0.85rem;
color: var(--vp-c-text-1);
margin-bottom: 15px;
line-height: 1.6;
}
.result-box {
border-radius: 12px;
background: var(--vp-c-bg-soft);
border-radius: 6px;
padding: 16px;
margin: 20px 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.header {
display: flex;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.title { font-weight: 800; }
.subtitle { color: var(--vp-c-text-2); font-size: 13px; }
select {
border: 1px solid var(--vp-c-divider);
border-radius: 10px;
padding: 8px 10px;
background: var(--vp-c-bg);
color: var(--vp-c-text-1);
}
.options {
display: flex;
gap: 12px;
flex-wrap: wrap;
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
border-radius: 10px;
padding: 10px 12px;
font-size: 14px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
}
.panel {
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
border-radius: 10px;
padding: 12px;
}
.result-label {
font-size: 0.75rem;
color: var(--vp-c-text-3);
margin-bottom: 8px;
}
.result-content {
font-size: 0.85rem;
color: var(--vp-c-text-2);
line-height: 1.6;
}
.result-comment {
display: block;
margin-top: 10px;
padding: 8px;
border-radius: 4px;
font-size: 0.8rem;
}
.result-comment:not(.success) {
background: rgba(239, 68, 68, 0.1);
color: #ef4444;
}
.result-comment.success {
background: rgba(34, 197, 94, 0.1);
color: #22c55e;
}
.key-points {
display: flex;
flex-direction: column;
gap: 10px;
}
.point {
display: flex;
align-items: flex-start;
gap: 10px;
background: var(--vp-c-bg);
.panel-title { font-weight: 700; }
pre {
margin: 0;
background: #0b1221;
color: #e5e7eb;
border-radius: 8px;
padding: 12px;
border-radius: 6px;
font-size: 0.9rem;
color: var(--vp-c-text-2);
font-family: var(--vp-font-family-mono);
font-size: 13px;
overflow-x: auto;
white-space: pre-wrap;
}
.point-icon {
font-size: 1.3rem;
}
.checklist { display: grid; gap: 6px; }
.item { display: flex; gap: 8px; align-items: center; color: var(--vp-c-text-2); font-size: 13px; }
.dot { width: 10px; height: 10px; border-radius: 50%; }
.dot.ok { background: #22c55e; }
.dot.bad { background: #ef4444; }
.output { white-space: pre-wrap; line-height: 1.6; }
.warn { border-top: 1px dashed var(--vp-c-divider); padding-top: 10px; }
.warn-title { font-weight: 700; margin-bottom: 6px; }
ul { margin: 0; padding-left: 18px; color: var(--vp-c-text-2); }
</style>
@@ -0,0 +1,205 @@
<!--
PromptQuickStartDemo.vue
提示词先玩后讲快速体验同一任务切换提示词写法看输出质量变化
交互
- 选择任务写文案/总结/写代码
- 选择提示词等级随口一句 / 清晰版 / 专业版
- 展示你写的提示词AI 输出并提示改进点
-->
<template>
<div class="quick">
<div class="header">
<div>
<div class="title">先玩一下同一个需求换一种说法</div>
<div class="subtitle">你改的不是字数而是边界标准</div>
</div>
<div class="controls">
<select v-model="taskId">
<option v-for="t in tasks" :key="t.id" :value="t.id">
{{ t.label }}
</option>
</select>
<div class="levels">
<button
v-for="l in levels"
:key="l.id"
:class="['level', { active: levelId === l.id }]"
@click="levelId = l.id"
>
{{ l.label }}
</button>
</div>
</div>
</div>
<div class="grid">
<div class="panel">
<div class="panel-title">提示词 / Prompt</div>
<pre><code>{{ prompt }}</code></pre>
<div class="hint">{{ promptHint }}</div>
</div>
<div class="panel">
<div class="panel-title">AI 输出 / Output示意</div>
<div class="output">{{ output }}</div>
<div class="hint">{{ outputHint }}</div>
</div>
</div>
<div class="tips">
<div class="tip" v-for="t in tips" :key="t.title">
<div class="tip-title">{{ t.title }}</div>
<div class="tip-body">{{ t.body }}</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
const tasks = [
{ id: 'copy', label: '写一段小红书文案' },
{ id: 'summary', label: '把一段文字总结成要点' },
{ id: 'code', label: '写一个小函数' }
]
const levels = [
{ id: 'vague', label: '随口一句' },
{ id: 'clear', label: '清晰版' },
{ id: 'pro', label: '专业版' }
]
const taskId = ref('copy')
const levelId = ref('vague')
const prompt = computed(() => {
if (taskId.value === 'copy') {
if (levelId.value === 'vague') return '写个咖啡杯文案'
if (levelId.value === 'clear')
return '写一段小红书风格文案,主题:保温咖啡杯。语气:轻松。长度:120-160 字。'
return `你是小红书资深种草博主。\n任务:写一段保温咖啡杯的种草文案。\n受众:通勤上班族。\n要求:\n- 120-160 字\n- 3 个卖点(颜值/密封/保温)\n- 结尾加一句行动号召\n输出:一段中文文案,不要标题。`
}
if (taskId.value === 'summary') {
if (levelId.value === 'vague') return '帮我总结一下这段文字'
if (levelId.value === 'clear')
return '把下面内容总结成 3-5 个要点,每点不超过 15 个字。'
return `任务:把输入文本总结成要点。\n要求:\n- 5 个以内\n- 每点 <= 15 字\n- 只输出要点列表,不要解释\n格式:Markdown 无序列表`
}
// code
if (levelId.value === 'vague') return '写个排序函数'
if (levelId.value === 'clear')
return '用 JavaScript 写一个快速排序函数,并给一个使用示例。'
return `你是资深前端工程师。\n任务:实现 quickSort(arr)。\n要求:\n- 纯函数(不修改原数组)\n- 处理重复值\n- 代码加简短注释\n- 给一个示例输入输出\n输出:只给 JS 代码块`
})
const output = computed(() => {
if (taskId.value === 'copy') {
if (levelId.value === 'vague') return '这是一款很好用的咖啡杯,适合日常使用...'
if (levelId.value === 'clear')
return '早八通勤救星!这只保温杯颜值在线,放包里不漏,热咖啡到下午还温温的...'
return '通勤党必备!奶油配色超耐看,密封圈一拧就稳,放包里也不怕洒;保温够久,早上冲的拿铁下午还是温热...想要链接评论区见~'
}
if (taskId.value === 'summary') {
if (levelId.value === 'vague') return '这段文字主要讲了……(可能很长)'
if (levelId.value === 'clear')
return '- 核心观点 1\n- 核心观点 2\n- 核心观点 3'
return '- 关键结论\n- 主要原因\n- 影响范围\n- 建议行动'
}
// code
if (levelId.value === 'vague') return 'function sort(arr) { /* ... */ }'
if (levelId.value === 'clear')
return 'function quickSort(arr) { /* ... */ }\nconsole.log(quickSort([3,1,2]))'
return `function quickSort(arr) {\n const a = [...arr]\n if (a.length <= 1) return a\n const pivot = a[0]\n const left = a.slice(1).filter(x => x < pivot)\n const right = a.slice(1).filter(x => x >= pivot)\n return [...quickSort(left), pivot, ...quickSort(right)]\n}\n\nconsole.log(quickSort([3, 1, 2, 2])) // [1,2,2,3]`
})
const promptHint = computed(() => {
if (levelId.value === 'vague') return '问题:AI 不知道你要什么标准。'
if (levelId.value === 'clear') return '好一点:有风格/长度,但仍缺少“检查标准”。'
return '最好:角色 + 任务 + 要求 + 输出格式,AI 很难跑偏。'
})
const outputHint = computed(() => {
if (levelId.value === 'vague') return '常见结果:泛泛而谈、风格不稳、格式不对。'
if (levelId.value === 'clear') return '常见结果:更像你要的,但细节/格式可能还会飘。'
return '常见结果:风格稳定、结构清晰、可直接复制使用。'
})
const tips = computed(() => {
if (levelId.value === 'vague') {
return [
{ title: '先补 3 件事', body: '你要做什么?给谁看?最后要什么格式?' },
{ title: '别怕写长', body: '长不是目的,“可检查”才是目的。' }
]
}
if (levelId.value === 'clear') {
return [
{ title: '再加一条', body: '加“输出格式”或“要点数量”,能明显更稳。' },
{ title: '再加一个例子', body: '给 1 个示例,AI 会更像你的口吻。' }
]
}
return [
{ title: '记住模板', body: '角色 / 任务 / 输入 / 要求 / 输出格式。' },
{ title: '写完就测', body: '同一输入跑 2-3 次,看是否稳定。' }
]
})
</script>
<style scoped>
.quick {
border: 1px solid var(--vp-c-divider);
border-radius: 12px;
background: var(--vp-c-bg-soft);
padding: 16px;
margin: 20px 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.header {
display: flex;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.title { font-weight: 800; }
.subtitle { color: var(--vp-c-text-2); font-size: 13px; }
.controls { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
select {
border: 1px solid var(--vp-c-divider);
border-radius: 10px;
padding: 8px 10px;
background: var(--vp-c-bg);
color: var(--vp-c-text-1);
}
.levels { display: flex; gap: 8px; flex-wrap: wrap; }
.level {
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg);
padding: 8px 12px;
border-radius: 999px;
cursor: pointer;
}
.level.active {
border-color: var(--vp-c-brand);
color: var(--vp-c-brand);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.panel { background: var(--vp-c-bg); border: 1px solid var(--vp-c-divider); border-radius: 10px; padding: 12px; }
.panel-title { font-weight: 700; margin-bottom: 6px; }
pre { margin: 0; background: #0b1221; color: #e5e7eb; border-radius: 8px; padding: 12px; font-family: var(--vp-font-family-mono); font-size: 13px; overflow-x: auto; white-space: pre-wrap; }
.output { color: var(--vp-c-text-1); white-space: pre-wrap; line-height: 1.6; }
.hint { margin-top: 6px; color: var(--vp-c-text-2); font-size: 13px; }
.tips { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.tip { background: var(--vp-c-bg); border: 1px dashed var(--vp-c-divider); border-radius: 10px; padding: 10px; }
.tip-title { font-weight: 700; margin-bottom: 4px; }
.tip-body { color: var(--vp-c-text-2); font-size: 13px; line-height: 1.5; }
</style>