当前位置: 首页 > news >正文

折腾笔记[56]-使用kimi批量进行英文文献翻译

摘要

在macOS上配置kimi-cli的libretranslate-en-to-zh技能,通过本地LibreTranslate服务将英文技术文档批量翻译为简体中文.

声明

本文人类为第一作者, 龙虾为通讯作者.本文有AI生成内容.

libretranslate-en-to-zh技能

SKILL.md

<hr>
<p>name: libretranslate-en-to-zh</p>
<h2 id="description-translate-english-text-or-files-to-simplified-chinese-using-a-local-libretranslate-service-use-when-the-user-asks-to-translate-english-technical-documents-manuals-or-plain-text-to-chinese-zh-hans-via-libretranslate-or-when-working-with-cognex-insight-documentation-and-similar-industrial-technical-english-content-that-needs-chinese-translation-">description: Translate English text or files to Simplified Chinese using a local LibreTranslate service. Use when the user asks to translate English technical documents, manuals, or plain text to Chinese (zh-Hans) via LibreTranslate, or when working with Cognex InSight documentation and similar industrial/technical English content that needs Chinese translation.</h2>
<h1 id="libretranslate-en-zh-hans">LibreTranslate EN → ZH-Hans</h1>
<p>Translate English content to Simplified Chinese via a local LibreTranslate instance.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>LibreTranslate installed (e.g. <code>uv tool install libretranslate</code>)</li>
<li><code>en -&gt; zh-Hans</code> language pack present at <code>~/.local/share/argos-translate/packages/translate-en_zh-1_9/</code></li>
<li>Default endpoint: <code>http://127.0.0.1:5555</code> (port 5000 is often occupied by macOS AirTunes)</li>
</ul>
<h2 id="quick-start">Quick Start</h2>
<h3 id="translate-text-inline">Translate text inline</h3>
<pre><code class="lang-bash"><span class="hljs-keyword">python3</span> ~/.config/agents/skills/libretranslate-<span class="hljs-keyword">en</span>-<span class="hljs-keyword">to</span>-zh/scripts/translate.<span class="hljs-keyword">py</span> \--text <span class="hljs-string">"System Requirements"</span>
</code></pre>
<h3 id="translate-a-single-file">Translate a single file</h3>
<pre><code class="lang-bash">python3 ~/.config/agents/skills/libretranslate-en-to-zh/scripts/translate<span class="hljs-selector-class">.py</span> \--file <span class="hljs-selector-tag">input</span><span class="hljs-selector-class">.txt</span> --out output.txt
</code></pre>
<h3 id="batch-translate-a-directory">Batch translate a directory</h3>
<pre><code class="lang-bash">python3 ~<span class="hljs-regexp">/.config/</span>agents<span class="hljs-regexp">/skills/</span>libretranslate-en-to-zh<span class="hljs-regexp">/scripts/</span>translate.py \--dir sections<span class="hljs-regexp">/en/</span> --outdir sections<span class="hljs-regexp">/zh/</span>
</code></pre>
<h2 id="service-lifecycle">Service Lifecycle</h2>
<ol>
<li><strong>Check</strong> if LibreTranslate is running on <code>localhost:5555</code></li>
<li><strong>Start</strong> automatically if not running (background daemon, logs to <code>/tmp/libretranslate.log</code>)</li>
<li><strong>Wait</strong> up to 30s for readiness</li>
<li><strong>Translate</strong> via <code>/translate</code> API (<code>source=en</code>, <code>target=zh-Hans</code>)</li>
</ol>
<p>To stop the service manually:</p>
<pre><code class="lang-bash"><span class="hljs-selector-tag">pkill</span> <span class="hljs-selector-tag">-f</span> "<span class="hljs-selector-tag">libretranslate</span> <span class="hljs-selector-tag">--host</span> 127<span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.1</span> <span class="hljs-selector-tag">--port</span> 5555"
</code></pre>
<h2 id="post-translation-review-checklist">Post-Translation Review Checklist</h2>
<p>Machine translation of technical docs requires human review. Verify:</p>
<table>
<thead>
<tr>
<th>Category</th>
<th>Rule</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Product names</td>
<td>Keep English</td>
<td>In-Sight → <strong>In-Sight</strong> (not &quot;内视&quot;)</td>
</tr>
<tr>
<td>Function names</td>
<td>Keep English</td>
<td>ApplyAcquisitionSettings → <strong>ApplyAcquisitionSettings</strong></td>
</tr>
<tr>
<td>Model numbers</td>
<td>Keep original</td>
<td>In-Sight 3800 → <strong>In-Sight 3800</strong></td>
</tr>
<tr>
<td>Acronyms</td>
<td>Keep or add note</td>
<td>COM → <strong>COM</strong> (串口)</td>
</tr>
<tr>
<td>Units</td>
<td>Keep symbols</td>
<td>mm, ms, FPS</td>
</tr>
</tbody>
</table>
<h2 id="troubleshooting">Troubleshooting</h2>
<table>
<thead>
<tr>
<th>Symptom</th>
<th>Cause</th>
<th>Fix</th>
</tr>
</thead>
<tbody>
<tr>
<td>Port 5000 refused / 403</td>
<td>macOS AirTunes occupies 5000</td>
<td>Use <code>--port 5555</code></td>
</tr>
<tr>
<td><code>Chinese not available</code></td>
<td>Missing <code>en-&gt;zh</code> language pack</td>
<td>Download <code>translate-en_zh-1_9.argosmodel</code> and unzip to <code>~/.local/share/argos-translate/packages/</code></td>
</tr>
<tr>
<td><code>filelock Timeout</code></td>
<td>Stale lock file</td>
<td><code>rm ~/.local/share/argos-translate/minisbd/*.lock</code> then restart</td>
</tr>
<tr>
<td>Empty response</td>
<td>Service still loading</td>
<td>Wait 10-20s for model warmup</td>
</tr>
</tbody>
</table>
<h2 id="python-api-for-embedding-">Python API (for embedding)</h2>
<pre><code class="lang-python">from scripts.translate <span class="hljs-built_in">import</span> translate_text, translate_file, translate_dir<span class="hljs-comment"># Single string</span>
<span class="hljs-attr">zh</span> = translate_text(<span class="hljs-string">"Release History"</span>)<span class="hljs-comment"># Single file</span>
<span class="hljs-attr">zh</span> = translate_file(<span class="hljs-string">"input.txt"</span>, <span class="hljs-string">"output.txt"</span>)<span class="hljs-comment"># Whole directory</span>
translate_dir(<span class="hljs-string">"sections/en/"</span>, <span class="hljs-string">"sections/zh/"</span>)
</code></pre>

scripts/translate.py

#!/usr/bin/env python3
"""
LibreTranslate EN->ZH helper script.Usage:python translate.py --text "Hello world"python translate.py --file /path/to/input.txtpython translate.py --file /path/to/input.txt --out /path/to/output.txtpython translate.py --dir /path/to/en_dir/ --outdir /path/to/zh_dir/
"""from __future__ import annotations
import argparse
import http.client
import json
import os
import pathlib
import subprocess
import sys
import timeDEFAULT_HOST = "127.0.0.1"
DEFAULT_PORT = 5555
SOURCE_LANG = "en"
TARGET_LANG = "zh-Hans"def is_service_running(host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> bool:"""Check if LibreTranslate is responding."""try:conn = http.client.HTTPConnection(host, port, timeout=2)conn.request("GET", "/languages")resp = conn.getresponse()conn.close()return resp.status == 200except Exception:return Falsedef ensure_service(host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> None:"""Start LibreTranslate if not already running."""if is_service_running(host, port):returnlibretranslate = os.path.expanduser("~/.local/bin/libretranslate")if not os.path.exists(libretranslate):libretranslate = "libretranslate"print(f"[libretranslate-en-to-zh] Starting LibreTranslate on {host}:{port} ...")log_path = "/tmp/libretranslate.log"with open(log_path, "a") as logf:subprocess.Popen([libretranslate, "--host", host, "--port", str(port)],stdout=logf,stderr=subprocess.STDOUT,start_new_session=True,)# Wait up to 30s for service to become readyfor _ in range(30):time.sleep(1)if is_service_running(host, port):print(f"[libretranslate-en-to-zh] Service ready at http://{host}:{port}")returnprint(f"[libretranslate-en-to-zh] ERROR: Service failed to start. Check {log_path}")sys.exit(1)def translate_text(text: str, host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> str:"""Translate a single string."""ensure_service(host, port)payload = json.dumps({"q": text,"source": SOURCE_LANG,"target": TARGET_LANG,"format": "text",})headers = {"Content-Type": "application/json"}conn = http.client.HTTPConnection(host, port, timeout=60)try:conn.request("POST", "/translate", body=payload, headers=headers)resp = conn.getresponse()data = resp.read().decode("utf-8")conn.close()if resp.status != 200:raise RuntimeError(f"HTTP {resp.status}: {data}")result = json.loads(data)if "translatedText" not in result:raise RuntimeError(f"Unexpected response: {data}")return result["translatedText"]except Exception:conn.close()raisedef translate_file(input_path: str, output_path: str | None = None,host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> str:"""Translate the contents of a file."""p = pathlib.Path(input_path)if not p.exists():raise FileNotFoundError(f"File not found: {input_path}")text = p.read_text(encoding="utf-8")translated = translate_text(text, host, port)if output_path:out_p = pathlib.Path(output_path)out_p.parent.mkdir(parents=True, exist_ok=True)out_p.write_text(translated, encoding="utf-8")print(f"[libretranslate-en-to-zh] Written: {output_path}")return translateddef translate_dir(input_dir: str, output_dir: str,host: str = DEFAULT_HOST, port: int = DEFAULT_PORT) -> None:"""Translate all .txt files in a directory, preserving structure."""src = pathlib.Path(input_dir)dst = pathlib.Path(output_dir)if not src.is_dir():raise NotADirectoryError(f"Not a directory: {input_dir}")files = list(src.rglob("*.txt"))if not files:print("[libretranslate-en-to-zh] No .txt files found.")returnensure_service(host, port)for f in files:rel = f.relative_to(src)out_file = dst / relprint(f"[libretranslate-en-to-zh] Translating: {f} -> {out_file}")try:translate_file(str(f), str(out_file), host, port)except Exception as exc:print(f"[libretranslate-en-to-zh] FAILED: {f} ({exc})")print(f"[libretranslate-en-to-zh] Done. Translated {len(files)} file(s).")def main() -> None:parser = argparse.ArgumentParser(description="LibreTranslate EN->ZH helper")parser.add_argument("--text", help="Text to translate")parser.add_argument("--file", help="Input file path")parser.add_argument("--out", help="Output file path (optional)")parser.add_argument("--dir", help="Input directory (translates all .txt files)")parser.add_argument("--outdir", help="Output directory (used with --dir)")parser.add_argument("--host", default=DEFAULT_HOST, help="LibreTranslate host")parser.add_argument("--port", type=int, default=DEFAULT_PORT, help="LibreTranslate port")args = parser.parse_args()if args.text:print(translate_text(args.text, args.host, args.port))elif args.file:result = translate_file(args.file, args.out, args.host, args.port)if not args.out:print(result)elif args.dir:if not args.outdir:parser.error("--outdir is required when using --dir")translate_dir(args.dir, args.outdir, args.host, args.port)else:parser.print_help()sys.exit(1)if __name__ == "__main__":main()

运行效果

  1. 运行python translate.py --text "Attention is all you need"输出"你只需要注意一点"
  2. 运行python translate.py --file input.txt --out output.txt翻译单个文件
  3. 运行python translate.py --dir en/ --outdir zh/批量翻译目录下所有.txt文件
  4. 服务自动管理:检测→启动→等待就绪→翻译,无需手动干预
http://www.jsqmd.com/news/740289/

相关文章:

  • 8大网盘直链下载神器:告别限速,一键获取真实下载地址
  • Seraphine:英雄联盟玩家的终极智能助手,全面提升你的游戏体验
  • 广州电子式动态平衡电动调节阀哪家好
  • 别再被Cartopy的‘白线’坑了!一个add_cyclic_point函数搞定全球数据可视化
  • 折腾笔记[53]-使用kimi转换latex到pdf
  • 如何快速掌握抖音下载器:面向新手的完整批量下载指南
  • 别再死记50欧姆了!从PCB走线到同轴线,一文搞懂特征阻抗的底层逻辑
  • 别再死记硬背了!用Python和PyTorch亲手画一遍Sigmoid、Tanh、ReLU激活函数,理解立马不一样
  • 折腾笔记[55]-使用kimi转换markdown为pdf
  • CF1608F MEX counting
  • Virtuoso ADE XL参数扫描实战:用gmid曲线指导MOS管尺寸优化(以IC618为例)
  • OTA校验失败、CRC对不上、版本号错乱——C语言固件升级链路11个关键断点调试技巧,工程师私藏手册
  • 折腾笔记[52]-使用kimi发送消息到matrix房间
  • 为内容创作平台集成 Taotoken 提供多样化的文本生成风格
  • 为什么你的Horovod训练总OOM?20年HPC架构师首次公开:4层内存泄漏配置链路与实时诊断脚本
  • MultiTimer vs. FreeRTOS软件定时器:在资源受限的STM32F4上,我为什么选择了它?
  • WorkshopDL:无需Steam客户端,轻松下载Steam创意工坊模组的终极方案
  • 别再死磕YOLOv5了!用CLIP+CRIS结构,手把手教你实现文本驱动的目标检测
  • 2026届学术党必备的十大AI辅助论文方案横评
  • 20260430
  • DataChain:构建面向对象存储的数据上下文层,实现AI时代数据处理革命
  • Stata数据合并保姆级避坑指南:从CSV导入到merge命令的完整流程
  • Windows 11 24H2 LTSC 微软商店一键安装完整指南:如何3分钟恢复完整应用生态
  • 杭州萧山区在职提升学历哪家好?萧山箭金学堂等五大机构深度测评榜 - 浙江行业评测
  • 3分钟搞定Android Studio中文界面:新手必备的完整免费汉化指南
  • 别再到处找了!电气AI项目数据集保姆级导航(含无人机巡检、负荷预测等60+资源)
  • 模型部署前必看:用Netron快速检查ONNX、TensorFlow模型结构,避开这些坑
  • FPGA新手避坑指南:用Verilog写自己的‘软’ROM存储波形,真的比用IP核好吗?
  • AI_10_Coze_Multi-Agent多智能体
  • python sanic