Emacs + AI 折腾日志

Table of Contents

安装 gptel 获得基本的 emacs gpt 能力 https://github.com/karthink/gptel

基本使用过程

  1. 使用命令: gptel 开启一个聊天的 buffer ,直接打文字
  2. 在 gptel 的 buffer 下,使用命令 gptel-menu 后可以打开命令行,使用 RET 就可以发送事件 或者也可以使用命令 C-c RET 直接执行 gptel-send 发送指令

gptel 的模式其实就是一个 markdown mode 的模式,然后在这个基础上增加了菜单 这个菜单可以通过切换模型:比如 gpt-3.5-turbo ,然后就可以发命令了

基本使用过程(在 org mode 中指导一个话题)

其实默认的 gptel-mode 下就是一个类似 org-mode 的方式进行消息发送。 在 org mode 下最简单的方式也可以直接 gptel-send 一个例子,我写如下一段话,然后直接调用 gptel-send :

我在使用 emacs 以及使用了 gptel 这个插件来调用 openai 的 api ,我怎样简单的把这个工具集成到 org-mode 中让他指导我的文档写作

gptel 能给我直接返回:

To integrate gptel into org-mode for guiding document writing:
1. Use 'gptel-send' in gptel-mode or org-mode to interact with OpenAI's API for guidance.
2. Consider customizing gptel for org-mode to streamline the integration.

增加额外的 context 信息,则需要使用 gptel-menu 来增加。 另外也可以使用 C-c u 放在 gptel-send 之前,就能定制某次发送的特殊字段,包括

  1. 选择使用 gpt model
  2. 只应用在下一次 send 时的指令
  3. 从另处读取 prompt 或把结果输出到别的地方
  4. 直接把 prompt 替换为 response 的操作

另外默认上下文是包含全部上下文的,在 gptel-menu 中我可以设置只附加几条,我设成了4

快速尝试

如果我需要解释一段代码的作用,我可以先选中代码,使用 C-u M-x gptel-send ,设置 System prompt 为 "请帮我解释如下代码:" ,并把 prompt from 改成 minibuffer ,把 response to 改成了 echo ,回车后, gptel 帮我完成了解释

如果不使用 minibuffer 作为 prompt from 的选项,则他会直接发送

在 org mode 中使用

在 org-mode 中的话,可以通过 gptel-org-set-topic 的方式,把话题限制在当前 org head 中

把 gptel 添加到 embark 指令中

基本想法:在一些常见的 embark 模式中,比如 embark-expression-map 中,绑定一些函数,这些函数主动触发 gptel 的方法,以实现查询

https://github.com/karthink/gptel/wiki/Defining-custom-gptel-commands

(defun gptel-explain-code (bounds &optional directive)
    "Send the selected code from expression to GPT for explanation."
    (interactive
     (list
      (cond
       ;; if it's a region
       ((use-region-p) (cons (region-beginning) (region-end)))
       ;; if it's in text mode, get sentence at point
       ((derived-mode-p 'text-mode)
        (list (bounds-of-thing-at-point 'sentence)))
       ;; otherwise get the line
       (t (cons (line-beginning-position) (line-end-position))))
      (and current-prefix-arg
           (read-string "ChatGPT Directive: "
                        "请帮我总结和解释这段代码的作用。"))))
    (gptel-request
        (buffer-substring-no-properties (car bounds) (cdr bounds)) ;the prompt
      :system (or directive "请帮我总结和解释这段代码的作用。")
      :buffer (current-buffer)
      :context (cons (set-marker (make-marker) (car bounds))
                     (set-marker (make-marker) (cdr bounds)))
      :callback
      (lambda (response info)
        (if (not response)
            (message "ChatGPT response failed with: %s" (plist-get info :status))
          (with-current-buffer (get-buffer-create "*gptel-lookup*")
            (let ((inhibit-read-only t))
           (erase-buffer)
           (insert response))
            (special-mode)
            (display-buffer (current-buffer)
                            `((display-buffer-in-side-window)
                              (side . bottom)
                              (window-height . ,#'fit-window-to-buffer)))))))

    )

然后把这个方法绑定,比如

(define-key embark-region-map (kbd "0") 'gptel-explain-code)

例子里还有其他代码,包括如何解析一个 url 并总结他的内容,都是值得学习的。

项目: https://github.com/kamushadenes/gptel-extensions.el 有许多实现也可以作为学习对象

TODO 调整实现,只对 prog 模式启用,在其他模式下不启用

TODO 学习 gptel-quick 使用 postframe 显示提示内容

TODO 增加多个 buffer 或 region 以帮助分析代码作用

TODO 试试其他模型,比如 claude

使用 ai 做编程指导

如何交互式的去优化一段代码,比如说,我先选中一段代码,问 gpt 他的作用,然后在上下文中,继续追问我要如何修改,以达到我的某种目的,然后逐渐完善我的代码,最好问答记录都能存下来,以便我反复的问同一段代码

使用 elysium 写代码

https://github.com/lanceberge/elysium

快速使用: 打开任何一个代码文件,可以选中需要调整的部分,也可以不选则为整个 buffer ,然后调用 elysium-query 输入要求,就能自动生成修改。 生成修改后,可以用 smerge-keep-upper 或者 smerge-keep-lower 来选择使用哪个版本的代码。 代码都可以开启 smerge-mode 这样会有高亮。

使用 magit 自动生成 commit 信息

https://github.com/douo/magit-gptcommit 这个库不好用,因为依赖外部库,而 emacs 的依赖处理不好,无法做到我的依赖只依赖我的版本, gptel 本身一升级, magit-gptcommit 就不能用了

后来换成了 https://github.com/ywkim/gpt-commit 用起来就比较简单好用,不需要复杂的配置。本身 commit 信息的生成任务比编码要简单,这里就用一个独立的库而不是依赖 gptel 来使用

2024-12-14_21-48-13_screenshot.png

这个自动总结的 commit 信息还是有点啰嗦,后续可以看一下如何优化

使用 ai 指导做一个博客自动发布流程的 el 脚本

参考过程 https://emacs-china.org/t/org-mode-ox-publish/13869 https://emacs-china.org/t/advice-ox-publish-org-roam/26973

这个过程也可以引入到: 一个笔记系统的思考

实现功能:

  1. 本地图片会放在一个固定文件夹下,使用 org-download 这样的机制
  2. 在 ox publish 时,扫描当前 page ,提取出所有图片,并上传 cdn ,在最终文件中替换成 cdn 地址
  3. 如果某个文件已经被上传过,或 hash 没改变,则不上传
  4. 添加 ga 信息,生成索引文件和 rss 文件
  5. 将文件发布到 github 上

    以上处理只针对带有 blog 和 publish tag 的帖子

    我创建一个 my-ox-publish.el 文件,让 elysium 按我的描述反复修改和生成这个代码

Author: gsj987

Publish Date: 2025-02-04 Tue 15:26

License: CC BY-NC 4.0