Jules Robineau

TL;DR: システムを本当に理解するのは、それを再構築したときだけ。学校でTCPを再実装し、その後DNSプロトコル、ModbusをそれぞれGoで再実装し、内側から理解した。同僚もLLMで同じ経験をした。Goで小さなエージェントを書いたことで、ツールとコンテキストウィンドウを理解できた。LLMはただの、もう一つのシステムにすぎない。最小限のバージョンを作れば、ユーザーからエンジニアへ移行できる。

LLMを単に使うだけでなく、習得したい開発者向け。

同僚、Goエージェント、そして理解のきっかけ

今週、私は同僚にLLMの理解を深めてもらっている。コンテキスト、トークン、ツールについて説明する。トークンとは、モデルが読み取りカウントする小さなテキスト片だ。彼は話を聞くが、何かが腑に落ちない。

その後、彼は嬉々として戻ってきた。Goで小さなCLIを書いたのだ。モデルを呼び出し、ツールを実行する単純なチャットループだ。そして今、彼は理解している。ツール、コンテキストウィンドウ、ループについて。私の説明ではなく、自分で再構築したからだ。

私はこの理解の瞬間をよく知っている。他のテーマでも何度も感じてきた。いつも同じ方法だ。何かを理解するには、それを再構築する。

システムを理解するのは、再構築したときだけ

ドキュメントを読むのは地図を得ること。再構築するのは地形を得ること。両者は同じではない。地図は「ここに川がある」と示す。地形は流れを体感させてくれる。

システムを書き直すと、ごまかせなくなる。すべてのバイトが正しい位置に置かれなければならない。すべてのエッジケースが自分に降りかかる。理解したと思うだけでは済まない。理解するか、コードが失敗するかのどちらかだ。

これは学術的な演習ではない。むしろ逆だ。あとでより良く行動するために再構築する。より速くデバッグするため。ツールを自在に扱うため。既存のライブラリでは得られないものを構築するため。

CでのTCP:最初の実装

最初は学校で、C言語だった。TCPとUDPの一部を再実装した。有名な3ウェイハンドシェイク。そしてヘッダーのパースをフィールドごとに。

TCPは3つのメッセージで接続を開く。SYN、SYN-ACK、ACK。それまでは講義の一行にすぎなかった。それが、自分でパケットに配置したバイトになった。

何も発明したわけではない。プロトコルは40年前から存在していた。しかし再実装することで、ネットワークの見方が変わった。それ以来、パケットキャプチャは謎ではなくなった。自分で手書きしたフォーマットなのだ。

DNS:プロトコルを再実装してサブドメインを活用する

その後、DNSに取り組んだ。DNSはjrobineau.comのような名前をIPアドレスに変換する。これをGoで自分で書き直した。ヘッダー、クエリ、応答を1バイトずつ。

再構築すると、ドキュメントが軽視する詳細にぶつかる。ドメイン名は一連のラベルで、各ラベルの先頭に長さが付く。「www」は3、w、w、wとなる。

そしてアイデアが生まれた。ラベルを制御できれば、バイトを制御できる。自分のデータをサブドメインに埋め込める。それが、DNSエクスフィルトレーションの原理だ(認可されたセキュリティの文脈で)。

私のサーバーはクエリを受信し、名前をパースし、隠されたデータを復元する。名前圧縮という厄介な部分も扱った。既製のライブラリでは決して見えないものだった。再構築したからこそ見えた。

Modbus:バグの原因を特定するために再構築する

産業用ハードウェアの仕事でModbusを扱った。Modbusはコントローラやセンサーを駆動する古いプロトコルだ。使っていたライブラリは悪く、多くのバグと奇妙な挙動があった。

問題の原因がわからなかった。プロトコル?ライブラリ?私たちのコード?それを解決する唯一の方法をした。ModbusをGoで自分で再実装した。

結論:プロトコルは問題なかった。原因はライブラリだった。そしてプロトコルを再構築したことで、本当の収穫があった。自分なりの方法でツールを構築できたのだ。

