没有不值得去解决的问题,也没有不值得去学习的技术!

A Tour of Go Multilingual Translation Project: Completing the First zh-CN Page Translation Cycle

A Tour of Go Multilingual Translation Project: Completing the First zh-CN Page Translation Cycle

作者:

,

On August 2, 2026, I officially began working on the Simplified Chinese translation for the go-tour-i18n project.

Today’s original goal was simply to translate the first page, but the actual process successively exposed multiple issues: page projection, conditional content, terminology consistency, validation rules, retry strategies, and the collaboration workflow between ChatGPT and Codex.

After a full day of development and calibration, the project ultimately completed the full translation loop for the first Simplified Chinese page, welcome/1, and pushed the verified code, translation, and project status to GitHub.

1. The upstream baseline currently used by the project

The project continues to use the Tour source code from the official Go website repository as its baseline:

  • Official repository: golang/website
  • Branch: master
  • Pinned commit: e11dacba76c5aae474746e9eedee19693f492803
  • Go environment: go1.26.0 linux/amd64

The project has currently confirmed:

  • There are 7 .article files;
  • There are 101 formal lesson pages in standalone mode;
  • 2 App Engine conditional pages are also retained;
  • There are 92 .play example references;
  • There is 1 .image reference.

The Go example code on the right remains exactly as the official version; at this stage, only the lesson text on the left and the subsequent common UI copy are translated.

2. First solving how to reliably save project state

After reopening the ChatGPT session today, I encountered a very practical issue.

Although a considerable amount of work had already been completed for this project previously, a new chat might not fully restore all the details from the previous session. If project progress relies primarily on:

  • ChatGPT memory;
  • Codex session history;
  • Published blog posts;
  • Manually copy-pasted execution reports;

Then as the project gradually grows longer, context omissions or judgment biases can easily occur.

Earlier today, precisely because the context was not fully restored, code generated earlier that day was referred to as an “old module,” and a separate set of CLI, page identities, and upstream reading logic was briefly generated.

A read-only audit confirmed that the interrupted task left behind two overlapping architectures:

  • The original cmd/tour-i18n, internal/i18n, internal/tour;
  • The newly generated cmd/go-tour-i18n, internal/translation, internal/projector, and internal/upstream.

These implementations were subsequently consolidated, ultimately re-establishing:

  • The sole CLI is cmd/tour-i18n;
  • The sole page identity uses a persistent page_id, such as welcome/1;
  • The page sources are the in-repository _content and data/tour-pages.tsv;
  • The external upstream checkout is used only for synchronization and verification, not as a translation runtime dependency;
  • internal/i18n.ValidateCandidate continues to serve as the sole candidate validation entry point.

To ensure project state no longer depends on chat history, the following was added to the repository:

Plaintext
docs/PROJECT_STATE.md

This document records the project state currently verified by code and tests, completed capabilities, current page status, and the single next step.

Code and tests remain the ultimate source of truth, while PROJECT_STATE.md organizes these facts into a state snapshot that is easier for ChatGPT, Codex, and myself to read.

3. Adding persistent, secure key configuration for GLM-5.2

When executing the first real translation, Codex found:

Plaintext
ZHIPU_API_KEY 未设置

Manually entering environment variables every time VS Code restarts would be cumbersome.

Therefore, the project added automatic loading of a local .env:

Plaintext
go-tour-i18n/
├── .env
└── .env.example

Where:

  • .env stores the actual local key;
  • .env.example stores only the variable names;
  • .env is explicitly added to .gitignore by /.env rules;
  • System environment variables take precedence over .env;
  • .env does not overwrite existing environment variables;
  • Keys are never written to requests, logs, or Git.

The local .env permissions are set to:

Plaintext
600 .env

Upon inspection, .env does not appear in the Git status or the final commit.

4. The first real translation exposed a standalone page source error

When GLM-5.2 was first called, the model output passed the structural validation at the time and entered ready.

However, the translation contained:

Plaintext
#appengine: 远程服务器上的
你电脑上的

Investigation revealed that the problem lay not with the model, but with the full English page itself that was fed to the model.

The request actually contained:

