From 2e7789df63c6935cf97eee75fb9f2d494f676c72 Mon Sep 17 00:00:00 2001 From: Julian Freeman Date: Sun, 5 Apr 2026 17:40:50 -0400 Subject: [PATCH] optimize chat prompts --- src/components/ConversationView.vue | 36 ++++++++------ src/components/SettingsView.vue | 6 +-- src/stores/settings.ts | 73 +++++++++++++++-------------- 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/components/ConversationView.vue b/src/components/ConversationView.vue index 456a123..de0a2d3 100644 --- a/src/components/ConversationView.vue +++ b/src/components/ConversationView.vue @@ -181,7 +181,10 @@ const translateMessage = async (sender: 'me' | 'partner', retranslateId?: string // 3. Prepare Prompt const fromLang = sender === 'me' ? activeSession.value.me.language : activeSession.value.partner.language; const toLang = sender === 'me' ? activeSession.value.partner.language : activeSession.value.me.language; - const myToneLabel = TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.label || '随和'; + const targetTone = sender === 'me' + ? TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.value || 'Polite & Conversational' + : 'Auto-detect'; + const senderName = sender === 'me' ? activeSession.value.me.name : activeSession.value.partner.name; const systemPrompt = settings.chatSystemPromptTemplate .replace(/{ME_NAME}/g, activeSession.value.me.name) @@ -191,15 +194,16 @@ const translateMessage = async (sender: 'me' | 'partner', retranslateId?: string .replace(/{PART_GENDER}/g, activeSession.value.partner.gender) .replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName) .replace(/{HISTORY_BLOCK}/g, historyBlock || 'None (This is the start of conversation)') + .replace(/{SENDER_NAME}/g, senderName) .replace(/{FROM_LANG}/g, fromLang.englishName) .replace(/{TO_LANG}/g, toLang.englishName) - .replace(/{MY_TONE}/g, myToneLabel); + .replace(/{TARGET_TONE}/g, targetTone); const requestBody = { model: settings.modelName, messages: [ { role: "system", content: systemPrompt }, - { role: "user", content: text } + { role: "user", content: `[Text to Translate]\n${text}` } ], stream: settings.enableStreaming }; @@ -271,8 +275,8 @@ const evaluateMessage = async (messageId: string, force = false) => { // 动态确定目标语气约束 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)?.value || 'Polite & Conversational') + : 'Auto-detect'; const systemPrompt = settings.chatEvaluationPromptTemplate .replace(/{ME_NAME}/g, activeSession.value.me.name) @@ -285,9 +289,9 @@ const evaluateMessage = async (messageId: string, force = false) => { .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); + .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}`; @@ -367,14 +371,15 @@ const refineMessage = async (messageId: string) => { return `${senderName}: "${m.original}"`; }).join('\n'); - const myToneLabel = TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.label || '随和'; - // 确定目标语气 - const targetTone = msg.sender === 'me' ? myToneLabel : '自动识别 (保持原作者原始语气和情绪)'; + const targetTone = msg.sender === 'me' + ? TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.value || 'Polite & Conversational' + : 'Auto-detect'; // 动态确定语言方向 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 systemPrompt = settings.chatRefinementPromptTemplate .replace(/{ME_NAME}/g, activeSession.value.me.name) @@ -384,10 +389,11 @@ const refineMessage = async (messageId: string) => { .replace(/{PART_GENDER}/g, activeSession.value.partner.gender) .replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName) .replace(/{HISTORY_BLOCK}/g, historyBlock || 'None') - .replace(/{ORIGINAL_TEXT}/g, msg.original) - .replace(/{CURRENT_TRANSLATION}/g, msg.translated) - .replace(/{SUGGESTIONS}/g, suggestionsText) + // .replace(/{ORIGINAL_TEXT}/g, msg.original) + // .replace(/{CURRENT_TRANSLATION}/g, msg.translated) + // .replace(/{SUGGESTIONS}/g, suggestionsText) .replace(/{TARGET_TONE}/g, targetTone) + .replace(/{SENDER_NAME}/g, senderName) .replace(/{FROM_LANG}/g, fromLang.englishName) .replace(/{TO_LANG}/g, toLang.englishName); @@ -409,7 +415,7 @@ const refineMessage = async (messageId: string) => { model: refineModelName, messages: [ { role: "system", content: systemPrompt }, - { role: "user", content: `Please refine the following original text: ${msg.original}` } + { role: "user", content: `[Source Text]\n${msg.original}\n\n[Current Translation]\n${msg.translated}\n\n[Suggestions]\n${suggestionsText}` } ], stream: settings.enableStreaming }; diff --git a/src/components/SettingsView.vue b/src/components/SettingsView.vue index b4edc34..83a55d8 100644 --- a/src/components/SettingsView.vue +++ b/src/components/SettingsView.vue @@ -536,7 +536,7 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick)); >
- {{ tag }} + {{ tag }}
@@ -558,7 +558,7 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick)); >
- {{ tag }} + {{ tag }}
@@ -580,7 +580,7 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick)); >
- {{ tag }} + {{ tag }}
diff --git a/src/stores/settings.ts b/src/stores/settings.ts index 35280fb..3d15f02 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -154,50 +154,54 @@ export interface ChatSession { lastActivity: string; } -export const CONVERSATION_SYSTEM_PROMPT_TEMPLATE = `You are a professional real-time conversation translator. -Current Context: -- Role A (Me): {ME_NAME}, Gender: {ME_GENDER}, Language: {ME_LANG}. -- Role B (Other): {PART_NAME}, Gender: {PART_GENDER}, Language: {PART_LANG}. +export const CONVERSATION_SYSTEM_PROMPT_TEMPLATE = `# Role: Professional Real-time Conversation Translator -[Conversation History] +# Participants: +- Participant A: [Name: {ME_NAME}, Gender: {ME_GENDER}, Language: {ME_LANG}] +- Participant B: [Name: {PART_NAME}, Gender: {PART_GENDER}, Language: {PART_LANG}] + +# Recent Conversation Flow: {HISTORY_BLOCK} -[Current Task] -Translate the incoming text from {FROM_LANG} to {TO_LANG}. +# Current Turn to Translate: +- Speaker: {SENDER_NAME} +- Source Language: {FROM_LANG} +- Target Language: {TO_LANG} +- Intended Tone/Register: {TARGET_TONE} -[Constraints] +# Constraints 1. Contextual Awareness: Use the [Conversation History] to resolve pronouns (it, that, etc.) and maintain consistency. -2. Tone & Register: - - If translating for 'Me', strictly use the tone: {MY_TONE}. - - If translating for 'Other', auto-detect and preserve their original tone/emotion. +2. Personalization & Tone: Ensure all grammatical agreements and self-referential terms reflect speaker's gender. Faithfully replicate the intended tone, maintaining the formality, emotional nuance, and unique style of the source text without neutralizing it. 3. Natural Flow: Keep the translation concise and natural for a chat environment. Avoid "translationese". 4. Strictly avoid over-translation: Do not add extra information not present in the source text. 5. Output ONLY the translated text, no explanations.`; export const CONVERSATION_EVALUATION_PROMPT_TEMPLATE = `# Role: Expert Conversation Auditor -# Context Info -- Role A (Me): {ME_NAME} ({ME_GENDER}, Native {ME_LANG}) -- Role B (Other): {PART_NAME} ({PART_GENDER}, Native {PART_LANG}) +# Participants: +- Participant A: [Name: {ME_NAME}, Gender: {ME_GENDER}, Language: {ME_LANG}] +- Participant B: [Name: {PART_NAME}, Gender: {PART_GENDER}, Language: {PART_LANG}] -# Recent Conversation Flow (Original Messages Only): +# Recent Conversation Flow: {HISTORY_BLOCK} # Current Turn to Audit: - Speaker: {SENDER_NAME} -- Direction: {FROM_LANG} -> {TO_LANG} -- Source Text ({FROM_LANG}): {ORIGINAL_TEXT} -- Translation ({TO_LANG}): {CURRENT_TRANSLATION} +- Source Language: {FROM_LANG} +- Target Language: {TO_LANG} +- Intended Tone/Register: {TARGET_TONE} -# Audit Priorities -1. **Contextual Accuracy**: Does the translation correctly reflect the meaning based on the [Recent Conversation Flow]? -2. **Relational Tone**: - - If the Speaker is 'Me', does it match the target tone({TARGET_TONE})? - - If the Speaker is 'Other', does it preserve their original tone/emotion? -3. **Naturalness**: Is it concise and fit for an IM (Instant Messaging) environment? +# Audit Criteria +1. **Contextual Inaccuracy**: Failure to correctly reflect the meaning based on the [Recent Conversation Flow] +2. **Semantic Error**: Objective misalignment with the source meaning or complete hallucinations. +3. **Grammatical Error**: Clear violations of target language grammar or syntax rules. +4. **Tone Failure**: A tone that is the opposite or significantly different from the [Intended Tone/Register]. +5. **Poor Readability**: The phrasing is so stiff, unnatural, or convoluted that it hinders smooth comprehension (e.g., obvious "translationese" or broken logic). + +**Note**: Do NOT penalize if the translation is simply "not the most elegant" or if there's a subjective preference for a different synonym. If it's natural enough for a native speaker to understand without effort, it's acceptable. # Instructions -1. **Evaluation**: Compare the [Source Text] and [Translation] based on the [Audit Priorities]. +1. **Evaluation**: Compare the [Source Text] and [Translation] based on the [Audit Criteria]. 2. **Scoring Strategy**: - **90-100**: Accurate, grammatically sound, and flows naturally. - **75-89**: Accurate meaning, but suffers from "stiff" phrasing or minor flow issues that need adjustment. @@ -217,26 +221,23 @@ Respond ONLY in JSON. "analysis" and "text" MUST be in Simplified Chinese: export const CONVERSATION_REFINEMENT_PROMPT_TEMPLATE = `# Role: Professional Conversation Editor -# Context: -- Role A (Me): {ME_NAME} ({ME_GENDER}, Native {ME_LANG}) -- Role B (Other): {PART_NAME} ({PART_GENDER}, Native {PART_LANG}) +# Participants: +- Participant A: [Name: {ME_NAME}, Gender: {ME_GENDER}, Language: {ME_LANG}] +- Participant B: [Name: {PART_NAME}, Gender: {PART_GENDER}, Language: {PART_LANG}] -# Recent Conversation Flow (Original Messages Only): +# Recent Conversation Flow: {HISTORY_BLOCK} # Current Turn to Refine: - Speaker: {SENDER_NAME} -- Direction: {FROM_LANG} -> {TO_LANG} -- Source Text ({FROM_LANG}): {ORIGINAL_TEXT} -- Current Translation ({TO_LANG}): {CURRENT_TRANSLATION} - -# Suggestions to Apply: -{SUGGESTIONS} +- Source Language: {FROM_LANG} +- Target Language: {TO_LANG} +- Intended Tone/Register: {TARGET_TONE} # Instructions: 1. Carefully review the [Suggestions] and apply the requested improvements to the [Current Translation] while ensuring it fits naturally into the [Recent Conversation Flow]. 2. Ensure that the refined translation remains semantically identical to the [Source Text]. -3. If the Speaker is 'Me', strictly maintain the target tone({TARGET_TONE}); if the Speaker is 'Other', auto-detect and preserve their original tone/emotion. +3. Maintain the speaker's gender and [Intended Tone/Register] as specified. 4. If a piece of feedback contradicts the [Source Text], prioritize accuracy and provide a balanced refinement. 5. Produce ONLY the refined {TO_LANG} translation, without any additional explanations, notes, or commentary.`;