Welcome to Kaoru’s Blog!

We shape our tools and thereafter our tools shape us. –John M. Culkin

gpt.el & mcp.el で整う emacs llm環境

はじめに Emacs内での大規模言語モデル(LLM)との連携は、ここ数年で劇的な進化を遂げてきました。 思い返せば2022年11月、初めて copilot.el によるAI autocompletion を体験したときの感動は鮮明に覚えています。 その後間もなくChatGPT が登場し、ChatGPT.el 等でEmacs内でのAIとの対話ができるようになりましたが、当時は機能も少なく、EmacsでLLMを使うメリットはあまり感じられませんでした。 ブレークスルーとなったのは、東京Emacs勉強会 サマーフェスティバル2024 のTomoya さんの発表で ellama を知ったことでした。 ellamaでは従来の対話形式だけでなく、様々な関数を通じてLLMを利用でき、Emacs が何倍も強力な開発環境へと変貌しました。 そして最近では gptel が llm module として doom emacs に正式に組み込まれ、ツール連携やプロンプト/コンテクストエンジニアリング1が非常にスムーズになりました。 これとmcp.el と組み合わせることで、ある種 LLM in emacs のplateau を感じている今、タイミング的にちょうど良いかなと思い、この記事を書くことにしました。 gptel, mcp.el の設定方法や使う理由、補足としてmcp.el を用いる際のNixOS におけるエラー処理の方法などを紹介します。 gantt title 私のEmacs 内LLM 遍歴 todayMarker off dateFormat YYYY-MM axisFormat %Y-%m section 自動補完 copilot.el :2022-11, 32M section 黎明期 ChatGPT.el :2023-03, 17M org-ai :2023-12, 8M section 革命 ellama/llm :2024-08, 9M section 開拓期 ai-org-chat :2024-11, 2M ob-llm :2025-01, 2M elisa :2025-03, 1M copilot-chat.el :2025-03, 2M section 成熟期 gptel+mcp.el :2025-05, 2M claude-code.el :2025-06, 1M copilot-emacs/copilot.el: An unofficial Copilot plugin for Emacs. joshcho/ChatGPT.el: ChatGPT in Emacs rksm/org-ai: Emacs as your personal AI assistant s-kostyaev/ellama: Ellama is a tool for interacting with large language models from Emacs. ahyatt/llm: A package abstracting llm capabilities for emacs. ultronozm/ai-org-chat.el jiyans/ob-llm s-kostyaev/elisa: ELISA (Emacs Lisp Information System Assistant) is a system designed to provide informative answers to user queries by leveraging a Retrieval Augmented Generation (RAG) approach. chep/copilot-chat.el: Chat with Github copilot in Emacs ! karthink/gptel: A simple LLM client for Emacs lizqwerscott/mcp.el: An Mcp client inside Emacs stevemolitor/claude-code.el: Claude Code Emacs integration gptel とは gptelは、Emacsのためのシンプルかつ強力な大規模言語モデル(LLM)クライアントです。 Emacs内のあらゆる場所から自由な形式でLLMと対話できる環境を提供します。 このデモを見ると使用イメージが分かりやすいです。 ...

7月 2, 2025 · 4 分 · Kaoru Babasaki

ox-hugo で mermaid.js を使う方法

はじめに このブログは、以下のワークフローで運用されています。 graph LR org-mode -- <a href="https://ox-hugo.scripter.co/">ox-hugo</a> --> markdown -- <a href="https://gohugo.io/">Hugo</a> --> HTML 上のようなフローチャートなどのダイアグラムを載せようとすると、どのような方法が思い浮かぶでしょうか? まさか、パワポ等で作ったダイアグラムを画像としてエクスポートして…なんて方法は考えていませんよね? それ、Dティアです 図1: パワポはまじでDティア それはさておき、私はダイアグラムを作る方法について詳しくなかったので、ox-hugo を使うという前提で Gemini 2.5 Pro に、Deep research してもらいました。 結果、以下のようなTier Listができました。1 表 1: ox-hugo でのダイアグラム作成方法のTier List by Gemini 2.5 Pro & me S HugoレンダーフックによるMermaid.js A Org Babel + Hugo Kroki 純粋なOrg Babel実行 (PlantUML/Ditaa) B GUIツール (Excalidraw等) で作成し、SVG/PNG画像として挿入 レガシーなHugoショートコード C iFrame埋め込み アスキーアート (ditaa, GoAT) D 🤮 M社製品 (PowerPoint, Visio)で作成+バイナリ挿入 🤮 表で示しているように、個人的にはmermaid.js を使うのがベストです。 しかし、方法がそれほどシンプルではなく、 少し面倒だったので、書き残しておきます。 ...

