本次功能
Prompt Playground(提示词工作台)
效果:
- 每个会话都能单独编辑 system prompt
- 可以恢复到当前角色的默认 prompt
- 修改后立即影响后续对话
- 更像真正的 AI 产品调试台
1)改 web/src/utils/session.js
createSession
return {
id: crypto.randomUUID(),
title,
mode,
customPrompt: persona.systemPrompt,
pinned: false,
createdAt: Date.now(),
updatedAt: Date.now(),
messages: [
{
role: 'system',
content: persona.systemPrompt,
},
{
role: 'assistant',
content: '你好,我已经准备好了。你今天想聊什么?',
},
],
}
改 loadSessions 里的 normalize
const normalized = sessions.map(item => {
const mode = item.mode || 'companion'
const persona = PERSONA_MAP[mode] || PERSONA_MAP.companion
return {
mode,
customPrompt: item.customPrompt || item.messages?.find(m => m.role === 'system')?.content || persona.systemPrompt,
pinned: false,
...item,
}
})
2)改 web/src/App.vue
新增状态
const promptDraft = ref('')
新增计算属性
const currentSystemPrompt = computed(() => {
return currentSession.value?.customPrompt || ''
})
新增监听
watch(
currentSystemPrompt,
newVal => {
promptDraft.value = newVal || ''
},
{ immediate: true }
)
resetSystemMessageByMode
const resetSystemMessageByMode = (messages = [], mode = 'companion', prompt) => {
const persona = PERSONA_MAP[mode] || PERSONA_MAP.companion
const finalPrompt = prompt || persona.systemPrompt
const nextMessages = [...messages]
const systemIndex = nextMessages.findIndex(item => item.role === 'system')
if (systemIndex > -1) {
nextMessages[systemIndex] = {
...nextMessages[systemIndex],
content: finalPrompt,
}
} else {
nextMessages.unshift({
role: 'system',
content: finalPrompt,
})
}
return nextMessages
}
handleChangeSessionMode
const handleChangeSessionMode = (id, mode) => {
const persona = PERSONA_MAP[mode] || PERSONA_MAP.companion
sessions.value = sortSessions(
sessions.value.map(item =>
item.id === id
? {
...item,
mode,
customPrompt: persona.systemPrompt,
updatedAt: Date.now(),
messages: resetSystemMessageByMode(item.messages, mode, persona.systemPrompt),
}
: item
)
)
}
新增 3 个方法
const handleSavePrompt = () => {
if (!currentSession.value) return
const nextPrompt = promptDraft.value.trim()
if (!nextPrompt) return
sessions.value = sortSessions(
sessions.value.map(item =>
item.id === currentSessionId.value
? {
...item,
customPrompt: nextPrompt,
updatedAt: Date.now(),
messages: resetSystemMessageByMode(item.messages, item.mode, nextPrompt),
}
: item
)
)
}
const handleResetPrompt = () => {
if (!currentSession.value) return
const persona = PERSONA_MAP[currentSession.value.mode] || PERSONA_MAP.companion
promptDraft.value = persona.systemPrompt
sessions.value = sortSessions(
sessions.value.map(item =>
item.id === currentSessionId.value
? {
...item,
customPrompt: persona.systemPrompt,
updatedAt: Date.now(),
messages: resetSystemMessageByMode(item.messages, item.mode, persona.systemPrompt),
}
: item
)
)
}
const handleUsePromptTemplate = template => {
promptDraft.value = template
}
3)改模板
添加
<div class="prompt-panel">
<div class="prompt-panel-header">
<div class="prompt-panel-title">Prompt Playground</div>
<div class="prompt-panel-actions">
<button class="prompt-btn secondary" @click="handleResetPrompt">恢复默认</button>
<button class="prompt-btn" @click="handleSavePrompt">保存 Prompt</button>
</div>
</div>
<textarea
v-model="promptDraft"
class="prompt-textarea"
placeholder="编辑当前会话的 system prompt"
/>
<div class="prompt-template-list">
<span
class="prompt-template-tag"
@click="handleUsePromptTemplate('你是一个专业、友好、清晰的 AI 助手,回答准确,表达简洁。')"
>
通用助手
</span>
<span
class="prompt-template-tag"
@click="handleUsePromptTemplate('你是一个资深技术顾问,回答时要结构化、专业、可执行,优先给出步骤、代码和避坑建议。')"
>
技术顾问模板
</span>
<span
class="prompt-template-tag"
@click="handleUsePromptTemplate('你是一个资深面试教练,请从面试官视角给出高质量回答,突出考点、答题框架和表达建议。')"
>
面试教练模板
</span>
<span
class="prompt-template-tag"
@click="handleUsePromptTemplate('你是一个温柔、稳定、善于倾听和鼓励的陪伴型 AI,回答自然、真诚、有情绪价值。')"
>
陪伴模板
</span>
</div>
</div>
4)补样式
.prompt-panel {
margin-bottom: 16px;
padding: 16px;
border: 1px solid #e5e7eb;
border-radius: 12px;
background: #fafafa;
}
.prompt-panel-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.prompt-panel-title {
font-size: 16px;
font-weight: 600;
color: #111827;
}
.prompt-panel-actions {
display: flex;
align-items: center;
gap: 8px;
}
.prompt-btn {
border: none;
border-radius: 10px;
background: #111827;
color: #fff;
padding: 8px 12px;
font-size: 12px;
cursor: pointer;
}
.prompt-btn.secondary {
background: #6b7280;
}
.prompt-textarea {
width: 100%;
min-height: 96px;
resize: vertical;
box-sizing: border-box;
border: 1px solid #d1d5db;
border-radius: 10px;
padding: 12px;
font-size: 14px;
line-height: 1.6;
outline: none;
background: #fff;
margin-bottom: 12px;
}
.prompt-template-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.prompt-template-tag {
display: inline-flex;
align-items: center;
padding: 6px 10px;
border-radius: 999px;
background: #eef2ff;
color: #4338ca;
font-size: 12px;
cursor: pointer;
}
.prompt-template-tag:hover {
background: #e0e7ff;
}
5)验证
测试 1:自定义 Prompt
把 prompt 改成:
你是一个只用项目符号回答的技术顾问,回答必须简洁,每次最多 5 条。
然后问:
如何准备 AI Agent 岗位面试
测试 2:恢复默认
点“恢复默认”,再问同一个问题,回答风格应该回到当前角色默认风格。
测试 3:模板切换
点不同模板标签,再保存,马上提问,回答应该切换风格。
nice !