それをGin風のAPIを持つ小さなGoライブラリに仕上げた。レジスタ範囲ごとにハンドラを宣言し、ロギングとリカバリミドルウェアを追加する。1979年の産業用プロトコルを、Webフレームワークのような快適さで扱えるようにした。それが知識を自分の必要に合わせて曲げるということだ。

LLMは再構築すべき、もう一つのシステム

LLMに戻ろう。2026年、AIは魔法のように売られている。話しかけるブラックボックス。そしてあなたは少し受動的で、少しその言いなりになるユーザーとして留まる。

しかしLLMエージェントは魔法ではない。それはループだ。モデルにメッセージを送る。モデルは返信し、ときにはツールを要求する。あなたがツールを実行し、結果を送り返す。そしてまた始める。

コンテキストウィンドウは、モデルが今見ているすべてだ。あなたのループが、何を入れ、何を捨てるかを決める。モデルは何も覚えていない。毎ターン過去を供給するのは、あなたなのだ。

以下がGoで書いた全体のループだ。装飾を剥がすと、残るのはこれだけだ。

func runAgent(ctx context.Context, client LLM, tools map[string]Tool, goal string) (string, error) {
    // The context window is this list. You alone fill it.
    msgs := []Message{{Role: "user", Content: goal}}

    for {
        // 1. You send the whole context to the model.
        reply, err := client.Complete(ctx, msgs, tools)
        if err != nil {
            return "", err
        }
        msgs = append(msgs, reply)

        // 2. No tool requested? The model is done, you return.
        if len(reply.ToolCalls) == 0 {
            return reply.Content, nil
        }

        // 3. You run each tool yourself, not the model.
        for _, call := range reply.ToolCalls {
            out := tools[call.Name].Run(ctx, call.Args)
            // 4. You feed the result back into the context. Loop again.
            msgs = append(msgs, Message{Role: "tool", Content: out})
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

これを書いた瞬間、恐れは消える。「エージェント」とは、このループと少数の良いツールにすぎない。ツール呼び出しとは、モデルがどの関数を呼ぶかを伝えるだけだ。それ以上のものではない。

再構築はするが、すべてを、永遠にではない

目的は、すべてを一生書き直すことではない。本番環境に自分のTCPスタックをデプロイしたりはしない。システムのものを使い、それで正しい。

一度再構築するのは、理解するためだ。その後、箱の中身を知っているから信頼する。盲目的な信頼ではなく、獲得した信頼だ。

再構築するのは、賭け金が高いときだ。製品の核となるプロトコル。頻繁にデバッグするツール。LLMのような新しい技術で、誰もが表面に留まっているとき。それが理解が報われる場面だ。

技術を再構築して学ぶためのチェックリスト

次に印象に残った技術を、ただ使うのではなく、その一部を再構築してみよう。

  • [ ] 快適さではなく核心を目指す。ベンダーAPI全体ではなく、エージェントループ
  • [ ] 小さく保つ。CLI、1ファイル、午後の時間で十分なことが多い
  • [ ] フォーマットを一度手で書く。バイトがドキュメントが隠すことを教えてくれる
  • [ ] 鍵となる詳細を探す。DNSラベル、コンテキストループ
  • [ ] 意図的に壊す。限界と落とし穴がすぐにわかる
  • [ ] ライブラリが役に立たない? 本当に問題を抱えているのが誰かを知るために再構築する
  • [ ] 理解したら、それを曲げる。既製ライブラリでは得られないツールを構築する
  • [ ] その後、おもちゃのバージョンを捨てる。本番用ライブラリに戻り、本物のメンタルモデルを持って

覚えておくべきこと

開発者の心得は変わっていない。ツールを理解せずに使うことは、その言いなりになるということ。再構築すれば、たとえおもちゃでも、コントロールを取り戻せる。

TCP、DNS、Modbus、LLMエージェント。毎回、同じ方法。再構築して理解する。理解して曲げる。LLMは単にリストの次のシステムにすぎない。

チームにLLMをトレーニングしたり、堅牢なGoバックエンドを求めているなら、それが私の仕事です。ご連絡ください。私たちはツールに苦しめられるのではなく、理解します。


Sources: RFC 1035, DNS format · RFC 9293, TCP · Modbus Application Protocol · Anthropic, Building effective agents