org-ai
适用于 Emacs org-mode 的次模式,提供对生成式 AI 模型的访问。当前支持:
- OpenAI API (ChatGPT, DALL-E,其他文本模型),可以选择通过 Azure API 而不是 OpenAI 运行
- 通过 stable-diffusion-webui 进行稳定扩散
在 org-mode 缓冲区内,您可以:
- 使用 ChatGPT 生成文本,完全控制系统和用户提示 (演示)
- 语音输入和输出!与您的 AI 交谈!
- 使用 Stable Diffusion 或 DALL-E 和文本提示生成图像和图像变体 (演示 1, 演示 2)
- org-ai 无处不在:可用于 org-mode 外的各种命令,用于选择的文本或多个文件的提示。
注意:要使用 OpenAI API,您需要一个 OpenAI 帐户 并且需要获取一个 API 令牌。据我所知,当前免费层的使用限制已相当宽松。
目录
演示
org-mode 中的 ChatGPT
#+begin_ai
Emacs 是最棒的编辑器吗?
#+end_ai
您可以继续键入并按 C-c C-c
创建对话。C-g
将中断正在运行的请求。
org-mode 中的 DALL-E
使用 :image
关键字生成图像。默认使用 DALL·E-3。
#+begin_ai :image :size 1024x1024
超级复杂技术机器的超现实科幻渲染。
#+end_ai
您可以使用以下关键字控制图像生成:
:size <width>x<height>
- 要生成的图像大小 (默认:1024x1024):model <model>
- 要使用的模型 (默认:"dall-e-3"):quality <quality>
- 图像质量 (选项:hd、标准):style <style>
- 要使用的风格 (选项:生动、自然)- `:n
- 要生成的图像数量 (默认:1)
(有关这些设置的更多信息,请参阅 此 OpenAI 博客文章。)
您可以通过 customize-variable
或在配置中设置这些变量的默认值:
(setq org-ai-image-model "dall-e-3")
(setq org-ai-image-default-size "1792x1024")
(setq org-ai-image-default-count 2)
(setq org-ai-image-default-style 'vivid)
(setq org-ai-image-default-quality 'hd)
(setq org-ai-image-directory (expand-file-name "org-ai-images/" org-directory))
图像变体
功能和使用
#+begin_ai...#+end_ai
特殊块
类似于 org-babel,这些块标记 AI 模型的输入(对于 ChatGPT 也包括输出)。您可以将其用于 AI 聊天、文本完成和文本->图像生成。有关更多信息,请参阅下文的 选项。
创建一个块,例如
#+begin_ai
Emacs 是最棒的编辑器吗?
#+end_ai
然后按 C-c C-c
。聊天输入将内联显示,一旦响应完成,您可以输入您的回复,依此类推。请参阅下面的 演示。在 ai 请求运行时,您可以按 C-g
取消它。
您还可以修改 系统 提示和使用的其他参数。系统提示在用户输入之前注入,并“引导”模型以某种风格回答。例如,您可以这样做:
#+begin_ai :max-tokens 250
[SYS]: 假装你是一个强大的中世纪国王。
[ME]: 你今天吃什么?
#+end_ai
这将产生一个类似这样的 API 载荷
{
"messages": [
{
"role": "system",
"content": "假装你是一个强大的中世纪国王。"
},
{
"role": "user",
"content": "你今天吃什么?"
}
],
"model": "gpt-4o-mini",
"stream": true,
"max_tokens": 250,
"temperature": 1.2
}
有关一些提示创意,例如可以参阅 Awesome ChatGPT Prompts。
当使用 :image
标志生成图像时,图像将内联显示在 ai 块下方。图像将与其提示一起存储在 org-ai-image-directory
中,默认位置为 ~/org/org-ai-images/
。
您还可以使用语音输入来转录输入。按C-c r
(org-ai-talk-capture-in-org
)开始录音。请注意,这需要您设置语音识别(请参见下文)。可以通过 org-ai-talk-output-enable
启用语音输出。
在 #+begin_ai...#+end_ai
块内,您可以使用以下命令修改和选择聊天部分:
- 按
C-c <backspace>
(org-ai-kill-region-at-point
) 删除当前光标下的聊天部分。 org-ai-mark-region-at-point
会标记当前光标下的区域。org-ai-mark-last-region
会标记最后一个聊天部分。
ai 块中的语法高亮
要对您的 #+begin_ai ...
块应用语法高亮,只需在 _ai
后添加一个语言主模式名称。例如 #+begin_ai markdown
。特别是对于 markdown,要正确高亮其中的代码,您可以设置 (setq markdown-fontify-code-blocks-natively t)
。确保您还安装了 markdown-mode package。感谢 @tavisrudd 提供此技巧!
完成后跳转到块的末尾
默认启用此行为,使交互更类似于聊天。当存在长输出且缓冲区滚动时阅读可能会有些烦人。因此您可以通过以下设置禁用它:
(setq org-ai-jump-to-end-of-block nil)
插入时自动填充段落
设置 (setq org-ai-auto-fill t)
以“填充”插入的文本(根据 fill-column
自动换行)。基本上像 auto-fill-mode
但适用于 AI。
块选项
#+begin_ai...#+end_ai
块可以使用以下选项。
ChatGPT 的选项
默认情况下,ai 块的内容被解释为 ChatGPT 的消息。以 [ME]:
开头的文本与用户相关, 以 [AI]:
开头的文本与模型的响应相关。可选地,您可以在块的开头添加 [SYS]: <行为>
输入以引导模型(请参阅下文的 org-ai-default-chat-system-prompt
)。
:max-tokens number
- 生成的最大 token 数量 (默认:nil,使用 OpenAI 的默认值):temperature number
- 模型的温度 (默认:1):top-p number
- 模型的 top_p (默认:1):frequency-penalty number
- 模型的频率惩罚 (默认:0):presence-penalty
- 模型的存在惩罚 (默认:0):sys-everywhere
- 对每个用户消息重复系统提示 (默认:nil)
如果您对同一主题和设置(系统提示、温度等)有大量不同的对话线程,并且不想重复所有选项,可以设置 org 文件范围的属性或创建一个带属性抽屉的 org 标题,以便该标题下的所有 #+begin_ai...#+end_ai
块都会继承这些设置。
示例:
* Emacs(有关 Emacs 的多个对话将在此子树下继续)
:PROPERTIES:
:SYS: 你是一个 Emacs 专家。你可以通过回答我的问题来帮助我。你也可以问我问题以澄清我的意图。
:temperature: 0.5
:model: gpt-4o-mini
:END:
** 通过 elisp 进行 Web 编程
#+begin_ai
如何调用 REST API 并解析其 JSON 响应?
#+end_ai
** 其他 Emacs 任务
#+begin_ai...#+end_ai
* Python(有关 Python 的多个对话将在此子树下继续)
:PROPERTIES:
:SYS: 你是一个 Python 程序员。请用详细的分步说明和代码回复任务。
:temperature: 0.1
:model: gpt-4
:END:
** 学习 QUIC
#+begin_ai
如何设置支持 http3 的 Web 服务器?
#+end_ai
** 其他 Python 任务
#+begin_ai...#+end_ai
以下自定义变量可用于配置聊天:
org-ai-default-chat-model
(默认:"gpt-4o-mini")org-ai-default-max-tokens
响应的长度。目前不能超过 4096。如果此值太小,答案可能会被截断 (默认:nil)org-ai-default-chat-system-prompt
如何“引导”模型。这是在用户输入之前注入的提示。 (默认:"You are a helpful assistant inside Emacs.")org-ai-default-inject-sys-prompt-for-all-messages
是否对每个用户消息重复系统提示。有时模型会“忘记”其引导方式。这可以帮助提醒它。 (默认:nil)
DALL-E 的选项
当您在 ai 块中添加 :image
选项时,提示将用于图像生成。
:image
- 生成图像而不是文本:size
- 要生成的图像大小 (默认:256x256,可以是 512x512 或 1024x1024):n
- 要生成的图像数量 (默认:1)
以下自定义变量可用于配置图像生成:
org-ai-image-directory
- 存储生成图像的位置 (默认:~/org/org-ai-images/
)
稳定扩散的选项
类似于 DALL-E,但使用
#+begin_ai :sd-image
<提示>
#+end_ai
您可以通过在 org-mode 图像前加上 #+name 并在 org-ai 块中使用 :image-ref 引用它来运行 img2img。
#+begin_ai :sd-image :image-ref label1
森林,梵高风格
#+end_ai
M-x org-ai-sd-clip 猜测 org-mode 中前一张图像的提示,使用 CLIP 询问器并将其保存在剪贴板中。
M-x org-ai-sd-deepdanbooru 猜测 org-mode 中前一张图像的提示,由 DeepDanbooru 询问器完成并将其保存在剪贴板中。
本地模型的选项
要从使用 oobabooga/text-generation-webui 提供的本地模型请求完成,请按照 下文 描述的设置步骤进行操作。
然后启动一个 API 服务器:
cd ~/.emacs.d/org-ai/text-generation-webui
conda activate org-ai
python server.py --api --model 某个模型
当您在 org-ai 块中添加 :local
键并使用 C-c C-c
请求完成时,该块将发送到本地 API 服务器,而不是 OpenAI API。例如:
#+begin_ai :local
...
#+end_ai
将向 org-ai-oobabooga-websocket-url
发送请求,并将响应流式传输到 org 缓冲区中。
其他文本模型
较旧的补全模型也可以通过在 ai 块中添加 :completion
选项来提示。
:completion
- 使用补全模型而不是 chatgpt 模型:model
- 使用哪个模型,请参阅 https://platform.openai.com/docs/models 获取模型列表
有关这些参数的详细含义,请参阅 OpenAI API 文档。
以下自定义变量可用于配置文本生成:
org-ai-default-completion-model
(默认值:"text-davinci-003"
)
图像变体
您还可以使用现有图像作为输入,生成更多相似的图像。org-ai-image-variation
命令将提示您输入图像的文件路径、大小和数量,然后生成多个图像并在当前的 org-mode
缓冲区内插入指向这些图像的链接。图像将存储在 org-ai-image-directory
中。请参阅下面的演示。
有关更多信息,请参阅 OpenAI 文档。输入图像需要是正方形且大小必须小于 4MB。当前需要命令行工具 curl1。
全局命令
org-ai
也可以在 org-mode
缓冲区之外使用。启用 org-ai-global-mode
时,前缀 C-c M-a
将绑定到多个命令:
命令 | 快捷键 | 描述 |
---|---|---|
org-ai-on-region | C-c M-a r | 对选定文本提出问题或告诉 AI 对其进行处理。响应将打开在 org-mode 缓冲区中,以便您继续对话。设置变量 org-ai-on-region-file (例如 (setq org-ai-on-region-file (expand-file-name "org-ai-on-region.org" org-directory)) )将把该缓冲区与文件关联起来。 |
org-ai-summarize | C-c M-a s | 总结选定的文本。 |
org-ai-refactor-code | C-c M-a c | 告诉 AI 如何更改选定的代码,修改后的差异缓冲区将出现。 |
org-ai-on-project | C-c M-a p | 在多个文件上运行提示并修改/重构。这将在可用时使用 projectile,如果不可用,则回退到当前目录。 |
org-ai-prompt | C-c M-a P | 提示用户输入文本,然后在当前缓冲区中打印 AI 的响应。 |
org-ai-switch-chat-model | C-c M-a m | 交互式更改 org-ai-default-chat-model |
org-ai-open-account-usage-page | C-c M-a $ | 打开 https://platform.openai.com/account/usage 查看您的消费情况。 |
org-ai-open-request-buffer | C-c M-a ! | 打开 url 请求缓冲区。如果某些功能不起作用,查看该缓冲区可能会有所帮助。 |
org-ai-talk-input-toggle | C-c M-a t | 通常为不同的提示命令启用语音输入。 |
org-ai-talk-output-toggle | C-c M-a T | 通常启用语音输出。 |
org-ai-on-project
使用 org-ai-on-project 缓冲区允许您对项目中的文件运行命令,或者仅对这些文件中的选定文本运行命令。例如,您可以选择项目的 readme 文件并询问“这是什么内容?”,或者让 AI 解释代码。您还可以要求代码更改,这将生成差异。如果您认识某些人认为只有启用了 Copilot 的 VS Code 才能做到这一点,请向他们推荐此功能。
运行 org-ai-on-project
命令将打开一个单独的缓冲区,允许您选择多个文件(还可以选择文件中的一个子区域),然后对其运行提示。
如果您停用“修改代码”,效果类似于运行 org-ai-on-region
,只是文件内容全部出现在提示中。
在激活“修改代码”的情况下,您可以要求 AI 修改或重构代码。默认情况下(“请求差异”被停用),我们将提示为所有选定的文件/区域生成新代码,然后您可以看到每个文件的差异并决定是否应用它。激活“请求差异”时,将要求 AI 直接创建一个统一的差异,可以随后应用。
Noweb 支持
给定一个命名的源代码块
#+name: sayhi
#+begin_src shell
echo "Hello there"
#+end_src
我们可以尝试通过名称引用它,但这不起作用。
#+begin_ai
[SYS]: 你是一个模仿者。每当我说话时,你都要重复我对你说的内容。要准确地重复我所说的,不要添加任何东西。
[ME]: <<sayhi()>>
[AI]: <<sayhi()>>
[ME]:
#+end_ai
使用 :noweb yes
#+begin_ai :noweb yes
[SYS]: 你是一个模仿者。每当我说话时,你都要重复我对你说的内容。要准确地重复我所说的,不要添加任何东西。
[ME]: <<sayhi()>>
[AI]: Hello there.
[ME]:
#+end_ai
您还可以在父标题的任何位置使用 org-ai-noweb: yes
标题属性来触发 noweb 扩展(标头参数优先)。
要查看您的文档在发送到 api 时将扩展成什么样子,请运行 org-ai-expand-block
。
内联运行任意 lisp
这是一个黑科技,但效果很好。
创建一个块
#+name: identity
#+begin_src emacs-lisp :var x="fill me in"
(format "%s" x)
#+end_src
我们可以调用它,并让 noweb 参数(支持 lisp)作为代码进行评估
#+begin_ai :noweb yes
告诉我 3 个简单的方法来改进这个 dockerfile
<<identity(x=(quelpa-slurp-file "~/code/ibr-api/Dockerfile"))>>
[AI]: 1. 使用更具体版本的 Python,例如“python:3.9.6-buster”而不是“python:3.9-buster”,以确保兼容未来的更新。
2. 在安装 poetry 后添加一个清理步骤,以删除任何不必要的文件或依赖项,从而减小最终镜像的大小。
3. 使用多阶段构建,将构建环境与生产环境分离,从而减少最终镜像的大小并提高安全性。例如,第一个阶段可用于安装依赖项并构建代码,而第二阶段则仅包含最终工件并用于部署。
[ME]:
#+end_ai
安装
Melpa
org-ai 在 Melpa 上:https://melpa.org/#/org-ai。如果您已将 Melpa 添加到您的包档案中
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(package-initialize)
您可以使用以下命令安装它:
(use-package org-ai
:ensure t
:commands (org-ai-mode
org-ai-global-mode)
:init
(add-hook 'org-mode-hook #'org-ai-mode) ; 在 org-mode 中启用 org-ai
(org-ai-global-mode) ; 在 C-c M-a 上安装全局键绑定
:config
(setq org-ai-default-chat-model "gpt-4") ; 如果您在 gpt-4 beta 上:
(org-ai-install-yasnippets)) ; 如果您使用 yasnippet 并希望 `ai` 片段
Straight.el
(straight-use-package
'(org-ai :type git :host github :repo "rksm/org-ai"
:local-repo "org-ai"
:files ("*.el" "README.md" "snippets")))
手动
检出此存储库。
git clone https://github.com/rksm/org-ai
然后,如果您使用 你可以使用
ffmpeg -f avfoundation -list_devices true -i "" 的输出列出音频输入设备,然后告知 whisper.el 使用它:
(setq whisper--ffmpeg-input-device ":0")。
:0` 是麦克风索引,请查看上述命令的输出以使用其他设备。
我创建了一个 Emacs 助手,可以让你交互式地选择麦克风。参见 这个 gist。
我的完整语音启用配置如下:
(use-package whisper
:load-path (lambda () (expand-file-name "lisp/other-libs/whisper.el" user-emacs-directory))
:config
(setq whisper-model "base"
whisper-language "en"
whisper-translate nil)
(when *is-a-mac*
(rk/select-default-audio-device "Macbook Pro Microphone")
(when rk/default-audio-device)
(setq whisper--ffmpeg-input-device (format ":%s" rk/default-audio-device))))
macOS 替代方案:Siri 语音输入
在 macOS 上,你也可以使用内置的 Siri 语音输入代替 whisper。要启用它,请进入 偏好设置 -> 键盘 -> 语音输入
,启用并设置快捷键。默认快捷键是 ctrl-ctrl。
Windows 特定步骤
(defun whisper--check-install-and-run)
的实现方式在 Win10 上不起作用(参见 https://github.com/rksm/org-ai/issues/66)。
一个解决方法是手动安装 whisper.cpp 和模型并打补丁:
(defun whisper--check-install-and-run (buffer status)
(whisper--record-audio))
espeak / greader
非 macOS 系统上的语音输出默认使用 greader 包,该包使用 espeak 底层语音合成。你需要手动安装 greader(例如通过 M-x package-install
)。从那时起它应该就能正常工作了。你可以通过选择一些文本并调用 M-x org-ai-talk-read-region
来测试它。
设置 Stable Diffusion
可以使用 stable-diffusion-webui 项目托管一个 Stable Diffusion API。按照 你的平台的安装步骤,然后启动一个仅限 API 的服务器:
cd path/to/stable-diffusion-webui
./webui.sh --nowebui
默认情况下,这将在 http://127.0.0.1:7861 启动一个服务器。要将其用于 org-ai,你需要设置 org-ai-sd-endpoint-base
:
(setq org-ai-sd-endpoint-base "http://localhost:7861/sdapi/v1/")
如果你使用的是托管在其他地方的服务器,请相应地更改该 URL。
使用 oobabooga/text-generation-webui 运行本地 LLM
自 0.4 版起,org-ai 支持使用 oobabooga/text-generation-webui 运行本地模型。请参阅 安装说明 以在你的系统上设置它。
这里是一个在 Ubuntu 22.04 上测试的安装步骤。假设已经安装了 miniconda 或 Anaconda 以及 git-lfs。
第一步:设置 conda 环境并安装 pytorch
conda create -n org-ai python=3.10.9
conda activate org-ai
pip3 install torch torchvision torchaudio
第二步:安装 oobabooga/text-generation-webui
mkdir -p ~/.emacs.d/org-ai/
cd ~/.emacs.d/org-ai/
git clone https://github.com/oobabooga/text-generation-webui
cd text-generation-webui
pip install -r requirements.txt
第三步:安装语言模型
oobabooga/text-generation-webui 支持 多个语言模型。通常,你可以从 huggingface 安装它们。例如,要安装 CodeLlama-7b-Instruct
模型:
cd ~/.emacs.d/org-ai/text-generation-webui/models
git clone git@hf.co:codellama/CodeLlama-7b-Instruct-hf
第四步:启动 API 服务器
cd ~/.emacs.d/org-ai/text-generation-webui
conda activate org-ai
python server.py --api --model CodeLlama-7b-Instruct-hf
根据你的硬件和使用的模型,你可能需要调整服务器参数,例如使用 --load-in-8bit
来减少内存使用,或使用 --cpu
如果你没有合适的 GPU。
现在,你应该能够通过在 #+begin_ai
块中添加 :local
选项来使用本地模型:
#+begin_ai :local
Hello CodeLlama!
#+end_ai
常见问题
这是 OpenAI 专用的吗?
不是,OpenAI 是最容易设置的(你只需要一个 API 密钥),但你也可以使用本地模型。请参阅上面关于如何使用 Stable Diffusion 和 oobabooga/text-generation-webui 运行本地 LLM 的说明。还支持 Anthropic Claude 和 perplexity.ai。如果你希望支持其他服务,请提出问题或 PR。我可能会响应较慢,但如果有足够的兴趣,我会添加支持。
是否有类似项目?
gptel 包提供了一个 OpenAI ChatGPT API 的替代接口:https://github.com/karthink/gptel
赞助
如果你发现这个项目有用,请考虑 赞助。谢谢!
Footnotes
-
注意: 当前的图像变体实现需要安装命令行工具 curl。原因是 OpenAI API 需要 multipart/form-data 请求,而 Emacs 内置的
url-retrieve
不支持该请求(至少我还没有找到方法)。切换到request.el
可能是一个更好的选择。如果您有兴趣贡献,欢迎提交 PR! ↩