6月 21, 2025 · 2 分 · Kaoru Babasaki

Hoff解答例サイト、軽量化したら(?)検索順位が上がった話🚀

TL;DR (要約) 修士のときに作り、今もめちゃくちゃスローペースで更新している A First Course in Bayesian Statistical Methods/標準 ベイズ統計学 の章末問題解答サイト。 先日、サイトを少しアップデートだけで、 Google検索で全くヒットしなかった状態から上位に出てくるようになった ので、やったことをメモします📝 サイト改善のきっかけ: 「検索結果に全く出ない」 このサイト、修士時代に修士論文の次に力を入れて作ったもので、標準ベイズ統計学の読者からの需要はそこそこにあるんじゃないかと思っていました。 ところが どんなキーワードで検索しても、 全く ヒットしませんでした😭 例えば… hoff bayes exercise 標準ベイズ 解答 などでGoogle検索しても、検索結果の 最後のページ にすら出てこない…。 図1: Google検索結果のナビゲーションバー。oの数がページ数を表すっぽい…知らなかった 順位が低いならまだしも、候補にすら挙がらないのは流石におかしいのでは?と思い、「もしかしてサイトが重すぎる…?」 と仮説を立て、軽量化してみることにしました やったことリスト🛠️ 具体的にやったことは以下の通りです。 サイト構造の大幅変更 (軽量化) Before: トップページに全章(2~10章、当時54問!)の解答を掲載 After: 各演習問題ごとにページを分割 SEO基本対策 各ページに keyword, description を追加 robots.txt を設置 (クローラーに対する指示🤖) sitemap.xml を生成・設置 (サイトの地図🗺️) 結果発表!劇的ビフォーアフター✨ サイト改善の効果は、PageSpeed Insights のスコアに如実に現れました 指標 Before 😱 After 🚀 改善度 Performance 51 97 +46 ポイント Largest Contentful Paint 1.4s 1.0s -0.4s Total Blocking Time 4,590ms 0ms -4,590ms (!!) Cumulative Layout Shift 0.195 0.011 -0.184 Speed Index 2.2s 1.0s -1.2s ユーザー補助 (Accessibility) ! 88 エラー解消! SEO ! 100 インデックス可に! Total Blocking Time が 4.5秒 もあったのが 0秒 になったのはびっくりです ...

5月 3, 2025 · 1 分 · Kaoru Babasaki

Doom Emacs & Mac へのSKK導入ガイド