Plaintext
to compile and run the program on
#appengine: a remote server.
your computer.

In other words, the standalone welcome/1 erroneously retained the App Engine conditional branch.

The root cause was located in the page splitting logic:

  • The original implementation only recognized conditional page titles starting with #appengine: *;
  • #appengine: a remote server. within the body text was not excluded;
  • present treated lines starting with # as comments;
  • As a result, the erroneous candidate could still be successfully parsed and pass structural validation.

Ultimately, both issues were fixed simultaneously.

First, the standalone page source now excludes all #appengine: lines, while still retaining the two conditional pages separately.

Second, defensive rules were added to the validator:

  • #appengine: must not appear in the standalone source;
  • #appengine: must not appear in the standalone candidate.

After the fix, the source hash for welcome/1 was updated to:

Plaintext
3fbd64163f0301d60fcf1440c8aa65a79358e7028fec433aee49ae0c364d3034

The new page source:

  • Retains your computer.;
  • No longer contains #appengine:;
  • No longer contains a remote server..

The run records for the old source are retained by source hash; they will neither be overwritten nor take up translation records for the new source.

5. Structural correctness does not mean the translation is ready for publication

After fixing the page source, GLM-5.2 quickly generated a structurally correct translation.

However, the translation still had several terminology issues:

  • A Tour of Go was not translated;
  • previous and next remained in English;
  • Run and Format were not translated;
  • slides was translated as “幻灯片” (slideshow);
  • The meaning of tour was lost or translated mechanically.

This shows that a correct present structure, link targets, .play, and inline code do not guarantee that the Chinese terminology meets publication standards.

The project subsequently established a minimal Chinese glossary:

  • A Tour of GoGo 语言之旅
  • previous上一页
  • next下一页
  • Run运行
  • Format格式化
  • slides页面

“幻灯片” was also listed as a forbidden translation.

The validator also began checking terminology based on the structural relationship between link targets and labels, rather than simply performing a full-text string match.

6. Adding deterministic terminology locking for fixed UI labels

After enabling strict terminology validation, GLM-5.2 consecutively translated:

Plaintext
A Tour of Go

into:

Plaintext
Go 之旅

Whereas the project requires:

Plaintext
Go 语言之旅

Since the request had:

Plaintext
do_sample: false

set, the same input would very likely stably generate the same result. Simply retrying would only waste tokens.

At this point, instead of opting for post-translation string replacement, a few link labels that required strict consistency were incorporated into the protected token process.

For example:

Plaintext
[[javascript:highlight(".logo")][A Tour of Go]]

Before being submitted to the model, the link target and the display label are protected separately.

After the model completes the full-page translation, the label is deterministically restored to:

Plaintext
[[javascript:highlight(".logo")][Go 语言之旅]]

The currently locked fixed UI labels include:

  • A Tour of Go
  • previous
  • next
  • Run
  • Format

Quoted "previous" and "next" retain their original quotes when restored to Chinese.

Regular body text is not locked on a large scale; the body is still fully translated by GLM-5.2.

7. Distinguishing between proper names and “tour” in regular body text

After resolving the fixed labels, the next translation passed terminology validation, but multiple instances of the following appeared:

Plaintext
本之旅分为……
在本之旅中……
本之旅是交互式的……

The problem was that tour cannot be translated the same way in different contexts.

It was ultimately clarified that:

  • Proper name A Tour of GoGo 语言之旅
  • Regular body text tour教程
  • Regular body text the tour本教程

And the following expressions were added to the forbidden translations:

  • 本之旅
  • 欢迎使用 Go 编程语言之旅
  • 幻灯片

A Tour of Go in fixed links continues to be restored to “Go 语言之旅” via protected tokens, while tour in regular body text is still translated by the model based on the prompt.

8. Removing the three-retry limit during the development phase

The initial formal workflow stipulated:

Plaintext
完整页面翻译
→ 最多 3 次完整重试
→ 仍失败则 blocked
→ ChatGPT 完整页面兜底

This rule is suitable for formal batch translation once the process is stable, but today we are still in the development and calibration phase.

