optimize prompts

This commit is contained in:
Julian Freeman
2026-04-05 12:55:50 -04:00
parent a8967809a2
commit f8785f4395
3 changed files with 50 additions and 41 deletions

View File

@@ -245,11 +245,17 @@ const evaluateMessage = async (messageId: string, force = false) => {
const historyLimit = 10; const historyLimit = 10;
const recentMessages = activeSession.value.messages.filter(m => m.id !== messageId).slice(-historyLimit); const recentMessages = activeSession.value.messages.filter(m => m.id !== messageId).slice(-historyLimit);
// 净化历史:只提供原文流
const historyBlock = recentMessages.map(m => { const historyBlock = recentMessages.map(m => {
const senderName = m.sender === 'me' ? activeSession.value!.me.name : activeSession.value!.partner.name; const senderName = m.sender === 'me' ? activeSession.value!.me.name : activeSession.value!.partner.name;
return `${senderName}: [Original] ${m.original} -> [Translated] ${m.translated}`; return `${senderName}: ${m.original}`;
}).join('\n'); }).join('\n');
// 动态确定语言方向
const fromLang = msg.sender === 'me' ? activeSession.value.me.language : activeSession.value.partner.language;
const toLang = msg.sender === 'me' ? activeSession.value.partner.language : activeSession.value.me.language;
const senderName = msg.sender === 'me' ? activeSession.value.me.name : activeSession.value.partner.name;
// 动态确定目标语气约束 // 动态确定目标语气约束
const targetTone = msg.sender === 'me' const targetTone = msg.sender === 'me'
? (TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.label || '随和') ? (TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.label || '随和')
@@ -263,7 +269,12 @@ const evaluateMessage = async (messageId: string, force = false) => {
.replace(/{PART_GENDER}/g, activeSession.value.partner.gender) .replace(/{PART_GENDER}/g, activeSession.value.partner.gender)
.replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName) .replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName)
.replace(/{HISTORY_BLOCK}/g, historyBlock || 'None') .replace(/{HISTORY_BLOCK}/g, historyBlock || 'None')
.replace(/{TARGET_TONE}/g, targetTone); .replace(/{TARGET_TONE}/g, targetTone)
.replace(/{SENDER_NAME}/g, senderName)
.replace(/{FROM_LANG}/g, fromLang.englishName)
.replace(/{TO_LANG}/g, toLang.englishName)
.replace(/{ORIGINAL_TEXT}/g, msg.original)
.replace(/{CURRENT_TRANSLATION}/g, msg.translated);
const userPrompt = `[Source Text]\n${msg.original}\n\n[Current Translation]\n${msg.translated}`; const userPrompt = `[Source Text]\n${msg.original}\n\n[Current Translation]\n${msg.translated}`;
@@ -337,9 +348,10 @@ const refineMessage = async (messageId: string) => {
const historyLimit = 10; const historyLimit = 10;
const recentMessages = activeSession.value.messages.filter(m => m.id !== messageId).slice(-historyLimit); const recentMessages = activeSession.value.messages.filter(m => m.id !== messageId).slice(-historyLimit);
// 净化历史:只提供原文流
const historyBlock = recentMessages.map(m => { const historyBlock = recentMessages.map(m => {
const senderName = m.sender === 'me' ? activeSession.value!.me.name : activeSession.value!.partner.name; const senderName = m.sender === 'me' ? activeSession.value!.me.name : activeSession.value!.partner.name;
return `${senderName}: [Original] ${m.original} -> [Translated] ${m.translated}`; return `${senderName}: ${m.original}`;
}).join('\n'); }).join('\n');
const myToneLabel = TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.label || '随和'; const myToneLabel = TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.label || '随和';
@@ -347,6 +359,10 @@ const refineMessage = async (messageId: string) => {
// 确定目标语气 // 确定目标语气
const targetTone = msg.sender === 'me' ? myToneLabel : '自动识别 (保持原作者原始语气和情绪)'; const targetTone = msg.sender === 'me' ? myToneLabel : '自动识别 (保持原作者原始语气和情绪)';
// 动态确定语言方向
const fromLang = msg.sender === 'me' ? activeSession.value.me.language : activeSession.value.partner.language;
const toLang = msg.sender === 'me' ? activeSession.value.partner.language : activeSession.value.me.language;
const systemPrompt = settings.chatRefinementPromptTemplate const systemPrompt = settings.chatRefinementPromptTemplate
.replace(/{ME_NAME}/g, activeSession.value.me.name) .replace(/{ME_NAME}/g, activeSession.value.me.name)
.replace(/{ME_GENDER}/g, activeSession.value.me.gender) .replace(/{ME_GENDER}/g, activeSession.value.me.gender)
@@ -358,7 +374,9 @@ const refineMessage = async (messageId: string) => {
.replace(/{ORIGINAL_TEXT}/g, msg.original) .replace(/{ORIGINAL_TEXT}/g, msg.original)
.replace(/{CURRENT_TRANSLATION}/g, msg.translated) .replace(/{CURRENT_TRANSLATION}/g, msg.translated)
.replace(/{SUGGESTIONS}/g, suggestionsText) .replace(/{SUGGESTIONS}/g, suggestionsText)
.replace(/{TARGET_TONE}/g, targetTone); .replace(/{TARGET_TONE}/g, targetTone)
.replace(/{FROM_LANG}/g, fromLang.englishName)
.replace(/{TO_LANG}/g, toLang.englishName);
const requestBody = { const requestBody = {
model: settings.modelName, model: settings.modelName,

View File

@@ -558,7 +558,7 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
></textarea> ></textarea>
<div class="px-5 py-3 bg-slate-50 dark:bg-slate-950 border-t dark:border-slate-800"> <div class="px-5 py-3 bg-slate-50 dark:bg-slate-950 border-t dark:border-slate-800">
<div class="flex flex-wrap gap-1.5"> <div class="flex flex-wrap gap-1.5">
<span v-for="tag in ['{ME_NAME}', '{ME_GENDER}', '{ME_LANG}', '{PART_NAME}', '{PART_GENDER}', '{PART_LANG}', '{TARGET_TONE}', '{HISTORY_BLOCK}']" :key="tag" class="px-2 py-0.5 bg-white dark:bg-slate-800 text-[10px] font-mono rounded-md border dark:border-slate-700 text-slate-500 shadow-sm">{{ tag }}</span> <span v-for="tag in ['{ME_NAME}', '{ME_GENDER}', '{ME_LANG}', '{PART_NAME}', '{PART_GENDER}', '{PART_LANG}', '{TARGET_TONE}', '{SENDER_NAME}', '{FROM_LANG}', '{TO_LANG}', '{HISTORY_BLOCK}', '{ORIGINAL_TEXT}', '{CURRENT_TRANSLATION}']" :key="tag" class="px-2 py-0.5 bg-white dark:bg-slate-800 text-[10px] font-mono rounded-md border dark:border-slate-700 text-slate-500 shadow-sm">{{ tag }}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -174,31 +174,26 @@ Translate the incoming text from {FROM_LANG} to {TO_LANG}.
4. Strictly avoid over-translation: Do not add extra information not present in the source text. 4. Strictly avoid over-translation: Do not add extra information not present in the source text.
5. Output ONLY the translated text, no explanations.`; 5. Output ONLY the translated text, no explanations.`;
export const CONVERSATION_EVALUATION_PROMPT_TEMPLATE = `# Role export const CONVERSATION_EVALUATION_PROMPT_TEMPLATE = `# Role: Expert Conversation Auditor
You are an expert Conversation Auditor. Your task is to evaluate if the [Current Translation] accurately reflects the [Source Text] within the specific flow of the [Conversation History].
# Context Info # Context Info
- Me: {ME_NAME} ({ME_GENDER}, {ME_LANG}) - Role A (Me): {ME_NAME} ({ME_GENDER}, Native {ME_LANG})
- Partner: {PART_NAME} ({PART_GENDER}, {PART_LANG}) - Role B (Partner): {PART_NAME} ({PART_GENDER}, Native {PART_LANG})
- Target Tone: {TARGET_TONE} - Target Tone: {TARGET_TONE}
[Conversation History] # Recent Conversation Flow (Original Messages Only):
{HISTORY_BLOCK} {HISTORY_BLOCK}
# Audit Priorities # Current Turn to Audit:
1. **Contextual Accuracy**: Do pronouns (it, that, etc.) correctly point to objects/topics mentioned in the [Conversation History]? - Speaker: {SENDER_NAME}
2. **Relational Tone**: Does the translation match the [Target Tone]? (e.g., if set to 'Polite', is it too casual?) - Direction: {FROM_LANG} -> {TO_LANG}
3. **Consistency**: Are names, terms, or previously established facts handled consistently? - Source Text ({FROM_LANG}): {ORIGINAL_TEXT}
4. **Naturalness**: Is it concise and fit for an IM (Instant Messaging) environment? - Translation ({TO_LANG}): {CURRENT_TRANSLATION}
# Instructions # Audit Priorities
1. Analyze the [Source Text] and [Current Translation] against the history. 1. **Contextual Accuracy**: Does the translation correctly reflect the meaning based on the [Recent Conversation Flow]?
2. Scoring: 0-100. 2. **Relational Tone**: Does it match the [Target Tone]?
3. Suggestions: Provide actionable improvements. 3. **Naturalness**: Is it concise and fit for an IM (Instant Messaging) environment?
4. **Severity Level**: For each suggestion, assign an "importance" score (0-100).
- **80-100 (Critical)**: Misunderstanding meaning, wrong pronoun reference, or offensive tone.
- **40-79 (Moderate)**: Unnatural phrasing, minor tone mismatch.
- **0-39 (Minor)**: Polishing, stylistic preferences.
# Output Format # Output Format
Respond ONLY in JSON. "analysis" and "text" MUST be in Simplified Chinese: Respond ONLY in JSON. "analysis" and "text" MUST be in Simplified Chinese:
@@ -210,32 +205,28 @@ Respond ONLY in JSON. "analysis" and "text" MUST be in Simplified Chinese:
] ]
}`; }`;
export const CONVERSATION_REFINEMENT_PROMPT_TEMPLATE = `You are a professional conversation editor. Refine the [Current Translation] based on the [Original Source Text], [Audit Suggestions], and [Conversation History]. export const CONVERSATION_REFINEMENT_PROMPT_TEMPLATE = `# Role: Professional Conversation Editor
# Context Info # Context:
- Role A (Me): {ME_NAME}, Gender: {ME_GENDER}, Language: {ME_LANG}. - Role A: {ME_NAME} ({ME_GENDER}, Native {ME_LANG})
- Role B (Partner): {PART_NAME}, Gender: {PART_GENDER}, Language: {PART_LANG}. - Role B: {PART_NAME} ({PART_GENDER}, Native {PART_LANG})
- Target Tone: {TARGET_TONE} - Target Tone: {TARGET_TONE}
[Conversation History] # Recent Conversation Flow (Original Messages Only):
{HISTORY_BLOCK} {HISTORY_BLOCK}
[Original Source Text] # Task: Refine the following translation
{ORIGINAL_TEXT} - Direction: {FROM_LANG} -> {TO_LANG}
- Source Text ({FROM_LANG}): {ORIGINAL_TEXT}
- Current Draft ({TO_LANG}): {CURRENT_TRANSLATION}
[Current Translation] # Suggestions to Apply:
{CURRENT_TRANSLATION}
[Audit Suggestions]
{SUGGESTIONS} {SUGGESTIONS}
# Task # Instructions:
Produce a new, refined version of the translation that addresses the suggestions while staying true to the original meaning and natural conversation flow. 1. Produce a new version of the translation that addresses the [Suggestions] while ensuring it fits naturally into the [Recent Conversation Flow].
2. Strictly maintain the {TARGET_TONE}.
# Constraints 3. Output ONLY the refined {TO_LANG} text. No preamble, no commentary.`;
1. Maintain semantic identity with the [Original Source Text].
2. Strictly follow the Target Tone.
3. Output ONLY the refined translation text. No explanations.`;
export const useSettingsStore = defineStore('settings', () => { export const useSettingsStore = defineStore('settings', () => {
const isDark = useLocalStorage('is-dark', false); const isDark = useLocalStorage('is-dark', false);