年の瀬に学んだ Context Engineering
前置き
実は最初は Context Engineering なんて学ぶつもりなくて、年の瀬に Claude Code の現在地確かめてみた ぐらいの記事を書くつもりでした。(これも後日書くと思う、多分...)
Claude Code の公式ドキュメントを追いながら
この辺りのナウいワードなどをキャッチアップしていたのですが、初見ではそれぞれをどう使い分ければいいのか、しっかり腹落ちするところまで理解ができませんでした。
要するに任意の要求に対して、それを達成するには Subagent でも良い気がするし、Slash commands でも良い気がする...何なら全部 CLAUDE.md に書いちゃえば情報が集約されてハッピーなんじゃないの...ぐらいの気持ちになっていたということです。
このモヤモヤが解消される感覚を得たのが Context Engineering の考え方を理解したタイミングでした。この記事を読んで、自分と同じような状態の方々が「なるほどね」という気持ちになってくれることを願ってます。
Context Engineering
Token (Tokenization)
まずトークンについてです。例えば Claude Code であれば右下の方に出ているこれです。

トークンは LLM が処理する最小単位 です。実際にウェブ上で公開されている Tokenizer を利用して 1 トークンというものを直感的に捉えてみます。
こちらの OpenAI 公式の Tokenizer を利用します。

画像の下の方には、打ち込んだ文章が虹色に色付けされていますね。これは 1 トークンが視覚化された状態になっていて、例えば hashiiiii という私のハンドルネームは hash, ii, iii 合計 3 トークンということです。
冒頭で Tokenizer について何も語りませんでしたが、Tokenizer とは与えた文章をトークン化してくれるもののことです。OSS で公開されていたりもします。
例えば Claude に対して文章を与えた際には、内部の推論プロセスで Tokenizer が利用されています。今回はこの辺りのプロセスについては言及しませんが、下記のページが非常に分かりやすかったです。
先ほどの図に戻りましょう。
例えば
hashiiiiiという私のハンドルネームはhash,ii,iii合計 3 トークン
結果を見つつ、このような話をしました。その上で思うのは 1 トークンを正確に捉えようとすることには、あまり意味がなさそう ということです。ある時は 単語 だったり 1 文字 だったり。またある時は エイヤでそのまとまり (例えば iii) を 1 トークンとしている ようです。
では、少し見方を変えるために別のプロンプトを与えて見ていきましょう。
Tokenization の傾向
まず以下の例を見てみましょう。
GPT-4o & GPT-4o mini + 日本語
先ほど利用した図です。

GPT-4o & GPT-4o mini + 英語
前述の日本語版の文章を英訳して与えたものです。

それぞれの文章がトークン化された結果を見比べてください。
- 文字数は英語が多い
- トークン数は日本語が多い
ということが分かると思います。そもそもなぜこのようなことが起こるのか、そこにも Tokenizer が深く関わっています。
この記事が最高に分かりやすいです。この記事を元に説明していきます。
文字コードと byte 数の対応

日本語 も 英語 も、全ての文字を Unicode という規格で表現することができます。
そして Unicode から UTF-8 の byte 列にエンコードする際に、言語間でサイズに差が生まれます。例えば 英語 を UTF-8 でエンコードする場合 1 byte になります。対して 日本語 を UTF-8 でエンコードする場合 3 byte になります。
Tokenizer は byte 列を見てトークン化する
英語と日本語で Hello World という文章をトークン化する際の違いを見ていきましょう。まずは日本語を。

続いて英語。

Tokenizer はトークン化する際に単語や文字列ではなく byte 列を見るのです。そのため、そもそも日本語の多くの文字 (3 bytes) と英語 (1 byte) では文字を表現するのに要するサイズが 3 倍違うので、トークン化する際に 全体的な傾向として、日本語を利用するとトークン数は膨らみやすい ということです。
例えば「世」の文字に着目してください。この文字は 1 文字にも関わらず 2 トークンとしてカウントされます。1 文字を表現するのに 3 bytes を要するということは、こういった事も起こります。
次に「こんにちは」という単語に着目してください。この単語は 15 bytes を要しますが、1 トークンとして扱われています。このように頻出の単語は 1 トークンとして扱えるよう Tokenizer (統計モデル) は日々改良されています。
Of course, different factors, such as the fact that GPT models are not trained equally on multilingual texts, influence tokenization.
また、記事中でも言われていますが、トークン化の際の言語間の差異には、そもそもの byte サイズが異なるということに加えて、英語以外の言語の学習量不足など様々な要因があるらしいです。
日本語は不利
あくまで英語と比較した際の話をしていますが、ここまで見てきたように日本語はトークン数が膨れます。
例えば金銭面について着目すると、従量課金 API はトークン単位で課金が走るのでモロに日本語は不利です。
単純に英語を使うより 2 倍とかお金がかかると考えると結構厳しいですね....
なので、API を使うような場合は英語必須になりそうです。これを意識しないで済むようにするためには定額制のサービスを利用するのが良さそうです[1]。
また、Context Engineering の文脈においてもトークン数が多くなるという性質は不利です。この辺りはこの後の解説を経て理解が出来ると思います。今はこういった性質があるということを覚えておいてください。
Context と Context Window
次は Context について書いていくのですが、これを説明するにあたって Context Window も知っておいた方が良いので一緒に説明していきます。
Claude の公式ドキュメントの解説が分かりやすいので、時間がある人はこちらの記事も見てもらうのが良いです。時間のない人向けに記事を引用しながら要点をまとめていきます。
まず、Context Window とは LLM が認識できる最大トークン数 です。この数自体はモデルによって様々でなのですが、例えば Claude Sonnet 4.5 の場合 200,000 トークンです[2]。
図を見ればより直感的に分かると思うので、前述の記事内の画像を貼ります。