If, during development, every adjustment to the glossary, prompt, or validator were still subject to the three-retry limit, pages would quickly be sent to blocked, which is also not conducive to observing issues iteration by iteration.

Therefore, translate run added a development mode:

Bash
go run ./cmd/tour-i18n translate run \
  -id welcome/1 \
  -locale zh-CN \
  -dev

The formal mode still:

  • Executes at most 3 full-page translations;
  • Enters blocked after three failures;
  • blocked pages cannot continue with formal retries.

The development mode, however:

  • Can resume from pending or blocked;
  • Calls the model only once per command;
  • The attempt number continuously increments;
  • Does not overwrite old records;
  • Returns to pending upon failure;
  • Enters ready upon success.

This allows development and debugging to continue while preventing a single command from consecutively consuming multiple GLM tokens.

9. The sixth development attempt finally passed

After gradually calibrating the page source, validator, glossary, protected tokens, and prompt, attempt-006 finally passed all validations.

Call information for this run:

  • Request ID: 2026080221252064d5a523175a438a
  • finish_reason: stop
  • prompt tokens: 1052
  • completion tokens: 715
  • total tokens: 1767

The final candidate is:

Plaintext
* Hello, 世界

欢迎来到 [[/][Go 编程语言]]之旅。

本教程分为一系列模块,你可以点击页面左上方的
[[javascript:highlight(".logo")][Go 语言之旅]]来访问它们。

你还可以随时点击页面右上方的 [[javascript:highlightAndClick(".nav")][菜单]] 来查看目录。

在本教程中,你将看到一系列页面和练习供你完成。

你可以使用以下方式浏览它们:

- [[javascript:highlight(".prev-page")]["上一页"]] 或 `PageUp` 转到上一页,

- [[javascript:highlight(".next-page")]["下一页"]] 或 `PageDown` 转到下一页。

本教程是交互式的。现在点击
[[javascript:highlightAndClick("#run")][运行]] 按钮
(或按 `Shift` + `Enter`)来编译并运行你电脑上的程序。
结果会显示在代码下方。

这些示例程序展示了 Go 的不同方面。教程中的程序旨在作为你自己实验的起点。

编辑程序并再次运行。

当你点击 [[javascript:highlightAndClick("#format")][格式化]]
(快捷键:`Ctrl` + `Enter`)时,编辑器中的文本会使用
[[/cmd/gofmt/][gofmt]] 工具进行格式化。你可以通过点击
[[javascript:highlightAndClick(".syntax-checkbox")][语法]] 按钮来开启或关闭语法高亮。

当你准备好继续时,点击下方的 [[javascript:highlightAndClick(".next-page")][右箭头]] 或按 `PageDown` 键。

.play welcome/hello.go

The final inspection results:

  • Go 语言之旅 is correct;
  • 上一页, 下一页 are correct;
  • 运行, 格式化 are correct;
  • Regular body text uses “教程” and “本教程”;
  • Does not contain “本之旅”;
  • Does not contain “幻灯片”;
  • .play welcome/hello.go remains unchanged;
  • JavaScript targets, regular link targets, and inline code are all consistent;
  • Present parsing and page structure validation pass.

Although a few sentences may still have room for polishing in the future, there are no longer any structural or terminology errors that would necessitate sending it back for retranslation.

welcome/1 finally entered:

Plaintext
ready

10. Completing the translation loop for the first zh-CN page

The project ultimately completed the following loop:

Plaintext
仓库内完整 Section
→ standalone 页面投影
→ GLM-5.2 整页翻译
→ protected token 恢复
→ present 解析
→ 结构与引用比较
→ glossary 术语检查
→ candidate 落盘
→ ready 状态

The generated candidate is located at:

Plaintext
locales/zh-CN/candidates/welcome-1.article

All request, response, and validation records have been preserved as audit evidence for the development process.

The project passed full testing and completed the commit:

Plaintext
23b168beb29fbaa99a9b953a41d425558d8f91e6
feat: 完成首个 zh-CN 页面翻译闭环

It was subsequently pushed to GitHub:

Plaintext
d7f851d..23b168b  main -> main

The final workspace status is:

