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
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.