专业翻译工具。核心能力:翻译。使用术语词典,AC 机,OCR、LLM等组件来完成文本翻译和PDF翻译。
> 触发条件:config.json 中 configured 为 false。
> 适用范围:所有路由(text、PDF、及未来新增)。进入任何路由前先执行本检查。
当检测到 configured 为 false 时,必须以对话形式依次询问用户以下 4 项配置,不得跳过,每项提供默认值和示例:
> 交互约定:所有带默认值的项,用户回复 Y / y / 默认 即采用默认值。领域(第 3 项)无默认值,必须用户显式填写。
询问:"请输入翻译输出目录,回复 Y 使用默认值 [默认: ./translation-output]"
Y / y / 默认 或未提供路径 → 采用默认值询问:"请选择术语词典 CSV 文件,回复 Y 使用内置术语库 [默认: Gxpcode-dict.csv]"
Gxpcode-dict.csv(内置制药) / /path/to/my-dict.csv(自定义)Y / y / 默认 → 使用内置 Gxpcode-dict.csv> ⚠️ 领域配置对翻译结果有重大影响。必须认真填写,不可跳过。
询问:"翻译所属专业领域是什么?(必填,对翻译质量影响重大)"
制药 / 半导体 / 医疗器械 / 化工 / 生物技术 / 法律 / 金融Y 则重新提示,直到用户显式填写询问:"领域内的细分方向是什么?可填写多个,回复 Y 跳过 [可空](不建议跳过)"
GMP / 药品研发 / 药品注册 / 工艺验证 / 临床前研究Y / y / 默认 / 无 → 跳过(不推荐)、 或 , 分隔,如 药品研发、药品注册全部完成后,写入 config.json 并将 configured 设为 true,输出配置摘要供用户确认。
$configPath = "$env:USERPROFILE\.workbuddy\skills\gxpcode-translator\config.json"
$config = Get-Content $configPath | ConvertFrom-Json
# ... 对话收集上述 4 项后 ...
$config.output_dir = $outDir
$config.dict_path = $dictPath
$config.domain = $domain
$config.subdomain = $subdomain
$config.configured = $true
$config | ConvertTo-Json | Set-Content $configPath -Encoding UTF8
> skill_dir 和 python_exe 自动检测写入。配置仅执行一次,后续可通过编辑 config.json 修改。
对话框中仅允许输出纯译文。禁止输出术语表、匹配统计、自检表格、翻译说明、日志路径等任何其他内容。
唯一例外:术语库中找不到对应译法、需要向用户确认时,可输出询问信息。
任何译文内容不得出现在对话中。
| 允许在对话框中输出 | 禁止在对话框中输出 |
|---|---|
| --- | --- |
进度行(🌐 翻译中... 3/10) | 任何翻译文本 |
状态行(✅ 翻译完成: 10/10) | HTML/MD/表格内容 |
校验结果(P5: 4/4 ✅) | 术语表 |
| 文件路径 | 单个术语译文 |
> 自检:每次回复前,扫描回复内容是否包含译文字符。如有 → 删除,替换为文件路径引用。
Write-Output 打印验证一律跳过*_trans.md 文件,对话框仅显示进度(每页一行)用户通过 /trans 指令或自然语言("翻译这段话"、"translate this")触发。
config.json 读取 dict_path,默认 Gxpcode-dict.csv(skill 安装目录下)en,cn,explain> 本文档中所有 PowerShell 示例使用以下变量,实际运行前由主流程赋值:
| 变量 | 含义 | 示例 |
|---|---|---|
| --- | --- | --- |
$SkillDir | gxpcode-translator 安装目录 | ~/.workbuddy/skills/gxpcode-translator |
$PythonExe | Python 可执行文件 | ~/.workbuddy/binaries/python/envs/default/Scripts/python.exe |
> 跨平台时只需修改这两个变量,其余路径自动跟随。
读取方式(每次使用 Skill 时):
$config = Get-Content "$env:USERPROFILE\.workbuddy\skills\gxpcode-translator\config.json" | ConvertFrom-Json
$SkillDir = $config.skill_dir
$PythonExe = $config.python_exe
$DictPath = $config.dict_path
if (-not [System.IO.Path]::IsPathRooted($DictPath)) { $DictPath = "$SkillDir\$DictPath" }
$Domain = $config.domain
$Subdomain = $config.subdomain
> skill_dir 和 python_exe 由首次配置自动检测写入。dict_path、domain、subdomain 在首次对话中由用户指定。换平台时编辑 config.json 即可。
每次加载 Prompt 模板前,从 config.json 读取 domain 和 subdomain,将模板中的 {domain} 和 {subdomain} 替换为实际值。
| 配置项 | config.json 字段 | 默认值 | 说明 |
|---|---|---|---|
| --- | --- | --- | --- |
| 领域 | domain | ""(空,强制必填) | 翻译所属专业领域,对译文质量有重大影响 |
| 子模块 | subdomain | "" | 领域内的细分方向,如 药品研发、GMP、药品注册 等 |
替换规则:
| 条件 | 模板替换结果 |
|---|---|
| --- | --- |
subdomain 非空 | 你是{domain}领域({subdomain})专业翻译 → 你是制药领域(GMP)专业翻译 |
subdomain 为空 | 你是{domain}领域专业翻译 → 你是制药领域专业翻译(去掉空括号) |
> 受影响的 Prompt 模板位于 modules/translate-core.md:模式一 Agent Prompt、模式二文本翻译 Prompt、表格拆行翻译 Prompt。
当用户反馈译文不准确、术语错误、"翻译得不对"时,主动询问:
> "当前领域配置为「{domain}」子模块「{subdomain}」,是否准确?如需修改,我可以更新 config.json 中的 domain 和 subdomain。"
config.json 并重新翻译> 首次使用 PDF 路由时,自动触发配置采集(见 modules/Gxpcode-pdf-input.md 步骤 0.6)。
> PaddleOCR API Token 仅在 PDF 路由首次使用时询问,不属于 SKILL 通用首次配置。
> 所有路径从 config.json 读取,不硬编码。
| 配置项 | config.json 字段 | 默认值 | 说明 |
|---|---|---|---|
| --- | --- | --- | --- |
| PaddleOCR Token | paddleocr_token | (必填) | PDF 解析 API 令牌 |
| 输出根目录 | output_dir | ./translation-output/ | 双语 HTML/MD + 日志 + 中间产物,全部在此目录下 |
| HTML 文件 | {output_dir}/{ts}-{slug}/Gxpcode-{title}.html | — | 双语对照 HTML |
| MD 文件 | {output_dir}/{ts}-{slug}/Gxpcode-{title}.md | — | 双语对照 Markdown |
| 日志 | {output_dir}/logs/{ts}_trans.md | — | 翻译日志 |
| 中间产物 | {output_dir}/{ts}-{slug}/ | — | paddleocr/、pages/、translated.json |
本 Skill 采用渐进式加载——SKILL.md 只做路由,实现细节在子模块中按需加载。
从用户消息中提取:
输入类型检测:用户上传 .pdf 文件?→ PDF 路径;否则 → 文本路径。
> 加载铁律:以下 MANDATORY 标记的文件必须在对应阶段读取后才能继续。不读 = 走的是空壳分支。
| 场景 | 加载模块 | 说明 |
|---|---|---|
| --- | --- | --- |
| PDF 输入 | MANDATORY: modules/Gxpcode-pdf-input.md 步骤 0 | 文件存在性检查 |
| PDF → 加密检测 | MANDATORY(不可跳过): modules/Gxpcode-pdf-input.md 步骤 0.5 | pdfplumber 检测加密,加密则立即终止 |
| PDF → 解析 | MANDATORY: modules/Gxpcode-pdf-input.md 步骤 1 | paddleocr-parser 解析 |
| PDF → 截断修复 | MANDATORY(不可跳过): 运行 scripts/fix_truncations.py | 修复所有截断页的 md 文件 |
| PDF → Agent 自扫自译 | → MANDATORY: modules/translate-core.md 步骤 3 模式一 | 5页/组,Agent自扫术语+翻译(并发 ≤8) |
| PDF → merge + 校验 | → MANDATORY(merge_translations.py 强制内置): ① 完整性 → ② 合并 → ③ 类型分布 → ④ 表格行数 | 出口有 3 种可能(见下方 merge 出口表) |
| PDF → 导出 | → MANDATORY: modules/Gxpcode-export.md 步骤 B/C | 生成 Gxpcode.html + Gxpcode.md |
| 文本输入 | MANDATORY: modules/translate-core.md | 术语扫描 → AI 翻译 → 自检 → 输出 |
| 文本 → 日志 | MANDATORY: modules/logging.md | 日志写入 |
merge 出口表(merge_translations.py 的 3 种结果):
| 出口 | 条件 | 主流程动作 |
|---|---|---|
| --- | --- | --- |
| exit 0 无告警 | 全部通过 | → 直接导出 |
| exit 0 有告警 | 验表不通过(_fix_pages.json 存在) | → 读 _fix_pages.json → 重译问题页 → 回写 → 重新 merge(最多 2 轮) |
| exit 2 | 完整性不通过(缺页/空页,_retry_pages.json 存在) | → 读 _retry_pages.json → 起 Agent 补跑缺失页 → 重新 merge(最多 2 轮) |
> 循环上限:同一问题最多 2 轮修复。2 轮后仍失败 → 报告用户,标注遗留问题,跳过继续导出。
| PDF → 日志 | → MANDATORY: modules/logging.md | 日志写入 |
|---|---|---|
| 文本输入 | MANDATORY: modules/translate-core.md | 术语扫描 → AI 翻译 → 自检 → 输出 |
| 文本 → 日志 | MANDATORY: modules/logging.md | 日志写入 |
加载顺序:按路由表自上而下逐条触发,不得预加载所有模块。
用户提交 PDF
│
├─ 步骤 0 文件存在性检查 【强制】
├─ 步骤 0.5 PDF 加密检测(加密→终止) 【强制】
├─ 步骤 1 paddleocr 解析 【强制】
├─ 步骤 1.5 fix_truncations 截断修复 【强制】
├─ 步骤 2 5页切组 → Agent 自扫自译 【强制】(并发≤8,79页=16组分2批)
│
└─ 步骤 3 merge + 校验 【强制】
│
├── 出口A: exit 0 无告警 ──→ 步骤 4 导出
│
├── 出口B: exit 0 + _fix_pages.json ──→ 修复循环 ──→ 重 merge
│ (类型分布/表格行数不一致,最多 2 轮)
│
└── 出口C: exit 2 + _retry_pages.json ──→ 补跑循环 ──→ 重 merge
(缺页/空页,最多 2 轮)
├─ 步骤 4 导出 HTML + MD 【强制】
└─ 步骤 5 写日志 + preview_url 【强制】
| 步骤 | 性质 | 触发条件 |
|---|---|---|
| --- | --- | --- |
| 0 文件检查 | 强制 | 无条件 |
| 0.5 加密检测 | 强制 | 无条件;加密即终止 |
| 1 paddleocr | 强制 | 无条件 |
| 1.5 截断修复 | 强制 | 无条件 |
| 2 Agent 自扫自译 | 强制 | 无条件 |
| 3 merge+校验 | 强制 | 无条件;按出口分叉 |
| ↳ 补跑循环 | 条件强制 | exit 2 触发,读 _retry_pages.json,最多 2 轮 |
| ↳ 修复循环 | 条件强制 | _fix_pages.json 存在触发,最多 2 轮 |
| 4 导出 | 强制 | merge exit 0 无告警,或循环用尽后 |
| 5 日志 | 强制 | 导出完成后 |
循环上限:同一问题最多 2 轮。2 轮后仍失败 → 报告用户,标注遗留问题,跳过继续导出。
merge 三项校验(merge_translations.py 内置,顺序执行):
| 顺序 | 校验项 | 失败时 |
|---|---|---|
| --- | --- | --- |
| ① | 完整性(缺页/空文件) | exit 2,写 _retry_pages.json |
| ② | 合并(按元素对齐) | 打印 [missing]/[continuation],不阻塞 |
| ③④ | 元素类型分布 + 表格行数 | return False,写 _fix_pages.json |
脚本:term_match.py(位于 skill 目录下)
设计原则:使用 pyahocorasick 库实现真正的 Aho-Corasick 自动机。术语一次遍历完成全部匹配。长词优先,大小写不敏感。quick_check 子串预判跳过无需匹配的文本。输出 JSON 格式与旧版兼容。
调用方式:
& "$env:USERPROFILE\.workbuddy\binaries\python\envs\default\Scripts\python.exe" `
"$env:USERPROFILE\.workbuddy\skills\gxpcode-translator\term_match.py" "<原文>"
输出 JSON:
{
"source_text": "原文",
"placeholder_text": "{{T001}} integrity testing should be performed before use.",
"matches": [{"start": 0, "end": 20, "en": "sterilization filter", "cn": "除菌过滤器"}],
"placeholder_map": [{"pid": "{{T001}}", "en": "sterilization filter", "cn": "除菌过滤器"}],
"match_count": 1
}
流程中仅消费 matches 字段提取 en→cn 映射对。占位符替换功能保留可供手动调试用。
用户可通过以下方式维护词典:
Gxpcode-dict.csv(推荐用 Excel 打开 CSV 编辑)CSV 格式要求:
en,cn,explain
sterilization filter,除菌过滤器,
qualification,确认,
bio-decontamination,去生物污染,通过使用杀孢子剂消除活性生物负荷的工艺。
示例 1(文本,默认)
用户:/trans Sterilization filter integrity testing should be performed before use.
输出:除菌过滤器完整性测试应在使用前执行。
日志:自动写入 ~/.workbuddy/skills/gxpcode-translator/logs/YYYY-MM-DD_HH-MM-SS_trans.md
示例 2(PDF)
用户上传 SOP-Validation.pdf 并说 /trans
modules/Gxpcode-pdf-input.md → paddleocr-parser 解析 PDF(步骤 0~1.4)fix_truncations.py 修复截断页(步骤 1.5,不可跳过)_pXXX_trans.mdpreview_url共 1 个版本