この記事で分かること SKKとは何か AquaSKKのインストールと設定方法 Doom EmacsでのSKK(ddskk)の導入方法 SKK導入における障壁とその解決方法 SKKを長期間使用した感想と評価 SKKとは SKK(Simple Kana to Kanji conversion program)は、日本語入力システムの一種です。 一般的なIMEとは異なり、入力モードの切り替えが明示的で、変換候補を選ぶ際にも独特の操作方法を持っています。 特徴として: 変換時に送り仮名を明示的に指定する 辞書が自己学習し、使うほど自分専用の辞書になっていく キーボードから手を離さずに日本語入力ができる が挙げられます。 SKKとわたし 昨年8月に参加した東京Emacs勉強会 サマーフェスティバル2024 でSKKの存在を知り、そこでSKKをちょっと使ってみるも、何が良いのかわからず、いつのまにか存在を忘れる 約2ヶ月後の東京Emacs勉強会 オクトーバーフェスティバル2024 で再度SKKの話題になる。 参加者の過半数がSKKを使用しており、その空間ではSKKを使っていない方がマイノリティであることを知り、すぐにSKKを導入。全然思うように使えず、生産性が爆下がりする しかし、日本のEmacser多くの方々が使っているからには、何かしら良いところがあるはずだと考え、キーボード自体の設定を変えたりしながら、徐々にSKKに適応していく 使い始めてから5ヶ月ほど経ち、SKK関連の設定も安定。試行錯誤の結果の設定を共有したいと思いこの記事を書くに至る AquaSKKの導入 インストール Homebrewを使って簡単にインストールできます: brew install --cask aquaskk です。 nix&flake&home-managerを使っている方は、以下を適切にimportするとインストールできます: homebrew.casks = [ "aquaskk" ]; 基本設定 こういうのは基本的にデフォルトのままで使いたい派の自分ですが、日本語入力の切り替えキーだけは変えました。 AquaSKK/keymap.conf: - SKK_JMODE ctrl::j + SKK_JMODE ctrl::shift::j (理由は後述します) 設定の同期 複数のデバイス間で辞書やキーマップの設定を同期させるために、AquaSKKのディレクトリをDropboxに配置し、 ~/Library/Application Support/ 内にシンボリックリンクを作成しました: ln -s ~/Dropbox/AquaSKK ~/Library/Application\ Support/AquaSKK Macのデフォルト入力切替キー無効化 ...

4月 12, 2025 · 2 分 · Kaoru Babasaki

emacs の indirect buffer が便利だった

Emacsを使っていると、「このファイルの一部だけを別のウィンドウで編集したい…」「同じ内容だけど、表示モードを変えて見比べたい…」と思うことはありませんか? 自分は、よくありました。 そんな時に発見して感動した機能が、 Indirect Buffer です! この記事では、Indirect Bufferの基本的な概念から、使い方、注意点までを解説します。 Indirect Bufferとは? Indirect Bufferは、Emacsの特殊なバッファの一種で、別のバッファ(ベースバッファ と呼ばれます)の内容を「共有」するものです。 ファイルシステムのシンボリックリンクのようなもの、と言えばイメージしやすいかもしれません。 内容の共有: Indirect Bufferは、ベースバッファのテキスト内容(文字だけでなく、文字の色やフォントなどの テキストプロパティ も含む)を完全に共有します。一方での変更は、もう一方に即座に反映されます。 独立性: 内容は共有しますが、それ以外の点(バッファ名、カーソル位置、表示モードなど)は、Indirect Bufferとベースバッファでそれぞれ独立して設定できます。 ファイルとの関連: Indirect Buffer自体はファイルを直接開きませんが、ベースバッファはファイルを開くことができます。Indirect Bufferを保存しようとすると、実際にはベースバッファが保存されます。 Indirect Bufferの作り方 自分が調べた限りでは、 Indirect Bufferを作成する方法は、以下の3つでした。 M-x make-indirect-buffer: より汎用的な作成方法です。 ミニバッファを使って、ベースバッファとIndirect Bufferの名前を指定します。 M-x clone-indirect-buffer またはdoom emacs で SPC B c (clone-indirect-buffer-other-window または SPC B c): 現在開いているバッファをベースバッファとするIndirect Bufferを、素早く作成する方法です。 SPC B c は、新しいウィンドウでIndirect Bufferを開きます。 (org-mode内で) M-x org-tree-to-indirect-buffer (z n): 現在の subtree をIndirect Bufferとして開きます。 M-x doom/widen-indirectly-narrowed-buffer (z N)で、元のバッファに戻る 個人的には、1の方法は全く使わず、 2と3をよく使います。 手軽にIndirect Bufferを作れて、とても便利です! ...

3月 28, 2025 · 1 分 · Kaoru Babasaki

最強のAnki用単語学習Cardを作った

