การกำหนดค่า
Champollion ทำงานได้โดยไม่ต้องกำหนดค่า — ระบบจะตรวจจับไฟล์ locale, รูปแบบ, และภาษาเป้าหมายจากโปรเจกต์ของคุณโดยอัตโนมัติ หากต้องการควบคุมเพิ่มเติม ให้สร้าง champollion.config.json ในไดเรกทอรีรากของโปรเจกต์ หรือรัน:
npx champollion init
เอกสารอ้างอิงการกำหนดค่าแบบเต็ม
{
"version": 3,
"inputLocale": "en",
"localesDir": "./locales",
"contentDir": null,
"translatableFields": null,
"format": "auto",
"model": "google/gemini-3.5-flash",
"temperature": 0.3,
"defaultMethod": "llm",
"batchSize": 80,
"coachingFile": null,
"promptContext": null,
"jsonConcurrency": 200,
"contentConcurrency": 48,
"fallbackPrefix": "[EN] ",
"apiKeyEnvVar": "OPENROUTER_API_KEY",
"baseUrl": "",
"pairs": {},
"languages": {},
"lint": {
"srcDir": null,
"ignore": ["node_modules", ".next", "dist"],
"minLength": 2
},
"seo": {
"urlPattern": "/:locale/:path",
"pages": null
},
"typegen": {
"output": null,
"autoGenerate": false
}
}
:::note typegen ยังไม่ได้รับการพัฒนา
บล็อกการกำหนดค่า typegen ได้รับการรับรองและเก็บรักษาโดย config loader แต่การสร้าง TypeScript type ยังไม่ได้รับการพัฒนา นี่คือ placeholder สำหรับฟีเจอร์ที่วางแผนไว้ การตั้งค่าเหล่านี้ไม่มีผลใดๆ
:::
ฟิลด์
| ฟิลด์ | ประเภท | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
version | number | 3 | เวอร์ชัน schema ของการกำหนดค่า ต้องเป็น 3 เสมอ |
inputLocale | string | "en" | รหัสภาษาต้นทาง (BCP 47) |
localesDir | string | "./locales" | พาธไปยังไฟล์ locale Champollion จะสแกนไดเรกทอรีนี้ |
contentDir | string | null | ไดเรกทอรีเนื้อหา Hugo เปิดใช้งานการแปล Markdown body |
translatableFields | string[] | null | แทนที่ฟิลด์ frontmatter ที่แปลได้ตามค่าเริ่มต้นสำหรับการแปลเนื้อหา null ใช้ค่าเริ่มต้นในตัว (title, description, summary) |
format | string | "auto" | รูปแบบไฟล์: json, toml, yaml, หรือ auto (ตรวจจับจากนามสกุลไฟล์) |
model | string | "google/gemini-3.5-flash" | โมเดลเริ่มต้นสำหรับ LLM method รองรับ OpenRouter slug แบบเต็ม (provider/model) หรือ alias แบบย่อจาก shared/model-aliases.json (เช่น gemini-flash) ผู้ให้บริการโดยตรงใช้ชื่อเปล่า (เช่น gpt-4o) |
temperature | number | 0.3 | อุณหภูมิ LLM (0.0–2.0) ค่าต่ำ = ผลลัพธ์แน่นอนกว่า |
defaultMethod | string | "llm" | วิธีการแปลเริ่มต้น: llm, llm-coached, google-translate, deepl, microsoft-translator, libretranslate, openai, anthropic, gemini, api สามารถแทนที่ได้ด้วย flag --method ของ CLI |
batchSize | number | 80 | จำนวน key ต่อ batch การแปล ค่าสูงกว่า = เรียก API น้อยลง แต่ prompt ใหญ่ขึ้น |
coachingFile | string | null | พาธไปยังไฟล์ coaching prompt แบบข้อความอิสระ (สัมพัทธ์กับรากโปรเจกต์) เนื้อหาจะถูกอ่านเมื่อเริ่มต้นและแทรกเข้าไปใน system prompt เป็นบล็อก Coaching guidance: |
promptContext | string | null | สตริงบริบทของแอปพลิเคชันที่แทรกเข้าไปใน system prompt (เช่น "E-commerce product descriptions") ช่วยให้โมเดลปรับการแปลให้เหมาะกับโดเมนของคุณ |
jsonConcurrency | number | 200 | จำนวนการแปล locale สูงสุดแบบขนานสำหรับการซิงค์ JSON key สามารถแทนที่ได้ด้วย flag --json-concurrency ของ CLI |
contentConcurrency | number | 48 | จำนวนการเรียก API สูงสุดแบบขนานสำหรับการแปลเนื้อหา (Markdown/MDX) สามารถแทนที่ได้ด้วย flag --content-concurrency ของ CLI |
fallbackPrefix | string | "[EN] " | คำนำหน้า marker ที่ใช้โดย audit และ verify เพื่อตรวจจับค่าที่ยังไม่ได้แปลแบบ legacy จากการรันก่อนหน้า Champollion ไม่เขียนคำนำหน้านี้ — อ่านเพื่อตรวจจับเท่านั้น |
apiKeyEnvVar | string | "OPENROUTER_API_KEY" | ชื่อตัวแปรสภาพแวดล้อมสำหรับ API key แทนที่สำหรับชื่อตัวแปรสภาพแวดล้อมที่กำหนดเอง |
baseUrl | string | "" | URL พื้นฐานสำหรับการสร้าง SEO artifact (hreflang, sitemaps, JSON-LD) |
pairs | object | {} | การแทนที่ method, model, และ quality แบบรายคู่ ดู การกำหนดค่าคู่ |
languages | object | {} | การแทนที่แบบรายภาษา ดู การกำหนดค่าภาษา |
lint.srcDir | string | null | ไดเรกทอรีต้นทางสำหรับการสแกน lint null = ตรวจจับอัตโนมัติจาก framework |
lint.ignore | string[] | ["node_modules", ...] | รูปแบบ glob เพื่อยกเว้นจาก lint |
lint.minLength | number | 2 | ความยาวสตริงขั้นต่ำที่จะตั้งค่าสถานะว่าเป็น hardcoded |
seo.urlPattern | string | "/:locale/:path" | เทมเพลต URL pattern สำหรับการสร้าง hreflang tag |
seo.pages | string[] | null | รายการหน้าที่ระบุอย่างชัดเจนสำหรับ SEO null = ตรวจจับอัตโนมัติจาก locale key |
typegen.output | string | null | พาธเอาต์พุตสำหรับ TypeScript type ที่สร้างขึ้น null = ปิดใช้งาน |
typegen.autoGenerate | boolean | false | สร้าง type ใหม่อัตโนมัติหลังจากการซิงค์แต่ละครั้ง |
การกำหนดค่าคู่
แต่ละคู่ต้นทาง→ปลายทางสามารถกำหนดค่าได้อย่างอิสระ:
{
"pairs": {
"en:fr": {
"method": "google-translate",
"qualityTier": "high"
},
"en:ja": {
"method": "llm",
"model": "google/gemini-2.5-pro"
},
"en:crk": {
"methodPlugin": "crk-coached-v1"
}
}
}
ฟิลด์คู่
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
method | string | วิธีการแปล: llm, llm-coached, google-translate, deepl, microsoft-translator, libretranslate, openai, anthropic, gemini, api |
methodPlugin | string | ชื่อของ plugin ที่ติดตั้งแล้ว (จาก .champollion/methods/) |
model | string | แทนที่โมเดลเริ่มต้นสำหรับคู่นี้ |
temperature | number | แทนที่อุณหภูมิเริ่มต้นสำหรับคู่นี้ |
batchSize | number | แทนที่ขนาด batch เริ่มต้นสำหรับคู่นี้ |
register | string | การแทนที่ register/tone (preset key หรือข้อความอิสระ) |
endpoint | string | URL endpoint ของ API ระยะไกล จำเป็นเมื่อ method คือ api |
coachingFile | string | พาธไปยังไฟล์ coaching prompt สำหรับคู่นี้ |
promptContext | string | บริบทของแอปพลิเคชันสำหรับคู่นี้ |
qualityTier | string | ระดับการแสดงผล: standard, high, research, verified |
การกำหนดค่าภาษา
ภาษารองรับสามรูปแบบ:
อาร์เรย์ของรหัส (ง่ายที่สุด)
{
"languages": ["fr", "de", "ja"]
}
แต่ละภาษาจะได้รับ register เริ่มต้นจากตาราง register ในตัว ภาษาที่ไม่มีค่าเริ่มต้นจะได้รับ "Professional register."
อ็อบเจกต์พร้อมสตริง register
ค่าสามารถเป็น preset key จาก language card หรือข้อความ register ที่กำหนดเอง:
{
"languages": {
"fr": "casual-tu",
"ko": "formal-hapsyo",
"ja": "Custom: Polite Japanese for a gaming app."
}
}
Champollion จะตรวจสอบว่าสตริงตรงกับ preset key ใน language card หรือไม่ หากตรงกัน จะใช้ register prompt แบบเต็มจาก card หากไม่ตรงกัน จะใช้สตริงนั้นตามที่เป็น ดู ภาษาที่รองรับ สำหรับ preset ที่มีอยู่
อ็อบเจกต์พร้อมการกำหนดค่าแบบเต็ม
{
"languages": {
"crk": {
"name": "Plains Cree",
"register": "SRO syllabics with grammatical precision.",
"model": "google/gemini-2.5-pro",
"batchSize": 5,
"maxRetries": 5,
"script": "cans"
}
}
}
คุณสามารถผสม shorthand และ full object ในบล็อกเดียวกันได้
ฟิลด์ภาษา
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
register | string | คำแนะนำสไตล์/โทน สามารถเป็น preset key (เช่น casual-tu, formal-hapsyo) หรือข้อความที่กำหนดเอง ดู Language Cards |
name | string | ชื่อภาษาที่มนุษย์อ่านได้ (สำหรับการแสดงสถานะ) |
model | string | แทนที่โมเดลเริ่มต้น |
temperature | number | แทนที่อุณหภูมิเริ่มต้น |
batchSize | number | แทนที่ขนาด batch เริ่มต้น |
coachingFile | string | พาธไปยังไฟล์ coaching prompt สำหรับภาษานี้ |
promptContext | string | บริบทของแอปพลิเคชันสำหรับภาษานี้ |
maxRetries | number | งบประมาณการลองใหม่สูงสุดสำหรับ batch ที่ล้มเหลว (ค่าเริ่มต้น: 3) |
script | string | รหัส script ISO 15924 เปิดใช้งานการตรวจสอบ script ใน quality gate |
:::info ลำดับการสืบทอด การตั้งค่าจะถูกแก้ไขตามลำดับนี้ (ค่าแรกที่พบจะชนะ):
ระดับคู่ → ระดับภาษา → การกำหนดค่าส่วนกลาง → ค่าเริ่มต้น
ตัวอย่างเช่น หาก pairs["en:fr"] ตั้งค่า model จะแทนที่ค่า model ทั้งในระดับภาษาและระดับส่วนกลาง
:::
ภาษาต้นทางที่ไม่ใช่ภาษาอังกฤษ
หากภาษาต้นทางของคุณไม่ใช่ภาษาอังกฤษ:
# CLI flag (one-time)
npx champollion sync --source fr
{
"inputLocale": "fr"
}
Lock File
Champollion สร้าง .champollion.lock เพื่อติดตาม SHA-256 hash ของค่าต้นทางที่แปลแล้ว Commit ไฟล์นี้ เพื่อให้นักพัฒนาทุกคนใช้ baseline การแปลเดียวกัน
เมื่อค่าต้นทางเปลี่ยนแปลง hash จะไม่ตรงกันอีกต่อไป และ Champollion จะแปลคีย์นั้นใหม่ในการซิงค์ครั้งถัดไป
.champollionignore
สร้าง .champollionignore ในไดเรกทอรีรากของโปรเจกต์เพื่อยกเว้นไฟล์จากการสแกน lint ใช้รูปแบบ glob เช่นเดียวกับ .gitignore:
src/components/legacy/**
src/utils/constants.js
**/*.test.js
ไดเรกทอรี .champollion/
Champollion สร้างไดเรกทอรี .champollion/ ในไดเรกทอรีรากของโปรเจกต์สำหรับสถานะภายใน โดยทั่วไปคุณควร เพิ่มไดเรกทอรีนี้ใน .gitignore — เป็นการปรับแต่งในเครื่อง ไม่ใช่ source ของโปรเจกต์:
.champollion/
| ไฟล์ | วัตถุประสงค์ | Commit? |
|---|---|---|
tm.json | แคช Translation Memory — เก็บการแปลก่อนหน้าโดยใช้ข้อความต้นทาง + locale + method เป็น key | ไม่ (แคชในเครื่อง) |
xliff/*.xliff | ไฟล์ XLIFF export สำหรับการตรวจสอบโดยนักแปลมืออาชีพ | ไม่ (ชั่วคราว) |
methods/ | Manifest ของ method plugin ที่ติดตั้งแล้ว | ใช่ (การกำหนดค่าร่วมกัน) |
backups/ | การสำรองข้อมูลก่อน wrap (สร้างโดย wrap --undo) | ไม่ (ตาข่ายนิรภัย) |
ดู Translation Memory สำหรับรายละเอียดเกี่ยวกับ tm.json และวิธีที่ช่วยประหยัดค่าใช้จ่าย API
Programmatic API
สำหรับ build script และการผสานรวมที่กำหนดเอง ให้ import โดยตรงจาก package:
import { GeminiMethod, runSync, resolveConfig } from 'champollion';
// Use a method class directly
const gemini = new GeminiMethod();
const result = await gemini.translate(
['greeting', 'farewell'],
{ greeting: 'Hello', farewell: 'Goodbye' },
{ target: 'fr', name: 'French', register: 'formal', model: 'gemini-2.5-flash' },
{ cwd: process.cwd() }
);
// result = { greeting: 'Bonjour', farewell: 'Au revoir' }
Export ที่มีให้ใช้งาน
| Export | สิ่งที่ทำ |
|---|---|
TranslationMethod | คลาสพื้นฐานสำหรับ method ทั้งหมด |
LLMMethod | คลาสพื้นฐานสำหรับ LLM method (OpenRouter) |
DirectLLMMethod | คลาสพื้นฐานสำหรับผู้ให้บริการ LLM โดยตรง (OpenAI, Anthropic, Gemini) |
OpenAIMethod, AnthropicMethod, GeminiMethod | คลาสผู้ให้บริการ LLM โดยตรง |
DeepLMethod, MicrosoftTranslatorMethod, LibreTranslateMethod | คลาส MT แบบดั้งเดิม |
GoogleTranslateMethod | Google Cloud Translation |
LLMCoachedMethod | Coached LLM (OpenRouter + ข้อมูล coaching) |
APIMethod | Remote API client |
runSync, runContentSync | pipeline การซิงค์แบบเต็ม |
resolveConfig, resolvePairs | การแก้ไขการกำหนดค่า |
validateTranslations | Quality gate |
loadCoachingData, findDictionaryMatches | Coaching utility |
การขยาย Custom Provider
ขยาย DirectLLMMethod เพื่อเพิ่มผู้ให้บริการ LLM ใหม่ใน ~40 บรรทัด:
import { DirectLLMMethod } from 'champollion';
class MistralMethod extends DirectLLMMethod {
constructor(options) {
super(options);
this.name = 'mistral';
}
_getApiKeyEnvVar() { return 'MISTRAL_API_KEY'; }
_getApiKeyOptionsKey() { return 'mistralApiKey'; }
_getDefaultModel() { return 'mistral-large-latest'; }
_getProviderLabel() { return 'Mistral'; }
_buildApiRequest({ prompt, systemMessage, apiKey, model, temperature }) {
return {
url: 'https://api.mistral.ai/v1/chat/completions',
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: {
model,
messages: [
...(systemMessage ? [{ role: 'system', content: systemMessage }] : []),
{ role: 'user', content: prompt },
],
temperature,
},
};
}
_extractResponseText(json) {
return json.choices?.[0]?.message?.content;
}
// Optional but recommended: provider-specific setup help when translation fails
getSetupHelp() {
if (!process.env.MISTRAL_API_KEY) {
return [
'',
' ┌─ Missing API Key ─────────────────────────────────────────────┐',
' │ Mistral requires an API key from https://console.mistral.ai │',
' │ Run: export MISTRAL_API_KEY=... │',
' └────────────────────────────────────────────────────────────────┘',
];
}
return [' API key is set but translation failed. Check your Mistral dashboard.'];
}
}
คุณจะได้รับ translate, coaching, retry loop, การตรวจสอบโมเดล, quality tier, และความช่วยเหลือในการตั้งค่าโดยไม่ต้องเขียนเพิ่ม มีเพียงรูปแบบ HTTP request เท่านั้นที่เฉพาะเจาะจงกับผู้ให้บริการ สำหรับ adapter ที่ไม่ใช่ LLM ที่ใช้ fetch() แบบดิบ ให้ใช้ helper fetchWithRetry() ที่ใช้ร่วมกันจาก lib/methods/fetch-with-retry.js แทนการเขียน retry loop ของตัวเอง
ดูเพิ่มเติม
- เอกสารอ้างอิง CLI — คำสั่งและ flag ทั้งหมด
- วิธีการแปล — การเลือกและผสมวิธีการ
- Translation Memory — การแคชและการประหยัดค่าใช้จ่าย
- การทำงานกับนักแปลมืออาชีพ — workflow ของ XLIFF
- ข้อกำหนด Plugin — รูปแบบ manifest ของ method plugin
- สถาปัตยกรรม — วิธีที่ส่วนต่างๆ เชื่อมต่อกัน
- ภาษาที่รองรับ — การรองรับภาษาในตัว
- วิธีการทำงานของ Sync — pipeline การแปล