做多语言站点,常见的两条路:一是给每种语言复制一套文章,二是在前端挂个机器翻译脚本。前者内容一多就失控,后者译文不入库、搜索引擎也读不到。AI 上下文翻译走的是第三条:原文一个字不动,翻译发生在页面渲染完成之后,译文单独存表,前台按语言目录输出。
一次翻译经过哪些步骤
不论是后台点按钮、后台自动任务还是访客触发,走的都是同一条链路:
- 抓取原文页:插件用站内请求把目标页面完整取回来,带上标记参数,让前台知道这次要输出原文、不要参与替换。
- 解析 DOM 提取文本:整页 HTML 解析成 DOM 后逐节点提取,只取可见文字、
<title>、部分meta、placeholder、图片的alt/title、Microdata 字段,以及(开关打开时)站内链接的路径。脚本、样式、类名、data-*一律不碰。 - 分批送给 AI:以页面为单位组织请求,页内文本按字符数拆成多批,每批带上源语言、目标语言和一段 JSON。
- 入库:译文按「原文 md5 + 语言对」写进独立数据表,同一段文字在多个页面出现只存一份。
- 前台输出:访客打开
/ja/这样的语言目录时,插件在页面渲染完成后接管输出,把每个文本节点换成对应译文,站内链接挂到语言目录下。
为什么按页面组织请求
逐条翻译准确度会明显下降——「关于」在导航里和在正文里可以是两个词,脱离上下文的短句最容易翻错。插件把同一页的文本凑成一批交给 AI,模型能看到这些文字彼此的关系,译文的用词和语气才统一。
批次不是越大越好。单批总长度控制在 6000 字符、最多 50 条,因为译文长度与原文相当,这个值实际上是在约束模型的输出长度。万一还是撞上模型的输出上限被截断,插件会把切断点之前完整的译文抢救出来,剩下的缩小规模重发,最多再拆四层。
译文存在哪里
独立的数据表,与文章内容无关。每条记录包含原文、译文、语言对、来源页面、类型(普通文本还是 URL 路径)和来源标记(AI 翻译还是人工修改过)。这样带来几个直接好处:
- 全站去重。导航、页脚、按钮文字这些每页都出现的内容,只翻一次。
- 停用插件不会动原文,站点立刻回到单语状态,数据还在。
- 译文可以逐条人工校对,改过的会被标成人工来源,后续 AI 翻译不会把它覆盖掉。
接哪些 AI 服务
插件通过 php-ai 库对接模型,内置 OpenAI、Claude、Gemini、DeepSeek 四套协议。模型名可以直接填库里内置的(如 deepseek-chat、gpt-4o),平台由模型名自动识别;也可以填中转站自定的模型名,再手选协议格式、填上对方给的接口地址。自建网关、第三方中转都能接。
下一篇讲具体怎么配:从零配置到第一篇译文。