如何调用 LLM 对查询结果进行翻译?

之前遇到一些词典看不太明白,都需要复制粘贴相关内容到 LLM 中提问,但总觉得这样很麻烦。

现在是否可以通过 LLM 的 api,对词典的查询结果进行翻译或提问等?

什么词典软件支持这样的操作或有类似插件的机制让我们可以拓展这个功能?

以下是 AI 的回答,不知道是否靠谱?

我明白了,你的需求是:对现有的英英词典(如 Webster、Oxford 等)的释义内容本身进行“即时翻译”,实现类似浏览器沉浸式翻译插件的效果,让原本的全英解释变成中英对照。

这在 GoldenDict(尤其是 GoldenDict-ng)中是完全可以实现的,但不能通过“Programs”接口(只能传入关键词),而是需要利用 GoldenDict 的 前端渲染能力(JavaScript + DOM 操作)

若你具备 PythonOllama 的使用基础,且有 Web 开发(Flutter/前端) 的概念,那么这个方案对你来说会非常直观。

核心方案:注入 JavaScript (article-style.js) + Ollama API

GoldenDict 允许用户在配置目录中放置一个 article-style.js 文件。这个 JS 文件会在每次查询结果加载完毕后自动执行。我们可以利用它来:

  1. 抓取特定词典的 HTML 文本内容。
  2. 通过 fetch 请求本地运行的 Ollama
  3. 将翻译好的中文插入到原英文段落的下方。

第一步:配置 Ollama 允许跨域 (CORS)

GoldenDict 的内部浏览器页面通常运行在 qrc:// 或类似协议下,直接请求 http://localhost 会被浏览器的安全策略(CORS)拦截。你需要设置环境变量启动 Ollama。

在 Windows 终端(PowerShell 或 CMD)中设置环境变量并重启 Ollama:

# 停止当前运行的 Ollama
Taskkill /IM ollama_app_v2.exe /F

# 设置环境变量允许所有来源(或者仅允许 null/qrc 等)
[Environment]::SetEnvironmentVariable("OLLAMA_ORIGINS", "*", "User")

# 重新启动 Ollama
ollama serve

(注意:设置完环境变量后,请确保你的系统托盘里的 Ollama 也是重启过的)


第二步:找到目标词典的 CSS Class

你需要知道你想翻译哪本词典的内容。

  1. 在 GoldenDict (推荐使用 GoldenDict-ng) 中查询任意单词。
  2. 在页面上右键 → 审查元素 (Inspect) (GoldenDict-ng 支持此功能)。
  3. 找到包裹该词典内容的 div。通常它们会有特定的 class,例如 .gdarticle 是所有词典的容器,而具体的词典会有特定的 ID 或 class,比如 dsl_dictionary_name

假设我们要翻译的词典内容包裹在 <div class="dsl_definition"> 中(这是 DSL 词典常见的类名,如果是 MDX 词典,可能需要根据具体 CSS 调整)。


第三步:编写 article-style.js

找到你的 GoldenDict 配置目录(通常在 %APPDATA%\GoldenDict 或程序安装目录下的 portable 文件夹)。如果有 article-style.js 则编辑,没有则新建。

将以下代码写入文件。这段代码会在每个词典条目旁添加一个“:robot: 翻译”按钮,点击后调用 Gemma 进行翻译并插入。

// article-style.js