はじめに 皆さん、Ankiは使っていますか? Ankiは、間隔反復学習システム(SRS)を採用した、非常に強力な暗記ツールです。 私も長年Ankiを愛用しており、特に語学学習には欠かせない存在となっています。 今回、私がAnkiで英語の語彙学習をするにあたり、「こんな機能があったら最高なのに…」と思う理想のカードタイプを形にし、 GitHubで公開しました。 この記事では、そのカードタイプ「Super Vocab」の紹介と、開発の経緯、そしてAnki/Emacsユー ザーには嬉しい、 anki-editor を使ったカード作成方法について解説します。 理想の単語カードに求める機能 私が単語学習用のフラッシュカードに求める機能は、以下の5点です。 双方向学習: 単語を見て意味を答えるだけでなく、意味を見て単語を答える、両方向の学習ができること。 意味→単語カードでの例文表示: 意味から単語を答えるカードでは、定義だけでなく、例文や用例も表示すること。 理由: 単語は例文や構文とセットで覚えることで、記憶に定着しやすくなる。 同義語の微妙なニュアンスの違いを理解し、区別して覚えられる。 ただし、例文中のターゲット単語は隠したい (ここがポイント!) 理由: 答えが見えてしまうとフラッシュカードの意味がないからカードの意味がないから。 単語→意味はシンプルに: 単語から意味を答えるカードでは、単語以外の情報は極力表示しないこと。 理由: 例文などがあると、単語の意味を推測できてしまい、フラッシュカード本来の目的(想起訓練)が損なわれるため。 簡単に単語を追加でき、経験と結びつけられる: 読書などで出会った単語を、その文脈(例文)ごと簡単にカードに追加できること。 理由: 自分の経験と単語を結びつけることで、より深く記憶に刻み込むため。 柔軟な情報追加: 発音記号、品詞、関連語、語源、メモ、ヒント画像など、単語に関するあらゆる情報を簡単に追加できること。 既存のカードとの比較、そしてSuper Vocab誕生へ AnkiWebを探しても、上記の機能を全て満たすカードタイプは見つかりませんでした。 特に、2番目と3番目の要件(文脈付きの意味→単語カードで、ターゲット単語を自動的に隠す)を満たすものは皆無でした。 Ankiの標準機能であるクローズ削除(穴埋め問題)を使えば、この要件に近いものは作れます。 しかし、例文が増えるほど手作業でのクローズ削除は大変です。 「JavaScriptなどを使って、自動的に単語を隠せないか?」 そう考えていた時、English vocab (note type) という素晴らしいカードタイプに出会いました。 このカードタイプは、まさに私が求めていた自動クローズ削除機能を備えていました! しかし、惜しいことに、上記の要件を全て満たしているわけではありません。 そこで、私はこの「English vocab (note type)」をベースに、自分の理想とする機能を全て盛り込んだ、究極の単語カード「Super Vocab」を作ることにしました。 anki-editorとEmacs、立ちはだかる壁、そしてPull Requestへ 私は普段、Ankiのカード作成にanki-editorというEmacs packageを使っています。 org-modeで構造化されたノートをAnkiに簡単に取り込める、非常に便利なツールです。 Super Vocabのカードタイプも、anki-editorを使ってEmacsからAnkiに送信しようとしました。 しかし、ここで問題が発生しました。 通常、anki-editorはorg-modeのノートをHTMLに変換してAnkiに送信します。 しかし、HTMLに変換してしまうと、Super VocabのJavaScriptによる自動クローズ削除機能が動作しなくなってしまうのです。 anki-editorには :ANKI_FORMAT: nil というオプションがあり、これを使うとHTML変換を無効にできます。 しかし、このオプションは全てのフィールドに適用されてしまい、カードの見た目(HTML/CSSによる装飾)も失われてしまいます。 「特定のフィールドだけ、HTML変換せずに生のテキストとしてAnkiに送りたい…」 しかし、anki-editorにはそのような機能はありませんでした。 ...

3月 17, 2025 · 1 分 · Kaoru Babasaki

emacs起動時の、 Project … cannot be read

