おはようございます。マイクです。FMラジオ「zenncast」、お届けしていきます。
今日は2025年12月12日、金曜日の朝7時台。みなさん、いかがお過ごしでしょうか。通勤・通学中の方も、おうちで支度しながらの方も、ちょっと耳だけ貸していただければうれしいです。
この番組では、技術情報プラットフォーム「Zenn」で、今日トレンドになっている記事をピックアップしてご紹介していきます。
今日は全部で5本、ご紹介していきます。どれも「ちょっと人に話したくなる」内容になってますので、気になったものがあったら、あとでショーノートから原稿や元記事をチェックしてみてください。
ではさっそく、今日紹介する内容、1本目からいきましょう。
……。。
1本目は、C言語の記事です。タイトルは「アスタリスクはもう古い!?モダンC言語でのポインター型の記法」。
Cを書いている方なら、一度はモヤっとしたことがあるかもしれません。`int *a, b, c;` って書いたとき、「あれ?ポインタなのは結局どれなんだっけ?」ってなるやつですね。実はアスタリスクは「型」じゃなくて「変数」側にひっつく仕様なので、複数宣言すると直感に反する書き心地になっちゃう。さらに関数ポインタや配列ポインタが絡んでくると、宣言が暗号みたいになってきて、`signal` のシグネチャなんかは、初見だと完全にパズルです。
そこで登場するのが、C23で導入された `typeof` 演算子。式だけでなく型名からも型を取り出せるので、`typeof(int *) a, b, c;` のように書くと、「全部ポインタです」と素直に宣言できる。さらに `#define Ptr(T) typeof(typeof(T) *)` みたいなマクロを用意してあげると、`Ptr(int) a, b, c;` とか、`Ptr(void (int)) signal(int, Ptr(void (int)) func);` みたいに、あの読みにくかった関数ポインタ宣言もだいぶマシになるよ、という提案なんですね。
筆者の方自身は「この `Ptr` マクロが実務でバリバリ使われるかは微妙」と冷静に見つつも、「複雑な型を扱うときに `typeof` を知ってると視界が開けるよ」と知識としての価値を強調しています。C23での `typeof` 導入の経緯とか、関数ポインタを読みやすくしようという提案、さらには `_Typeas` という派生案まで触れられていて、「古典C」と「これからのC」の橋渡しになるような内容。
長くCを書いてきた方も、これから触る方も、「あのアスタリスク問題」にちょっと新しい視点が得られる記事になってます。
……。。
続いて2本目は、開発者の日本語入力まわりの悩みに切り込んだ記事です。
タイトルは「生成AI時代だからこそ、Vim as an IME」。
日本語のIMEって、実はかなりクセ者ですよね。仕様も複雑だし、LinuxでGUI環境を作るときなんかは、IMEとアプリの相性問題で地獄を見ることもある。結果として「このアプリ、日本語入力できないんだけど…」っていう場面、開発者なら何度か遭遇しているんじゃないでしょうか。
そこで筆者が提案しているのが、いっそIMEをあきらめて、「VimをIME代わりにする」という戦略的撤退。テキストを入力したいときは、まずNeovim上のプラグインで一時バッファに日本語を書く。それをコピペして済ませちゃう、という割り切り方です。パッと聞くと「なんか時代に逆行してない?」と思うんですが、ここで効いてくるのが「生成AI時代」というポイント。
Neovim上なら、GitHub CopilotみたいなAI補完をそのまま日本語入力でも活用できますし、辞書もdotfilesとしてGit管理できる。OSごとに違うIMEの挙動に振り回されることもなくて、WindowsでもmacOSでもLinuxでも、同じ操作感で日本語が打てるようになる。
さらに「Firenvim」という拡張を使うと、ブラウザのテキストエリアを丸ごとNeovimでオーバーレイできて、`:w` したタイミングで内容がフォームに反映される。つまり、Webフォームの入力も、ほぼネイティブIMEと同じ感覚で「Vim as an IME」ができちゃうんですね。見た目も設定次第でWebと馴染むようにカスタマイズ可能。
「技術的には一歩引いているようで、実はAIやポータビリティの面では前に進んでいるかもしれない」というおもしろい提案になっています。Vimmerな方はもちろん、「IMEにうんざりしてる」という方にも刺さる内容です。
……。。
3本目は、大人気テーマ「Transformer」を歴史の流れで捉え直す記事です。
タイトルは「テセウスのTransformer」。
2017年の「Attention is All You Need」で登場したオリジナルTransformerと、いまLLMで「Transformer」と呼んでいるもの、実はかなり別物になっているよね、というお話です。
まず大きいのが、Residual接続と正規化(LayerNorm)の位置。元々はPost-LN、つまり「ブロックのあとに正規化」する形でしたが、これだと層を深くすると勾配がうまく伝わらず、学習が安定しにくい。そこで、最近のLLMではPre-LN、つまり「入力側で正規化」が主流になっている。
正規化そのものも、LayerNormからRMSNormに置き換えられていて、平均の計算を省くことで高速化を図っているモデルが多いです。
さらにFFNの活性化関数も、最初のReLUから、GeLU、そしてSwiGLUへと進化。SwiGLUはパラメータの使い方が効率的で、精度面でも有利とされていて、最近のモデルではかなり採用が増えています。
Self-Attentionの計算量削減についても、研究レベルではいろんな手法が出ているものの、実際の大規模LLMで広く採用されているのはごく一部で、その代表がGrouped-Query Attention。
位置情報の扱いも、昔ながらの「埋め込みに単純に足し込む絶対位置」から、RoPEのようにAttention内部でうまく扱う相対位置表現が主流になってきて、長文での性能が大きく変わっています。
こうして部品が少しずつ入れ替わっていきながらも、私たちはそれをずっと「Transformer」と呼び続けている。ここを「テセウスの船」のパロディで、「テセウスのTransformer」と名づけて、「もしAttention自体が全く別のものに置き換わったら、それもTransformerと呼んでいいのか?」と問いかけているのが、この記事の面白いところです。
LLMを日々触っている方でも、「そういえば2017年の原型と、今のモデルってどこが同じでどこが違うんだっけ?」を整理したい人には、とても良い道しるべになる内容だと思います。
……。。
4本目は、現場エンジニアが知っておきたいオブザーバビリティのお話。
タイトルは「New Relic Go Agent 完全理解・実践導入ガイド」。
New Relicは、アプリケーションのパフォーマンス監視やログをまとめて扱える基盤で、そのGo向けエージェントを、実際の導入まで含めて徹底的に解説している記事です。
Goは静的コンパイルの言語なので、Javaみたいに「全部自動で計装してトレース取ります」というのが難しい。そこでNew Relic Go Agentでは、「通信境界の計装」と「個々の関数をどうトレースするか」という二本柱で設計されています。キーワードになってくるのが、Application / Transaction / Segment という3つの構造体。これを押さえると、「今どの単位で計測しているのか」「どこまでが1リクエストなのか」が見通しやすくなります。
Logs in Context という仕組みを使うと、ログにトレースIDやスパンIDを自動で紐づけられるので、あとから「このエラーの裏側のリクエスト、何が起こってたんだっけ?」を追いやすくなる。nrwriter、nrslog、zerologWriterなどを通じて、普段使っているロガーと統合できる点も丁寧に解説されています。
HTTPサーバでは、echoフレームワークにnrechoミドルウェアを挟んで、zerologのコンテキストと連携する設計例が紹介されていて、「手元のプロジェクトにどう組み込むか」がかなり具体的にイメージできます。バッチ処理では、urfave/cliのBeforeやActionをラップして、トランザクションの開始・終了とログの紐づけを行う方法も載っていて、「WebだけじゃないGoアプリのトレーシング」にも踏み込んでいるのがうれしいところです。
エラー通知は、明示的な通知、HTTPステータス、panicの捕捉という3ルートがあって、スタックトレースをちゃんと出してくれるライブラリを使うのがオススメ、といった実務寄りのTipsも満載。Goroutine周りでは、同じトランザクションを複数のゴルーチンで共有すると、Segmentの終了順序の制約で怒られてしまうので、NewGoroutineで派生トランザクションを作るか、レスポンス後処理は完全に別トランザクションにして、分散トレーシングでつなぐ、といった実践的な設計指針も紹介されています。
さらに、内部ロガーが大量エラーを吐いてログを汚さないよう、スロットリングロガーで抑制する実装例や、「人の注意力に頼らずに計装漏れを防ぐためにLinterも入れていこう」といった、現場視点ならではの締め。将来的なOpenTelemetryへの移行も見据えつつ、「今New Relic Go Agentをきちんと扱えるノウハウは十分価値があるよ」として、かなり腰の据わったガイドになっています。
……。。
そして最後、5本目は、今日の原稿づくりにも関わる(かもしれない)メタなお話です。
タイトルは「CLAUDE.mdの肥大化を防ぐ!.claude/rules/で動的にルールを読み込む方法」。
Claude Codeを使っていると、プロジェクトルールを全部CLAUDE.mdに書きたくなりますよね。「こういう命名で」「こういうディレクトリ構成で」「テストはこう書いて」…と詰め込んでいくと、ファイルがどんどん太っていきます。そうすると、起動時に毎回その大きなファイルがコンテキストに読み込まれて、肝心のコードや会話に割けるトークンが減ってしまう、という問題が出てくる。
そこで役に立つのが、`.claude/rules/` ディレクトリの仕組みです。ルールをトピックごとに小分けにして配置しておき、各ファイルの先頭にYAMLフロントマターを書いておきます。この中の `paths` というフィールドで、「このルールは、どのファイルを触っているときに読み込んでほしいのか」を指定できる。
`paths` の指定がないルールは「常に読み込む」グローバルルールとして扱われて、`paths` があるものは、該当するファイルを操作しているときだけ動的にロードされる。しかも、一度ロードされたルールは再読み込みされないようになっていて、「同じルールが何度もコンテキストを圧迫する」ことがないよう配慮されています。
検証の中では、複数ルールが同時に適用されるケースや、コンテキストが実際にどれぐらい増えるのか、同じルールが重複ロードされないか、といった挙動も確認されていて、安心して使える設計になっていることが分かります。
活用の仕方としては、「フロントエンド専用ルール」「バックエンド専用ルール」「テストコード専用ルール」「ドキュメント専用ルール」といった風に、局所的な規約を `.claude/rules/` 以下に分割。1ファイル1トピックを意識しておくと、あとから見返しやすいですし、サブディレクトリで整理しておくと大規模プロジェクトでも破綻しづらくなります。`paths` はあまり欲張って全てにつけるのではなく、「本当に限定したいルール」にだけ使うのがコツ、とも書かれています。
結果として、CLAUDE.mdはスリムなままキープしつつ、「必要な時に、必要なルールだけ」をコンテキストに載せられる。このバランスを取るテクニックとして、Claude Codeを本気で使い込んでいる人にはぜひ知っておいてほしい内容です。
……。。
というわけで、今日のzenncastでは、
1本目「モダンC言語のポインター記法と、C23のtypeofで可読性を上げる話」、
2本目「日本語IME沼から抜け出す、Vim as an IME戦略」、
3本目「オリジナルから現在まで、Transformerはどこまで同じでどこから別物か」、
4本目「New Relic Go Agentを使ったGoアプリの実践的な監視とトレーシング」、
5本目「CLAUDE.md肥大化を防ぐ、.claude/rules/による動的ルール読み込み」
この5本をご紹介してきました。
気になった記事があれば、詳しい内容は番組のショーノートにメモを残しておきますので、あとでゆっくり読んでみてください。
また、このzenncastへの感想や、「こんなテーマも取り上げてほしい!」というリクエストも、どしどしお待ちしています。あなたの一言が、次回のラインナップを変えるかもしれません。
それでは、そろそろお別れの時間です。
今日も一日、無理せず、でもちょっとだけワクワクすることがありますように。
お相手はマイクでした。次回のzenncastで、またお会いしましょう。