사용자 정의 메서드를 API로 제공하기
champollion의 api 메서드를 사용하면 모든 번역 쌍을 외부 HTTP 엔드포인트로 연결할 수 있어요. 이를 통해 단일 LLM 프롬프트로는 처리하기에 너무 복잡한 파이프라인 — 형태소 분석기, 유한 상태 변환기(FST), 다단계 LLM 체인, 또는 직접 구축한 사용자 정의 연구 방법 — 을 통합할 수 있어요.
왜 API 서비스인가요?
일부 번역 파이프라인은 단순한 요청-응답 주기 안에서 실행할 수 없어요:
| 파이프라인 단계 | 예시 |
|---|---|
| 형태소 분해 | 번역 전에 다종합어를 형태소로 분리 |
| FST 검증 | 음운론적 또는 형태론적 규칙을 위반하는 출력을 거부 |
| 다단계 LLM 체인 | 서로 다른 모델로 생성 → 검증 → 수정 주기 |
| 사전 조회 | 파이프라인 중간에 선별된 이중 언어 사전을 교차 참조 |
| 휴먼 인 더 루프 | 불확실한 번역을 전문가 검토를 위해 대기열에 추가 |
api 메서드는 파이프라인을 블랙박스로 취급해요 — champollion이 원본 문자열을 보내면 서비스가 번역을 반환하는 방식이에요. 내부에서 일어나는 일은 전적으로 사용자에게 달려 있어요.
아키텍처
서비스 설정하기
API 서비스는 JSON을 받고 반환하는 단일 엔드포인트를 구현해야 해요:
요청 형식
champollion은 정확히 이 JSON 본문을 보내요(자세한 내용은 api.js 참고):
POST /translate
Content-Type: application/json
Authorization: Bearer <CHAMPOLLION_API_KEY>
{
"source_locale": "en",
"target_locale": "crk",
"method": "crk-coached-v1",
"keys": {
"greeting": "Hello, welcome to our app",
"farewell": "Goodbye and thanks"
}
}
| 필드 | 타입 | 설명 |
|---|---|---|
source_locale | string | BCP 47 원본 언어 코드 |
target_locale | string | BCP 47 대상 언어 코드 |
method | string | 플러그인 이름 또는 "default" |
keys | object | 키 → 번역할 원본 문자열의 맵 |
### Response Format
Your service must return a `translations` object. An optional `meta` object can include cost and diagnostic info:
```json
{
"translations": {
"greeting": "tânisi, pê-kîwêw ôta",
"farewell": "ekosi mâka, kinanâskomitin"
},
"meta": {
"model": "my-custom-pipeline/v1",
"cost_usd": 0.0042,
"method": "decompose-translate-validate"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
translations | object | ✅ | Map of key → translated string |
meta | object | — | Optional metadata |
meta.cost_usd | number | — | If present, displayed in champollion's output |
errors | object | — | For partial success (HTTP 207): map of key → { message } |
Minimal Express Server
import express from 'express';
const app = express();
app.use(express.json());
/**
* champollion API contract:
*
* Request: { source_locale, target_locale, method, keys: { "key": "source" } }
* Response: { translations: { "key": "translated" }, meta: { ... } }
*/
app.post('/translate', async (req, res) => {
const { source_locale, target_locale, method, keys } = req.body;
const translations = {};
for (const [key, source] of Object.entries(keys)) {
// --- Your pipeline goes here ---
// Step 1: Morphological decomposition
const morphemes = await decompose(source, source_locale);
// Step 2: LLM translation with context
const draft = await llmTranslate(morphemes, target_locale);
// Step 3: FST validation
const validated = await fstValidate(draft, target_locale);
// Step 4: Post-processing (orthography normalization, etc.)
translations[key] = await postProcess(validated);
}
res.json({
translations,
meta: {
model: 'my-custom-pipeline/v1',
method: 'decompose-translate-validate',
},
});
});
app.listen(3001, () => {
console.log('Translation API running on http://localhost:3001');
});
Configuring champollion
Point a translation pair at your running service in champollion.config.json:
{
"inputLocale": "en",
"pairs": {
"en:crk": {
"method": "api",
"endpoint": "http://localhost:3001/translate",
"register": "Formal Plains Cree. Use SRO orthography."
}
}
}
Then run sync as usual:
npx champollion sync
champollion will POST your source strings to the endpoint and write the returned translations to crk.json.
Case Study: Plains Cree Pipeline
:::info Under Development The Plains Cree pipeline described below is under active development and is not yet running in production. Details here reflect the current design direction and may change as the project evolves. :::
The arena project demonstrates this pattern. Its Plains Cree pipeline uses:
- Morphological decomposition — Break polysynthetic Cree words into translatable morpheme chains
- LLM translation — Context-enriched GPT-4o translation with coaching data (SRO orthography rules, register instructions)
- FST validation — Finite-state transducer checks that outputs conform to Cree phonological rules
- Confidence scoring — Each translation gets a confidence score based on FST pass rate and dictionary coverage
The entire pipeline runs as a single HTTP endpoint that champollion calls via the api method.
Running Evaluations
After translating, you can evaluate output quality using the harness directly:
# Clone the harness
git clone https://github.com/gamedaysuits/arena.git
cd arena
pip install -e .
# Run the evaluation against your method's output
mt-eval run --corpus data/edtekla-dev-v1.json --submit
This produces structured evaluation records with chrF++, BLEU, and exact match scores that can be used as regression baselines.
Authentication
If your API requires authentication, set the apiKey field or use an environment variable:
{
"pairs": {
"en:crk": {
"method": "api",
"endpoint": "https://my-mt-service.example.com/translate",
"apiKey": "${CRK_API_KEY}"
}
}
}
Data Sovereignty & OCAP Principles
The api method is particularly important for Indigenous language communities. By self-hosting the translation pipeline, a community keeps full control over:
- Proprietary coaching data — register instructions, orthography rules, and domain glossaries never leave community infrastructure.
- Linguistic resources — curated dictionaries, FST grammars, and elder-verified translations remain under community ownership.
- Access policies — the community decides who can call the endpoint and under what terms.
This aligns with OCAP® principles (Ownership, Control, Access, Possession), ensuring that sensitive language data is governed by the community rather than a third-party platform.
Combine the api method with a private deployment (e.g., a community-hosted VM or on-prem server) for the strongest data-sovereignty posture. See Support a Low-Resource Language for a full walkthrough.
Cost Estimation
The api method returns null for cost estimation by default — your service controls pricing. If you want to provide cost transparency, have your API return a cost field in the metadata:
{
"translations": { "...": "..." },
"metadata": {
"cost": {
"estimatedCost": 0.0042,
"currency": "USD",
"source": "my-service-pricing"
}
}
}
모범 사례
- 실패 시 빈 문자열을 반환하세요 — 원본 문자열을 "번역"으로 반환하지 마세요.
""을 반환하면 champollion의 품질 게이트가 이를 포착해요. 해당 키는 건너뛰어지고 다음 sync에서 재시도돼요. - 신뢰도 점수를 포함하세요 — 파이프라인이 품질을 추정할 수 있다면 메타데이터에 반환하세요. 이는 품질 감사에 도움이 돼요.
- 상태 확인을 구현하세요 —
GET /health엔드포인트를 추가하면 champollion이 대규모 sync를 시작하기 전에 연결 상태를 확인할 수 있어요. - 속도 제한을 우아하게 처리하세요 — 파이프라인에 처리량 제한이 있다면
429상태 코드를 반환하세요. champollion의 배치 시스템이 자동으로 물러나요. - 모든 것을 로깅하세요 — 다단계 파이프라인은 조용히 실패할 수 있어요. 디버깅을 위해 각 단계의 입력/출력을 로깅하세요.
라이선스
api 메서드 패턴은 완전히 개방되어 있어요 — 자체 번역 파이프라인을 HTTP 서비스로 래핑하는 데 라이선스 제한이 없어요. arena은 참조 구현을 위해 MIT 라이선스로 제공돼요.