Prompt Playground(实现提示词工作台)

本次功能

Prompt Playground(提示词工作台)

效果:

  • 每个会话都能单独编辑 system prompt
  • 可以恢复到当前角色的默认 prompt
  • 修改后立即影响后续对话
  • 更像真正的 AI 产品调试台

1)改 web/src/utils/session.js

createSession

yaml 复制代码
  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

ini 复制代码
    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

新增状态

csharp 复制代码
const promptDraft = ref('')

新增计算属性

javascript 复制代码
const currentSystemPrompt = computed(() => {
  return currentSession.value?.customPrompt || ''
})

新增监听

ini 复制代码
watch(
  currentSystemPrompt,
  newVal => {
    promptDraft.value = newVal || ''
  },
  { immediate: true }
)

resetSystemMessageByMode

ini 复制代码
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

ini 复制代码
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 个方法

ini 复制代码
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)改模板

添加

ini 复制代码
<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)补样式

css 复制代码
.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 !

相关推荐
无籽西瓜a2 小时前
【西瓜带你学设计模式 | 第三期-工厂方法模式】工厂方法模式——定义、实现方式、优缺点与适用场景以及注意事项
java·后端·设计模式·工厂方法模式
竹林8182 小时前
在NFT项目中集成IPFS:从Pinata上传到前端展示的完整实战与踩坑
前端·javascript
取名不易2 小时前
canves实现画布
前端
华农DrLai2 小时前
什么是远程监督?怎么自动生成训练数据?
人工智能·算法·llm·prompt·知识图谱
格林威2 小时前
Baumer相机铝型材表面划伤长度测量:实现损伤量化评估的 5 个关键技术,附 OpenCV+Halcon 实战代码!
开发语言·人工智能·数码相机·opencv·计算机视觉·c#·工业相机
AlkaidSTART2 小时前
深入浅出 React Hooks 原理:从 Fiber 的 memoizedState 链表讲到 updateQueue 调度
前端
ZBLHai2 小时前
智标领航 AI 写标书:让投标编标效率翻倍,聚焦核心赢标策略
大数据·人工智能
Roselind_Yi2 小时前
【吴恩达2026 Agentic AI】面试向+项目实战(含面试题+项目案例)-2
人工智能·python·机器学习·面试·职场和发展·langchain·agent
谁在黄金彼岸2 小时前
MariaDB Docker容器权限配置问题分析与解决方案
后端·docker·容器