emacs上的LLM交互工具gptel介绍
GPTEL介绍和基本使用
近年来.大型语言模型(LLM)的发展日新月异.它们在文本生成,代码编写,语言翻译,问答系统等领域展现出了惊人的能力.
像OpenAI 的 ChatGPT,Google 的 Gemini,Anthropic 的 Claude.以及本地运行的Ollama,Llama.cpp 等模型.都成为了开发者和内容创作者的强大工具.
而像 GitHub Copilot 和 Cursor 这样的 IDE 集成.更是将 LLM 的能力直接带入了代码编辑器.极大地提升了开发效率.
作为 Emacs 用户.我们自然也希望能在 Emacs 中充分利用 LLM 的强大功能.虽然已经有一些 Emacs LLM 客户端.但它们往往局限于特定的交互方式(如 shell 模式或 Org-mode 的 babel 块).
而我们今天要介绍的 gptel.则是一款与众不同的 LLM 客户端.它将 LLM 的能力无缝融入 Emacs 的日常使用中.让你可以随时随地.在任何 buffer 中与 AI 交互.
gptel 的设计理念与 Emacs 的精神高度契合:高度可定制,可扩展.并且与 Emacs 的工作流程完美融合.它不仅仅是一个简单的聊天窗口.更是一个强大的工具.可以帮助你完成各种各样的任务.
gptel 的特性与优势
gptel 的强大之处在于它的灵活性和可定制性.它不仅支持多个 LLM后端.还提供了丰富的选项和钩子.让你可以根据自己的需求进行深度定制.
异步与流式响应: gptel 的所有操作都是异步的.
这意味着在等待 LLM 响应时. 仍然可以继续使用Emacs. 而且, gptel 支持流式响应(如果 LLM 后端支持). 可以实时看到 LLM 生成的内容.无需等待整个回复完成.
广泛的 LLM 后端支持: gptel 支持多种主流的 LLM 服务.包括:
- ChatGPT
- Gemini
- DeepSeek
- Claude
- Ollama
- Llama.cpp
- GPT4All
- Kagi (FastGPT & Summarizer)
- Azure
- Groq
- Perplexity
- OpenRouter
- together.ai
- Anyscale
- PrivateGPT
- DeepSeek
- Cerebras
- Github Models
- Novita AI
- xAI
更重要的是.gptel 支持兼容 OpenAI API 的任何 LLM 服务, 可以轻松地使用各种本地模型或自定义服务.
深度 Emacs 集成:
- 可在任何 buffer 中使用: 无论是在编写代码,撰写文档,编辑配置文件. 还是在 shell 中执行命令. 都可以随时随地调用 gptel.让 LLM 为你提供帮助.
- 与 Emacs 工作流无缝融合:gptel 的操作方式与 Emacs 的其他命令一样自然.
- 支持区域(region)操作:可以方便地处理代码,文本片段.
强大的 Org-mode 集成: gptel 为 Org-mode 用户提供了特别的优化:
gptel-org-branching-context: 开启此选项后.每个 Org 标题下的内容将构成一个独立的对话分支.这使得在同一个文件中进行多个独立的对话成为可能.gptel-org-set-topic: 将当前对话的上下文限制在当前 Org 标题下.gptel-org-set-properties: 将 gptel 的配置(如模型,后端,温度等)保存为 Org 属性.实现"可复现"的对话.- 自动将 LLM 返回的 Markdown 格式转换为 Org 格式.
灵活的上下文管理: 除了当前 buffer 的内容. 可以使用
gptel-add命令将任意区域, buffer 或文件添加到 gptel 的上下文中.可以轻松地让 LLM 参考项目中的其他文件, 代码片段或外部文档. 使用
gptel-context--buffer-setup可以查看上下文. 使用gptel-use-context控制如何使用这些上下文.实验性工具调用 (Tool Use): gptel 支持调用外部工具.允许 LLM 直接和 Emacs 以及外部世界交互.你可以定义自己的工具.实现更多可能.
可定制性:
通过
gptel-directives自定义 system prompt, 支持函数动态生成 prompt.(setq gptel-directives '((rewrite . gptel--rewrite-directive-default) (calc . "你是一个数学计算机, 仅仅给出最终的结果就行, 不要其他任何其他输出") (poet . "你是一个中国古代诗人, 擅长唐诗宋词") (clj-dart-expert . read-dart-expert-prompt) (emacs-expert . read-emacs-expert-prompt) (translation . "你是一个翻译, 把文本翻译为中文, 输出中使用英文标点, 而不是中文标点.") (default . "You are a large language model living in Emacs and a helpful assistant. Respond concisely, use english punctuation.") (programming . "You are a large language model and a careful programmer. Provide code and only code as output without any additional text, prompt or note.") (writing . "You are a large language model and a writing assistant. Respond concisely.") (chat . "You are a large language model and a conversation partner. Respond concisely.")))其中read-dart-expert-prompt 是一个函数
(defun read-prompt-from-file (file) "Read the content of FILE and return it as a string." (with-temp-buffer (insert-file-contents file) (buffer-string))) (defun read-emacs-expert-prompt () "Emacs expert." (read-prompt-from-file "~/.emacs.d/prompts/emacs-expert.md")) (defun read-dart-expert-prompt () "Clj dart expert." (read-prompt-from-file "~/.emacs.d/prompts/clj-dart-expert.md"))通过
gptel-request构建自定义命令.丰富的钩子 (hook):
gptel-pre-response-hook,gptel-post-response-functions,gptel-post-stream-hook等.gptel-expert-commands, 用于打开菜单中的专家模式.
安装与配置
通过 MELPA 安装 (推荐):
- 确保你的 Emacs 配置中已经添加了 MELPA 源.
- 执行
M-x package-install RET gptel RET. - (可选) 如果你需要 Markdown 支持.可以安装
markdown-mode.
基本配置 (以 ChatGPT 为例):
从 OpenAI 官网获取你的 API 密钥.
在 Emacs 配置文件中设置
gptel-api-key变量.为了安全起见.推荐使用auth-source:在
~/.authinfo文件中添加一行:machine api.openai.com login apikey password YOUR_API_KEY在 Emacs 配置文件中添加:
(setq gptel-api-key #'gptel-api-key-from-auth-source)
你也可以直接设置
gptel-api-key变量.但请注意保护好你的密钥:(setq gptel-api-key "YOUR_API_KEY")
或者更安全地, 将其设置为一个返回 key 的函数:
(setq gptel-api-key (lambda () "YOUR_API_KEY"))如果你不设置, 在你第一次使用gptel时, 它会提示你输入.
其他 LLM 后端的配置:
gptel 通过
gptel-make-openai,gptel-make-gemini,gptel-make-anthropic,gptel-make-ollama等函数支持其他多种模型, 详细配置, 请参考gptel 源码中对应函数的文档.这里提供一个常用模型的配置示例:
;; OPTIONAL configuration (setq gptel-model 'gpt-3.5-turbo gptel-backend (gptel-make-azure "Azure-1" :protocol "https" :host "YOUR_RESOURCE_NAME.openai.azure.com" :endpoint "/openai/deployments/YOUR_DEPLOYMENT_NAME/chat/completions?api-version=2023-05-15" :stream t :key #'gptel-api-key :models '(gpt-3.5-turbo gpt-4)))进阶配置
- gptel-directives: 自定义系统提示, 可以是字符串, 也可以是返回字符串的函数, 让你可以根据上下文动态生成prompt, 比如加入代码评审规范, 或者特定语言的文档
- (setq gptel-expert-commands t) 打开专家模式
实战演练 (详细的使用示例):
基本对话:
- 在任意 buffer 中使用
gptel-send - 使用
C-u gptel-send(或gptel-menu) 打开 transient 菜单.调整模型,温度等参数.
- 在任意 buffer 中使用
专用聊天 buffer:
M-x gptel创建新的聊天 buffer.- 使用
C-c RET(gptel-send) 发送 prompt. - 如何保存和恢复聊天会话 (开启
gptel-mode).
上下文管理:
- 使用
gptel-add将区域.buffer.文件添加到上下文. - 使用
gptel-context--buffer-setup查看和管理当前上下文. 演示如何用不同的上下文让LLM 完成不同的任务
- 使用
Org-mode 专属功能:
- 演示
gptel-org-set-topic和gptel-org-branching-context. - 演示
gptel-org-set-properties.
- 演示
编辑和修改历史消息:
区域重写/重构 (
gptel-rewrite):- 选中区域.
M-x gptel-rewrite.- 使用
C-c C-a接受,C-c C-d查看 diff,C-c C-e使用 ediff.
添加中文标点替换的例子.
(defun my/gptel-replace-chinese-punctuation (start end) "Replace Chinese punctuation with English punctuation in the region from START to END." (interactive "r") (save-excursion (let ((chinese-punctuation '("." "." ";" ":" "?" "!" "(" ")" "<" ">" "," "'" "'" """ """)) (english-punctuation '("." "." ";" ":" "?" "!" "(" ")" "<" ">" "," "'" "'" "\"" "\""))) (goto-char start) (while (search-forward-regexp "[..;:?!,()<>,''""]" end t) (let* ((cchar (match-string-no-properties 0)) (pos (cl-position cchar chinese-punctuation :test #'string=))) (when pos (replace-match (nth pos english-punctuation) t t))))))) (add-hook 'gptel-post-response-functions #'my/gptel-replace-chinese-punctuation)工具调用示例 (待补充):
- 展示一个简单的工具定义 (如获取当前 buffer 名称).
- 演示如何在 prompt 中触发工具调用.
编写自己的命令 使用
gptel-request展示已经add的commit message 例子
(defun get-staged-diff () "Get the diff of staged files in the current Git repository." (string-trim (shell-command-to-string "git diff --cached"))) (defun gptel-commit-message () "Insert a generated commit message at point using GPT." (interactive) (let ((diff (get-staged-diff))) (message "正在生成提交信息...") (gptel-request (concat "请直接生成中文的commit message, 要求如下 1. 使用中文 2. 使用英文半角标点, 比如`:\",`等 3. 提交信息简洁明了 4. 提交标题必须以下前缀之一开头: - [feat] 用于新功能 - [bug] 用于修复bug - [ref] 用于代码重构 - [doc] 用于文档更新 - [wip] 用于进行中的工作 5. 有列表详细描述改动的具体内容 " diff) :stream t )))
总结
gptel 是一个强大而灵活的 Emacs LLM 客户端.它将 LLM 的能力无缝融入到你的 Emacs 工作流中.通过丰富的选项,钩子和与其他 Emacs 工具的深度集成.gptel 可以帮助你提高工作效率,激发创造力.并探索 LLM 的无限潜力.