上下の切り取り線の間が Context Window です。では、Context は図のどこに相当するでしょう...
Turn 1 を見てください。Input と Output と書いてあると思いますが、Input はユーザーのプロンプトです。当然添付された画像データなどもここに含まれます。Output は LLM が生成した出力です[3]。
その上で、Context とは Input + Output の和 (オレンジ四角形 + グレー四角形) に対応するトークン数 です。
続いて Turn 3 を見てください。下の方がちょん切れていますが、これは LLM との会話を続けた結果 Context Window を超えてしまうケースを表現しています。
このように Context Window を超過する場合は当然これ以上の推論が不可能なので、例えば Claude Code は、自動で Context を圧縮 します[4]。
Context サイズが増えると起こること

この図は、ある単語が繰り返し並べられている中に、別の単語を埋め込んで LLM に入力として渡し、その入力をそのまま出力させて、入力と出力を比較した結果を表しています。
つまり「apple apple apple apples apple apple ....」のようなものを入力して、出力結果と比較したということです。
縦軸は正規化されたレーベンシュタイン距離...下記の レーベンシュタイン距離とは を見ればざっくり分かります。この図だと、どれくらい入出力が一致したかを表します。
横軸は入力長をトークンサイズで表したものです。
結論として言えるのは、
Through our experiments, we demonstrate that LLMs do not maintain consistent performance across input lengths. Even on tasks as simple as non-lexical retrieval or text replication, we see increasing non-uniformity in performance as input length grows.
記事をそのまま引用しちゃいますが、LLM は入力文の長さによって性能が一貫しない ということです。図からも分かりますが、Context サイズが大きくなるほど、性能は下がる傾向を見せていますね。
次はここまでの話を踏まえて、主題である Context Engineering についてまとめていこうと思います。
Context Engineering とは
Context engineering vs. prompt engineering
この記事に完璧なアンサーが書いてあります。一旦は記事中のこの章だけでも直接見てもらった方が良い気がしますが。自分の方でもまとめてみます。
Context Engineering とは LLM が推論を行う際に、最適化されたトークンセットを選び、Context が最適化された状態を維持していく手法を指しています。
似たようなものに、Prompt Engineering というものがあります。これは最適な結果を得るための指示文の作成・構成方法のことを指します。こちらの考え方は Context Engineering に完全に内包されていると思います。
かつては Prompt Engineering の名の通り、目の前のプロンプトで最適な結果を得るために、このワンショットをいかに磨くかという部分に目を向けていたと思います。
しかし LLM との会話のターン数が増え長期間化していく中で、プロンプトも当然大切だが、いかに Context 全体を最適化していくか。この会話セッションの品質を維持していくか、という部分に目が向くようになったということです。

図でも分かるように、Context 全体を最適化するにはプロンプトだけではなく、それまでの会話の履歴、メモリファイル (Claude だと CLAUDE.md)、MCP や Subagents 等の各種ツール類。あらゆる手段を利用して Context をデザインしていくことになります。
ここまで読んで、例えば CLAUDE.md などのメモリ機能をどう書くと良さそうか想像してみてください。
自分はこれまで日本語で書いていましたが、絶対に英語で書こうと思いました。また、情報に不足の無いよう文字を敷き詰めていましたが、この辺りも出来るだけシンプルに保ち、必要なタイミングで Context に乗るようデザインすべきです。ここまで理解した上で Subagents 機能を見ると、絶対使いたいという気持ちになると思います。
まとめ
ざっくりまとめると
- Token は LLM が処理する最小単位のこと。日本語は英語と比べてトークン数が膨らみやすい。
- Context Window は LLM が認識できる最大トークン数のこと。超過すると圧縮が走り情報が抜け落ちて辛い。
- Context サイズが大きくなるほど LLM の性能は低下する傾向がある。
- Context Engineering は最適化されたトークンセットを選び、Context が最適化された状態を維持していく手法のこと。
また、以前からよく耳にしていたであろう Prompt Engineering という言葉が出てきました。こいつは「このワンショットをいかに磨くか」に焦点を当てていたのに対して、Context Engineering は「会話セッション全体の品質をいかに維持するか」というより広い視点での最適化を目指しているということが分かっていただけたと思います。
(気持ちが乗れば) 続編として、この Context Engineering の学びを踏まえて Claude Code の各種機能を実際にどう活用していくか、具体的な設計例を交えながら紹介していきたいと思います。
Discussion