系列基础内容已经覆盖了模型调用、消息组织、提示词、结构化输出、错误处理和结果评估。本篇做一个综合小项目:把英文技术说明翻译成中文,同时由程序检查术语表中的固定译法是否被保留。它不是“把文本交给模型就结束”,而是把模型生成、规则校验和人工确认拆成清晰的步骤。

先定义输入、输出和边界

输入包含原文和术语表。术语表把英文词组映射到项目约定的中文表达,例如 embedding 必须翻译为“嵌入”,context window 必须翻译为“上下文窗口”。输出包含译文以及模型认为实际使用到的术语列表。

程序只负责生成候选译文和发现明显违规,不自动覆盖原文,也不证明译文在专业语境中一定正确。术语匹配是确定性规则,语言是否自然仍需要人工阅读。这个边界很重要:模型适合处理语言转换,代码适合检查不能含糊的约束。

准备最小环境

在独立虚拟环境安装官方 Python SDK:

1
2
3
python -m venv .venv
source .venv/bin/activate
python -m pip install openai

密钥和模型名只能从环境变量读取:

1
2
export OPENAI_API_KEY="替换为你的真实密钥"
export MODEL_NAME="替换为你可用的模型名称"

新建 translation_case.json:

1
2
3
4
5
6
7
8
{
"source": "An embedding maps text to a vector. The context window limits the input.",
"glossary": {
"embedding": "嵌入",
"context window": "上下文窗口",
"vector": "向量"
}
}

编写翻译和校验程序

创建 translator.py。示例使用 Responses API,并要求模型只返回 JSON。即使接口请求成功,json.loads 和本地规则检查仍然不可省略,因为“请求成功”不等于“内容符合协议”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import json
import os
import sys
from pathlib import Path

from openai import OpenAI


def load_case(path: Path) -> tuple[str, dict[str, str]]:
data = json.loads(path.read_text(encoding="utf-8"))
source = data.get("source")
glossary = data.get("glossary")
if not isinstance(source, str) or not source.strip():
raise ValueError("source 必须是非空字符串")
if not isinstance(glossary, dict) or not glossary:
raise ValueError("glossary 必须是非空对象")
if not all(isinstance(k, str) and isinstance(v, str)
and k.strip() and v.strip() for k, v in glossary.items()):
raise ValueError("术语表的键和值都必须是非空字符串")
return source, glossary


def validate(result: object, glossary: dict[str, str]) -> dict[str, object]:
if not isinstance(result, dict):
raise ValueError("模型结果必须是对象")
translation = result.get("translation")
used_terms = result.get("used_terms")
if not isinstance(translation, str) or not translation.strip():
raise ValueError("translation 必须是非空字符串")
if not isinstance(used_terms, list) or not all(isinstance(x, str) for x in used_terms):
raise ValueError("used_terms 必须是字符串数组")
expected = set(glossary.values())
unknown = set(used_terms) - expected
if unknown:
raise ValueError(f"used_terms 含有术语表之外的词:{sorted(unknown)}")
missing = [zh for en, zh in glossary.items() if en.lower() in source_text.lower()
and zh not in translation]
if missing:
raise ValueError(f"译文缺少必须使用的术语:{missing}")
return {"translation": translation, "used_terms": used_terms}


source_text = ""


def main() -> int:
global source_text
if len(sys.argv) != 2:
print("用法:python translator.py translation_case.json", file=sys.stderr)
return 2
source_text, glossary = load_case(Path(sys.argv[1]))
glossary_text = json.dumps(glossary, ensure_ascii=False)
instructions = (
"你是技术文档翻译助手。将 SOURCE 翻译为中文,并严格使用 GLOSSARY 中的中文译法。"
"只返回 JSON 对象,字段必须是 translation 和 used_terms。"
"used_terms 只能列出实际使用的术语中文值,不要输出 Markdown。"
)
prompt = f"GLOSSARY:\n{glossary_text}\n\nSOURCE:\n{source_text}"
response = OpenAI().responses.create(
model=os.environ["MODEL_NAME"],
instructions=instructions,
input=prompt,
)
result = validate(json.loads(response.output_text), glossary)
print(json.dumps(result, ensure_ascii=False, indent=2))
return 0


if __name__ == "__main__":
raise SystemExit(main())

load_case 检查输入协议,避免把错误的 JSON 直接送给模型。validate 则检查三个层次:结果是不是对象,字段类型是否正确,译文是否包含原文中出现的术语对应译法。示例把 source_text 作为校验上下文传入,是为了让检查逻辑知道哪些术语确实出现在本次原文中;更大的程序可以把原文作为参数传给校验函数,避免全局变量。

运行:

1
python translator.py translation_case.json

本文不伪造运行结果。实际译文取决于密钥、模型和服务端返回;若返回内容缺少“上下文窗口”或“向量”,程序应直接报错,而不是打印一份看似正常的结果。

常见问题

为什么还要让模型返回 used_terms? 它可以作为可读的审查线索,但不是最终依据。真正的通过条件是程序根据原文、术语表和译文重新检查,不能只相信模型自报的列表。

术语表很长怎么办? 先按文档类型拆分术语表,只把本篇可能用到的部分放入上下文。术语过多会增加输入长度,也会让模型更难区分相近表达;分块翻译时要在每块使用同一版本的术语表。

规则检查通过就可以自动发布吗? 不可以。规则只能发现缺词、错词和格式问题,不能判断语气、歧义、数字含义或上下文是否准确。涉及 API 说明、命令和安全操作时,至少保留人工复核步骤。

模型返回了 Markdown 代码围栏怎么办? 可以在有限次数内请求修复,但不要无条件剥离任意文本。更稳妥的方式是记录原始响应,先解析并校验;多次失败就停止,让调用方处理,而不是默默猜测 JSON 内容。

小结

这个项目把一次翻译调用变成了可验证流水线:输入校验保证边界,提示词传递任务和术语约束,模型生成候选译文,Python 再检查结构与固定词汇,最后由人确认语言质量。综合项目的重点不是增加代码量,而是明确哪些判断交给模型、哪些判断必须由程序完成。只要把模型输出当作不可信输入,AI 功能就更容易测试、审计和维护。