Plaintext
## main...origin/main

11. Today’s most important takeaway

The first page took six development attempts, which seems quite costly.

However, the earlier failures do not mean that GLM-5.2 will frequently fail in the future; rather, they helped the project discover and resolve infrastructure issues:

  • Incomplete standalone page projection;
  • The validator lacked defenses against conditional content;
  • Strict UI terminology should not be left entirely to the model;
  • Proper names and regular vocabulary need to be distinguished by context;
  • Different retry strategies are needed for the development phase versus formal runs;
  • Project state cannot rely solely on the session memory of ChatGPT or Codex.

Now that these issues have been resolved for the first page, the subsequent 100 pages will not need to bear the same development costs.

Today also further clarified the division of labor between ChatGPT, Codex, and myself:

  • ChatGPT is responsible for architecture analysis, task breakdown, and result review;
  • Codex is responsible for directly reading the repository, modifying code, and running tests;
  • I am responsible for supervision, cost control, decision-making, and final acceptance.

The code, tests, state files, and PROJECT_STATE.md in the repository will gradually become a more reliable shared source of truth among the three of us.

12. Next step: evaluate the new DeepSeek version before deciding on the translation model

Today, we will temporarily not continue translating the second page.

Currently, the GLM-5.2 resource pack has just over 3 million tokens remaining. According to the current purchasing rules, if we continue to supplement the resource pack, we would need to purchase 100 million tokens at once, and they must be used up within 3 months.

For the go-tour-i18n project, which is still in the development and model evaluation phase, purchasing a resource pack of this scale right now is not necessarily appropriate.

On the other hand, DeepSeek’s official update records show that DeepSeek-V4-Flash entered public testing on July 31, 2026; the official documentation also mentions that DeepSeek-V4-Pro plans to further open support in early August, but tomorrow we still need to confirm the specific model name and integration method based on actual API availability. (DeepSeek API Docs)

Therefore, tomorrow we will not directly start translating welcome/2, but will first evaluate the actual performance of the new DeepSeek version in this project.

The test should continue to use the same workflow established today:

Plaintext
完整 production 页面
→ protected token
→ 完整页面翻译
→ token 恢复
→ present 解析
→ 结构与引用比较
→ glossary 校验
→ candidate 验证

To make the comparison as fair as possible, we can first use the already familiar welcome/1 as the baseline page, but the test results should be saved to an independent model evaluation record and must not overwrite the currently verified GLM-5.2 candidate.

Key comparisons:

  • Whether protected tokens can be fully preserved;
  • Whether the present structure can pass on the first try;
  • Whether the fixed UI terminology is correct;
  • Whether the regular Chinese body text is natural;
  • Whether mechanical translations or unauthorized rewrites occur;
  • First-time pass rate;
  • Input and output tokens and actual costs;
  • Response speed and stability;
  • Whether the results are stable under identical inputs.

If the translation quality, structural stability, and cost of the new DeepSeek version are all acceptable, we can consider adopting DeepSeek as the primary translation model moving forward, keeping GLM-5.2 as a backup or control model.

If the test results are still clearly inferior to GLM-5.2, we will continue using the remaining GLM tokens to complete a more representative small-scale validation, and then decide whether to purchase a new resource pack based on the actual pass rate and estimated total cost.

Therefore, tomorrow’s focus is not on trying to translate a few more pages, but on first answering a question that has a major impact on the entire project’s cost:

Under the same conditions of full-page input, structural protection, glossary, and automatic validation, can the new DeepSeek version meet the quality standards required for the official Simplified Chinese translation of A Tour of Go?

Once the model route is determined, we will continue with the second page and subsequent small-scale page testing.

系列导航

需要长期技术维护或远程问题排查?

我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。

如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:

  • ✅ PHP / Laravel / Yii2 老项目无人维护
  • ✅ Go / Gin 后端接口需要排查或优化
  • ✅ WordPress 网站访问慢、报错或插件冲突
  • ✅ Nginx / MySQL / Redis / Linux 服务器异常
  • ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
  • ✅ 需要长期远程技术支持或兼职维护

更多介绍请查看:关于我 & 合作

微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理