修复翻译可能会有英文的问题

This commit is contained in:
yhy
2026-09-01 20:36:07 +08:00
parent 3b07e2a3c1
commit 0fea95f373
5 changed files with 29 additions and 4 deletions
@@ -1,6 +1,7 @@
import { LlmError } from "../../../llm/types"; import { LlmError } from "../../../llm/types";
import type { BeatType, SummaryJson } from "../../domain/types"; import type { BeatType, SummaryJson } from "../../domain/types";
import type { StoredBeat } from "../storage/lectureStore"; import type { StoredBeat } from "../storage/lectureStore";
import { FORCE_ZH_EXPLANATION } from "./promptRules";
import { parseJsonLoose, requestStructuredOutput } from "./structuredOutput"; import { parseJsonLoose, requestStructuredOutput } from "./structuredOutput";
const VALID_TYPES = new Set<BeatType>([ const VALID_TYPES = new Set<BeatType>([
@@ -17,7 +18,9 @@ const BEATS_SYSTEM = `你是 ChatPapers 语音伴读的备课助手。根据论
要求: 要求:
- beats 数组含 6–10 项,按教学逻辑:问题引入 → 核心方法 → 关键实验/证据 → 结论与局限 - beats 数组含 6–10 项,按教学逻辑:问题引入 → 核心方法 → 关键实验/证据 → 结论与局限
- script 为中文口语,每段 80–180 字,适合朗读;不要念公式符号,用白话解释 - script 为中文口语,每段 80–180 字,适合朗读;不要念公式符号,用白话解释
- type 只能是 intro / method / experiment / conclusion / extension`; - type 只能是 intro / method / experiment / conclusion / extension
${FORCE_ZH_EXPLANATION}`;
interface BeatJson { interface BeatJson {
title?: string; title?: string;
@@ -2,12 +2,15 @@ import { getRuntimeConfig } from "../../../llm/client";
import { parseJsonLoose, parseLabeledFields } from "../../../llm/jsonParse"; import { parseJsonLoose, parseLabeledFields } from "../../../llm/jsonParse";
import { LlmError } from "../../../llm/types"; import { LlmError } from "../../../llm/types";
import type { SummaryJson } from "../../domain/types"; import type { SummaryJson } from "../../domain/types";
import { FORCE_ZH_EXPLANATION } from "./promptRules";
import { requestStructuredOutput } from "./structuredOutput"; import { requestStructuredOutput } from "./structuredOutput";
const SUMMARY_SYSTEM = `你是 ChatPapers 语音伴读的备课助手。根据论文正文生成结构化摘要。 const SUMMARY_SYSTEM = `你是 ChatPapers 语音伴读的备课助手。根据论文正文生成结构化摘要。
必须只输出一个 JSON 对象,不要 markdown 代码块,不要其他说明。 必须只输出一个 JSON 对象,不要 markdown 代码块,不要其他说明。
格式:{"problem":"...","method":"...","result":"...","limitation":"..."} 格式:{"problem":"...","method":"...","result":"...","limitation":"..."}
每项 1-3 句中文,准确、简洁,基于正文,不要编造。`; 每项 1-3 句中文,准确、简洁,基于正文,不要编造。
${FORCE_ZH_EXPLANATION}`;
const SUMMARY_LABELS = [ const SUMMARY_LABELS = [
{ field: "problem", labels: ["问题", "研究问题", "problem"] }, { field: "problem", labels: ["问题", "研究问题", "problem"] },
@@ -4,6 +4,7 @@ import type { SummaryJson } from "../../domain/types";
import type { TextChunk } from "../pdf/chunker"; import type { TextChunk } from "../pdf/chunker";
import { splitSentences } from "../pdf/sentenceSplit"; import { splitSentences } from "../pdf/sentenceSplit";
import type { StoredParagraph, StoredSentence } from "../storage/lectureStore"; import type { StoredParagraph, StoredSentence } from "../storage/lectureStore";
import { FORCE_ZH_EXPLANATION, FORCE_ZH_USER_REMINDER } from "./promptRules";
import { requestStructuredOutput } from "./structuredOutput"; import { requestStructuredOutput } from "./structuredOutput";
const PARA_SYSTEM = `你是 ChatPapers 论文伴读助手。用户会按论文物理顺序逐段听课。 const PARA_SYSTEM = `你是 ChatPapers 论文伴读助手。用户会按论文物理顺序逐段听课。
@@ -15,7 +16,9 @@ const PARA_SYSTEM = `你是 ChatPapers 论文伴读助手。用户会按论文
- contextLink:1–2 句,说明本段与上一段及全文摘要的衔接(代词指代、逻辑转折等)。 - contextLink:1–2 句,说明本段与上一段及全文摘要的衔接(代词指代、逻辑转折等)。
- roleInPaper:本段在论文结构中的作用(如「方法开篇」「实验设置」)。 - roleInPaper:本段在论文结构中的作用(如「方法开篇」「实验设置」)。
- sentences:将本段拆成 2–8 个朗读单元(按句号/问号/叹号分句),每项含 original(原文句)与 translation(该句的中文讲解,3080 字)。 - sentences:将本段拆成 2–8 个朗读单元(按句号/问号/叹号分句),每项含 original(原文句)与 translation(该句的中文讲解,3080 字)。
- 术语与专有名词翻译前后一致;指代前文概念时用相同译法。`; - 术语与专有名词翻译前后一致;指代前文概念时用相同译法。
${FORCE_ZH_EXPLANATION}`;
export interface ParagraphLlmResult { export interface ParagraphLlmResult {
translation: string; translation: string;
@@ -100,6 +103,8 @@ ${options.priorContext || "(这是论文开头第一段)"}
【当前段落 ${options.chunk.id} 【当前段落 ${options.chunk.id}
${options.chunk.text} ${options.chunk.text}
${FORCE_ZH_USER_REMINDER}
请输出 JSON。`; 请输出 JSON。`;
return requestStructuredOutput({ return requestStructuredOutput({
@@ -0,0 +1,9 @@
/** 伴读/讲解 LLM 输出须为中文,即使原文是英文论文。 */
export const FORCE_ZH_EXPLANATION = `语言(强制):
- 无论原文是英文、中文或中英混合,JSON 内所有讲解/摘要类字段必须全部使用简体中文,严禁输出整句英文。
- 原文为英文时:translation、script 等须先准确译成中文再口语讲解,不得直接复述、改写或总结英文原文。
- 专有名词、缩写、符号名可保留英文,但其余讲解正文必须是中文。`;
/** 用户消息末尾的语言提醒(原文可能是英文段落/句子)。 */
export const FORCE_ZH_USER_REMINDER =
"【语言】无论上文原文是否为英文,JSON 中所有讲解字段必须全部使用简体中文。";
@@ -1,6 +1,7 @@
import { parseJsonLoose } from "../../../llm/jsonParse"; import { parseJsonLoose } from "../../../llm/jsonParse";
import { LlmError } from "../../../llm/types"; import { LlmError } from "../../../llm/types";
import type { SummaryJson } from "../../domain/types"; import type { SummaryJson } from "../../domain/types";
import { FORCE_ZH_EXPLANATION, FORCE_ZH_USER_REMINDER } from "./promptRules";
import { requestStructuredOutput } from "./structuredOutput"; import { requestStructuredOutput } from "./structuredOutput";
const SENTENCE_SYSTEM = `你是 ChatPapers 论文伴读助手。用户选中论文中的一句原文,需要你解释并用于语音朗读。 const SENTENCE_SYSTEM = `你是 ChatPapers 论文伴读助手。用户选中论文中的一句原文,需要你解释并用于语音朗读。
@@ -11,7 +12,9 @@ const SENTENCE_SYSTEM = `你是 ChatPapers 论文伴读助手。用户选中论
- translation:准确中文翻译,并用 30–80 字口语解释该句含义(不要念 LaTeX,公式转述为口语)。 - translation:准确中文翻译,并用 30–80 字口语解释该句含义(不要念 LaTeX,公式转述为口语)。
- syntaxNote:1–2 句,拆解句法结构或关键术语(英文句为主;中文句可简述逻辑)。 - syntaxNote:1–2 句,拆解句法结构或关键术语(英文句为主;中文句可简述逻辑)。
- contextRole:1 句,说明该句在段落或全文论证中的作用。 - contextRole:1 句,说明该句在段落或全文论证中的作用。
- 术语翻译与全文保持一致。`; - 术语翻译与全文保持一致。
${FORCE_ZH_EXPLANATION}`;
export interface SentenceLlmResult { export interface SentenceLlmResult {
translation: string; translation: string;
@@ -67,6 +70,8 @@ ${options.surroundingContext?.trim() || "(无)"}
【用户选中的句子】 【用户选中的句子】
${options.selectedText.trim()} ${options.selectedText.trim()}
${FORCE_ZH_USER_REMINDER}
请输出 JSON。`; 请输出 JSON。`;
return requestStructuredOutput({ return requestStructuredOutput({