Skip to content

Commit 37cd34b

Browse files
committed
fix(translator): add post-translation validation
1 parent f3be34a commit 37cd34b

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

tools/translator/agent.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ export async function createTranslationAgent(input: {
2626
const translator = new ChatGoogleGenerativeAI({
2727
apiKey: googleApiKey,
2828
model: translationModelName ?? defaultGeminiModel,
29-
temperature: 0.5, // 翻訳の一貫性を重視
29+
temperature: 0.2, // 翻訳の一貫性を重視
30+
cache: false,
3031
});
3132
const translatorPrompt = PromptTemplate.fromTemplate(
3233
translatorPromptTemplate
@@ -37,6 +38,7 @@ export async function createTranslationAgent(input: {
3738
apiKey: googleApiKey,
3839
model: proofreaderModelName ?? defaultGeminiModel,
3940
temperature: 0.8, // エラー修正への柔軟性を持たせる
41+
cache: false,
4042
});
4143
const proofreaderPrompt = PromptTemplate.fromTemplate(
4244
proofreaderPromptTemplate
@@ -90,6 +92,7 @@ const translatorPromptTemplate =
9092
9193
## 重要な注意事項
9294
95+
- **テキスト全体をコードブロックとしてラップしないでください。**
9396
- **マークダウンの構造を絶対に変更しないでください**
9497
- **行数を絶対に変更しないでください** - 入力と出力の行数は必ず同じにしてください
9598
- **コードブロック内の内容は翻訳しないでください**
@@ -112,13 +115,11 @@ const translatorPromptTemplate =
112115
- bad: "Angular の使い方"
113116
- good: "Angularの使い方"
114117
115-
翻訳されたテキストのみを返してください。他の説明や追加のテキストは含めないでください。テキスト全体をコードブロックとしてラップしないでください。
118+
翻訳されたテキストのみを返してください。他の説明や追加のテキストは含めないでください。
116119
117120
## 翻訳対象テキスト
118121
119-
===
120122
{text}
121-
===
122123
` as const;
123124

124125
const proofreaderPromptTemplate =
@@ -137,15 +138,13 @@ const proofreaderPromptTemplate =
137138
9. **インデントやスペースを保持してください**
138139
10. **指摘されたエラーのみを修正してください**
139140
140-
修正されたテキストのみを返してください。他の説明や追加のテキストは含めないでください。テキスト全体をコードブロックとしてラップしないでください。
141+
修正されたテキストのみを返してください。他の説明や追加のテキストは含めないでください。
141142
142143
## 校正エラー
143144
144145
{diagnostics}
145146
146147
## 修正対象テキスト (\`temp.md\`)
147148
148-
===
149149
{text}
150-
===
151150
` as const;

tools/translator/main.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import consola from 'consola';
22
import assert from 'node:assert';
33
import { readFile, writeFile } from 'node:fs/promises';
44
import { parseArgs } from 'node:util';
5+
import { cli } from 'textlint';
56
import {
67
cpRf,
78
exists,
@@ -139,17 +140,61 @@ async function saveTranslation(
139140
file: string,
140141
content: string,
141142
forceWrite: boolean
142-
): Promise<void> {
143+
): Promise<string | null> {
143144
const outputFile = getLocalizedFilePath(file);
144145
const shouldSave = forceWrite || (await promptForSave(outputFile));
145146

146147
if (!shouldSave) {
147-
return;
148+
consola.info('翻訳結果は保存されませんでした。');
149+
return null;
148150
}
149151

150152
await ensureEnglishFile(file);
151153
await writeFile(outputFile, content);
152-
consola.success(`保存しました`);
154+
consola.success(`翻訳結果を保存しました: ${outputFile}`);
155+
return outputFile;
156+
}
157+
158+
/**
159+
* 翻訳ファイルと原文ファイルの行数比較バリデーション
160+
*/
161+
async function validateLineCount(
162+
originalFile: string,
163+
translatedFile: string
164+
): Promise<void> {
165+
async function getLineCount(filePath: string) {
166+
const content = await readFile(filePath, 'utf-8');
167+
return content.split('\n').length;
168+
}
169+
170+
const [originalLines, translatedLines] = await Promise.all([
171+
getLineCount(originalFile),
172+
getLineCount(translatedFile),
173+
]);
174+
175+
const lineDiff = Math.abs(originalLines - translatedLines);
176+
177+
if (lineDiff === 0) {
178+
consola.success(`行数バリデーション: OK`);
179+
} else {
180+
consola.warn(
181+
`行数バリデーション: 注意 - 原文: ${originalLines}行, 翻訳: ${translatedLines}行 (差分: ${lineDiff}行`
182+
);
183+
}
184+
}
185+
186+
/**
187+
* textlintの実行
188+
*/
189+
async function runTextlint(file: string): Promise<void> {
190+
const ok = await cli.execute(`${file}`).then((code) => code === 0);
191+
if (ok) {
192+
consola.success(`textlint: OK`);
193+
} else {
194+
consola.warn(
195+
`textlint: エラーが検出されました。修正が完了してから提出してください。`
196+
);
197+
}
153198
}
154199

155200
/**
@@ -166,7 +211,17 @@ async function main() {
166211
const translated = await translateFile(file, googleApiKey, geminiModel);
167212

168213
console.log(translated);
169-
await saveTranslation(file, translated, !!write);
214+
const savedFile = await saveTranslation(file, translated, !!write);
215+
if (!savedFile) {
216+
return;
217+
}
218+
219+
// 翻訳結果の分析
220+
consola.start(`翻訳結果を分析...`);
221+
// 原文ファイルとの行数比較
222+
await validateLineCount(getEnFilePath(savedFile), savedFile);
223+
// textlintの実行
224+
await runTextlint(savedFile);
170225
}
171226

172227
main().catch((error) => {

0 commit comments

Comments
 (0)