問題 先日、いつものようにEmacsを起動すると、mini bufferに Project <プロジェクト名> at <プロジェクトのパス> cannot be read. と表示され、emacsがただの白い画面を写すソフトウェアになってしまいました。 少し前にこのプロジェクトのパスを変更したので、そのせいかと思い、 projectile-known-projects-file にあるプロジェクトのパスを変更/削除してみましたが、状況は変わりませんでした。 doom sync や doom upgrade なども試しても、解決しませんでした。 解決策 試行錯誤の結果、原因はなんと、treemacs にあることがわかりました。 treemacsは、セッション情報を、 treemacs-persist-file (通常は user-emacs-directory/.cache/treemacs-persist)に保存するのですが、 その名の通り、treemacs_persistがpesistしていたのが原因だったようです。 そのため、 rm ~/.config/emacs/.cache/treemacs-persist # pathは環境によって異なる で解決することができます。 自分はtreemacsを入れておきながら、全然使ってなかったので、treemacsをinitファイルから削除しました。 今回は以上です。 参考 Project .emacs.d at User/x.emacs.d cannot be read. · Issue #586 · Alexander-Miller/treemacs

2月 23, 2025 · 1 分 · Kaoru Babasaki

Server julia-ls starting exited (check corresponding stderr buffer for details). Do you want to restart it? (y or n) の解決策

問題 先日久々にemacsでjuliaを使おうとしたら、 Server julia-ls:50759/starting exited (check corresponding stderr buffer for details). Do you want to restart it? (y or n) のようなmessageが(y を押しても繰り返し)出てきて、lspが起動しませんでした。 これを直すのにそこそこ時間がかかったので、emacsでjuliaを使っている方 (果たして日本に何人いるのか…) のために解決策をメモしておきます。 解決策 lsp-julia のビルド済みファイルが格納されているディレクトリの中にある Project.toml (自分の環境では ~/.config/emacs/.local/straight/build-29.4/lsp-julia/languageserver/Project.toml ) が実体のあるファイルではなく、シンボリックリンクであることが原因でした。(理由はよくわからない) そのため、シンボリックリンク先のファイル(自分の場合は /.config/emacs/.local/straight/repos/lsp-julia/languageserver/Project.toml)をコピーして、直接のファイルを同じ場所に作成することで解決しました。 参考 language server crashes · Issue #66 · gdkrmr/lsp-julia

1月 29, 2025 · 1 分 · Kaoru Babasaki

Hoffの解答例のサイトのソースコードを公開しました

Hoffの演習問題の解答例のソースコードを公開しました: GitHub このサイトはちょうど2年前に公開し、少しずつアップデートしてきたものです 今までは、間違いやtypoを見つけたらメールで連絡して欲しいとサイトに書いていましたが、結局そのような連絡は2年間で1度も来たことがありませんでした😭 (海外の研究者の方から感謝のメールをいただいたことはあり、それはとても嬉しかったです) なので、もしかしたらgithubのissueやPRだと気軽に連絡してもらえるかもしれないと思い、公開しました これからは 11章以降の演習問題の解答例を追加 日本語と英語が混在しているので、英語版と日本語版をちゃんと分ける julia で書いた教科書本文中のコードをrepoに追加 などをしていきたいと思います

1月 28, 2025 · 1 分 · Kaoru Babasaki

Advent of Code 2023 1日目

明けましておめでとうございます。 昨年の年末、とある理由で2023 のAdvent of Code をちょっとずつ解いていたので、自分の解答や、ちょっとしたメモを残していこうと思います。 なお、全部pythonで書いています。 全部解き終わったタイミングで、まとめてgithubにあげようかなと考えていますが、いつになるかはわかりません。 それでは、早速Day 1 の解答を書いていきます。 Part a 問題の概要 数字と文字が混ざった文字列が与えられる。 この文字列のそれぞれの行に含まれる最初の数字と最後の数字を取り出し、それらを結合した数値を求める。 例: 1abc2 → 12 pqr3stu8vwx → 38 a1b2c3d4e5f → 15 treb7uchet → 77 課題は、与えられた入力ファイルの全ての行について、この方法で校正値を求めて合計することである。 この例では、4つの行の校正値(12 + 38 + 15 + 77)を合計すると142になる。 My solution from fastcore.utils import L from aocd import get_data, submit import re, regex from regex import findall def get_calibration_value(x:str): digits = re.findall(r"\d", x) return int(digits[0]+digits[-1]) def solve1a(inp:str): lines = L(inp.splitlines()) return lines.map(get_calibration_value).sum() Part b 問題の概要 ...

1月 7, 2025 · 1 分 · Kaoru Babasaki