$(document).ready(function() {
    // 1. 配置:这里填入你想翻译的词典内容的 CSS 选择器
    // 比如:.dsl_definition p (段落), .ex (例句), 或者直接整个 .dsl_definition
    // 为了演示,假设我们给每个词典条目的顶部加一个翻译按钮
    var targetSelector = ".gdarticle"; 

    // 2. 遍历每个词典条目,注入按钮
    $(targetSelector).each(function() {
        var $article = $(this);
        
        // 创建一个按钮
        var $btn = $('<button style="display:block; margin:5px 0; cursor:pointer; background:#e0f7fa; border:1px solid #006064; padding:5px; border-radius:4px;">🤖 翻译此词典内容</button>');
        
        // 插入按钮到词典头部
        $article.prepend($btn);

        // 3. 按钮点击事件
        $btn.click(async function() {
            var $button = $(this);
            var originalText = $article.text().trim(); // 获取纯文本内容
            
            // 简单的字数限制,避免把整个几十页的解释都发过去
            if (originalText.length > 2000) {
                originalText = originalText.substring(0, 2000) + "...";
            }

            $button.text("⏳ 翻译中 (调用 Ollama/Gemma)...").prop("disabled", true);

            // 构造 Prompt
            var prompt = "Translate the following dictionary definition text into Chinese. Keep the translation concise and accurate. Do not explain, just translate:\n\n" + originalText;

            try {
                // 4. 调用 Ollama
                const response = await fetch("http://localhost:11434/api/generate", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json"
                    },
                    body: JSON.stringify({
                        model: "gemma2:9b", // 确保模型名称正确
                        prompt: prompt,
                        stream: false
                    })
                });

                const data = await response.json();
                const translatedText = data.response;

                // 5. 将翻译结果渲染回页面
                // 这里我们用简单的 pre 标签显示,也可以插入到具体的 DOM 节点中实现“双语对照”
                var $resultDiv = $('<div class="llm-translation-result" style="border-left: 4px solid #4caf50; padding: 10px; margin: 10px 0; background: #f1f8e9; white-space: pre-wrap;"></div>');
                $resultDiv.text(translatedText);
                
                $button.after($resultDiv);
                $button.text("✅ 翻译完成").hide(); // 翻译完隐藏按钮

            } catch (error) {
                console.error(error);
                $button.text("❌ 错误 (检查控制台/CORS)").prop("disabled", false);
                $button.after('<div style="color:red">Error: Ensure Ollama is running and OLLAMA_ORIGINS="*" is set.</div>');
            }
        });
    });
});

关键点解析

  1. jQuery 支持: GoldenDict 内部通常已经加载了 jQuery。如果没有,你可能需要用原生 JS (document.querySelectorAll) 重写上述选择器部分。
  2. 按需翻译: 我设计为“点击按钮”触发。因为英英词典内容通常很长,如果每个单词都自动调用 LLM 翻译整个页面,会导致查询速度变慢,且 GPU 负载过高。
  3. 精确度: 效果好坏取决于 targetSelector 的选择。
  • 如果你想要逐句对照(像沉浸式翻译那样),代码会复杂一些:需要遍历所有 <p> 标签,分别发送请求(或者批量发送),然后插在每个 <p> 后面。
  • 目前的脚本是全文翻译后附在上方/下方,这对于快速理解大意已经足够。

进阶:如何实现“逐行对照”?

如果你希望像沉浸式翻译插件一样,在每一句英文例句下面显示中文,你需要修改 JS 逻辑:

  1. 选择器定位到例句的具体 class(例如 .x-g.example)。
  2. 循环这些元素。
  3. 提取 innerText
  4. 发送给 Ollama。
  5. append 一个 <div class="cn-trans">...</div> 到该元素内部。

这完全就是前端开发的逻辑了。若你对 Flutter/Dart 和 Python 有一定理解,在此处使用 JavaScript 操作 DOM 应该不会造成太大障碍。

可以直接用豆包,但不支持自定义接口。

可否展开说说,不太理解。

豆包支持用户选择文本进行翻译解释。就两个动作,第一个是选择文本,豆包会在文本上方弹出动作条,第二个是点击动作条中的解释按钮,豆包会弹出小窗口进行翻译和解释内容,你可以在这个弹窗中二次提问。不知道能不能满足你的需求?

1 Like

明白了!那么只要本地安装一个豆包或元宝之类的就可以了,:+1:

之前这些app的这个功能都被我屏蔽了,原来还有这个妙用,不错!感谢!学到了!

我使用元宝体验了一番,比我预想的还要好,开心 :grinning_face:

1 Like