Nhiệm vụ: Sửa trình dịch

Sửa trình dịch

02.09.2026futurist.expert

Vì lý do nào đó, rất thường xuyên văn bản không được dịch chút nào, hoặc chỉ có tiêu đề được dịch. Đồng thời, phản hồi trả về success: true

Điều này rất không đáng tin cậy

Ворклоги

Это поправил. Проблема была в том, что агент нарушал форматирование в yaml-документе. Текстовый ответ прилетал такой:

en:
  name: |
    Growth in Specialist Productivity Requires Corresponding Development of the Business Technological Environment
description: |
  Business gets the maximum out of new technologies and strong specialists only when its own technological environment allows realizing their productivity.
content: |
  New technologies increase specialist productivity, but this productivity is not realized in a vacuum. 

Тут description и content являлись не вложенностью в en, как name, а уже новыеми разделами. В итоге получалась вот такая конечная структура ответа:

{
  en: {
    name: 'Growth in Specialist Productivity Requires Corresponding Development of the Business Technological Environment\n'
  },
  description: 'Business gets the maximum out of new technologies and strong specialists only when its own technological environment allows realizing their productivity.\n',
  content: 'New technologies increase specialist productivity, but this productivity is not realized in a vacuum.

То есть переведенным у нас тут являлось только название, а все остальное не попадало в обработку.

В итоге сделал две вещи:

1. Вынес в разные сообщения отдельно системный промпт со всеми правилась, а документ для перевода в пользовательское сообщение. При таком подходе логическая структура данных для llm более различима.

2. Усилил правила для форматирования yaml.

Получилось вот так:

const fieldsYaml = fieldsToTranslate
  .map(
    ({ field, value }) =>
      `${field}: |\n${value
        .split('\n')
        .map((line) => '  ' + line)
        .join('\n')}`,
  )
  .join('\n')

const fieldNames = fieldsToTranslate.map((f) => f.field)

const systemPrompt = `You are a professional translator specializing in technical documentation and web content.

# YAML OUTPUT RULES (CRITICAL)

You MUST output valid YAML with this EXACT structure:

\`\`\`
<lang_code>:
<field_name>: |
  <translated text line 1>
  <translated text line 2>
\`\`\`

**STRICT REQUIREMENTS:**
1. Each language code (en, de, etc.) MUST be at the ROOT level (no indentation)
2. Each field (name, description, content) MUST be indented with exactly 2 spaces under its language
3. Field values MUST use the literal block scalar (|) syntax
4. Text content MUST be indented with exactly 4 spaces (2 for field + 2 for content)
5. NEVER put fields at the root level - they MUST always be nested under a language code

# TRANSLATION RULES

1. **Translate, do not transliterate.** Convert meaning, not just letters.
2. Only include fields that were provided in the source.
3. Preserve all markdown and HTML formatting exactly.
4. Exception: Proper nouns, brand names, company names, and product names should be transliterated to Latin script.

# OUTPUT FORMAT

Respond ONLY with valid YAML. No markdown code blocks, no explanations, no comments - just raw YAML.`

const userPrompt = `Translate the following fields from Russian into: ${targetLangs.join(', ')}

## Source fields:

${fieldsYaml}

## Expected output structure:

${targetLangs
.map(
  (lang) =>
    `${lang}:\n${fieldNames.map((f) => `  ${f}: |\n    <translated ${f}>`).join('\n')}`,
)
.join('\n')}`

const chatResponse = await llmChatCompletionResolver(
  null,
  {
    input: {
      provider: LlmProvider.OpenRouter,
      messages: [
        {
          role: LLMChatMessageRole.system,
          content: systemPrompt,
        },
        {
          role: LLMChatMessageRole.user,
          content: userPrompt,
        },
      ],
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      model: LlmModel.GEMINI_3_5_FLASH_LITE as any,
    },
  },
  ctx,
)

const responseContent = chatResponse.choices?.[0]?.message?.content

Справедливости ради стоит отметить, что тут все равно в пользовательское сообщение примешены и технические инструкции, но все равно, работать стало значительно стабильней.