← 記事一覧へ
AI生成画像

LLMはどう動くか:次のトークンを予測する仕組み

トークン、確率、温度、コンテキストウィンドウ。おもちゃのモデルを動かしながら、LLMが答えを作る流れと、間違える理由を整理する。

AI作成 · 約9分 · JavaScriptが読めれば十分
LLMトークン基礎
この記事で扱うこと

LLMは「次のトークンを確率で選ぶ」ことを繰り返して文章を作ります。この仕組みから、温度、コンテキスト、間違い方の理由が説明できます。

LLMがしていること

大規模言語モデル(LLM)は、大量のテキストで学習した、パラメータの多い言語モデルです。土台になる事前学習では、文書の中で「これまでの文脈から、次の単語を予測する」ことを学びます。事前学習しただけのモデルは、質問に答えたり指示に従ったりするのが得意ではありません。そこで、追加のデータでさらに学習するファインチューニングや、人間の好みに沿わせるRLHFで、アシスタントとして使いやすく整えます。Claudeもこの流れで作られています(公式の用語集による)。この記事は、2026年10月時点の公式ドキュメントに基づきます。

以下は仕組みを理解するための単純化です。実際のモデルの内部構造は、この記事では扱いません。

トークン:文字でも単語でもない単位

モデルは、文字や単語そのものではなく、トークンという単位で文章を扱います。トークンは単語、単語の一部、文字、バイトなどに対応し、1トークンが何文字にあたるかは、モデルと言語によって変わります。公式の用語集によると、Claude 4.7以降のモデルは新しいトークナイザーを使い、同じ文章でも以前のモデルより約30%多くのトークンになります。正確な数は、使うモデルでトークン数を数えるAPIで確かめます。手元の計算では数えられないので、この記事では日本語や英語の具体的なトークン数を載せません。

  • 料金は、入力と出力のトークン数で決まる
  • コンテキストウィンドウの大きさも、トークンで数える
  • 同じ内容でも、言語によってトークン数が違う

次の1語を、確率で選ぶ

LLMは、これまでのトークンを入力にして「次に来るトークンの確率」を計算し、そこから1つを選びます。選んだトークンを足して、また次を計算する。この繰り返しで文章ができます。形だけを確かめるために、直前の1語だけから次の語を予測する、おもちゃのモデルを書きました。短い文章で「ある語の次に、どの語が何回続いたか」を数え、それを確率にします。実際のLLMは、直前の1語だけでなく文脈全体を使って確率を計算します。ここでの学習は、数えているだけです。コードは、JavaScript版とPython版をタブで切り替えて読めます。どちらも同じ乱数の式を使っているので、出力は一字一句同じです(筆者がNode.js 26.1.0とPython 3.11.5で実行して確認)。

トークンを1つずつ足して文章を作る流れ1これまでのトークン2次のトークンの確率を計算3温度で偏りを調整して1つ選ぶ4選んだトークンを末尾に足す繰り返す
図1 LLMは、これまでのトークンから次のトークンを選び、末尾に足す、という繰り返しで文章を作る。
toy.py(同じ計算をPythonで)
# 次の単語を「直前の1語」だけから予測する、おもちゃの言語モデル(toy.mjs と同じ計算を Python で書いたもの)。
corpus = """
the model reads the text and predicts the next token .
the model predicts the next word from the context .
the context holds the text the model can see .
the answer looks plausible and the answer can be wrong .
the next token is chosen from a list of probabilities .
""".split()

# 1. 学習: 「ある単語の次に、どの単語が何回続いたか」を数える
counts = {}
for a, b in zip(corpus, corpus[1:]):
    counts.setdefault(a, {})
    counts[a][b] = counts[a].get(b, 0) + 1


# 2. 確率: 回数を、温度付きの確率に直す(温度が低いほど、一番多い単語に集中する)
def probabilities(word, temperature=1):
    words = list(counts[word].items())
    weights = [n ** (1 / temperature) for _, n in words]
    total = sum(weights)
    return [(w, weight / total) for (w, _), weight in zip(words, weights)]


# 3. 生成: 確率に従って次の単語を引く。乱数は固定の種で、何度実行しても同じ結果になる
def rng(seed):
    state = seed & 0xFFFFFFFF

    def random():
        nonlocal state
        state = (state + 0x6D2B79F5) & 0xFFFFFFFF
        t = ((state ^ (state >> 15)) * (1 | state)) & 0xFFFFFFFF
        t = ((t + (((t ^ (t >> 7)) * (61 | t)) & 0xFFFFFFFF)) & 0xFFFFFFFF) ^ t
        return ((t ^ (t >> 14)) & 0xFFFFFFFF) / 4294967296

    return random


def generate(start, temperature, seed, length=12):
    random = rng(seed)
    out = [start]
    while len(out) < length and out[-1] in counts:
        r = random()
        for w, p in probabilities(out[-1], temperature):
            r -= p
            if r <= 0:
                out.append(w)
                break
    return ' '.join(out)


for t in [0.5, 1, 2]:
    print(f'温度 {t}:', ', '.join(f'{w} {p * 100:.1f}%' for w, p in probabilities('the', t)))

# 「the」の次に、最頻の単語(model か next)が選ばれる割合を、2000回の抽選で確かめる
for t in [0.2, 1, 3]:
    random = rng(42)
    top = 0
    for _ in range(2000):
        r = random()
        for w, p in probabilities('the', t):
            r -= p
            if r <= 0:
                if w in ('model', 'next'):
                    top += 1
                break
    print(f'温度 {t}: 最頻の単語が選ばれた割合 {top / 20:.2f}%')
print('例(温度0.2):', generate('the', 0.2, 1))
print('例(温度3):', generate('the', 3, 1))
2回分の生成の実例1回目入力:the次の語の確率model25.0%← 選ばれたnext25.0%answer16.7%context16.7%text16.7%選んだ語を足して、次の入力にする2回目入力:the model次の語の確率can33.3%predicts33.3%← 選ばれたreads33.3%これを繰り返して、文章になる
図2 記事のおもちゃのモデルの、実際の確率。どの語が選ばれるかは確率で決まるので、毎回同じとは限らない(この例では model、predicts が選ばれた)。

温度:選び方の偏りを調整する

上のコードを実行すると、次の結果になります(筆者がNode.js 26.1.0で実行して確認。乱数の種を固定してあるので、何度実行しても同じ結果です)。

実行結果
温度 0.5: model 30.0%, text 13.3%, next 30.0%, context 13.3%, answer 13.3%
温度 1: model 25.0%, text 16.7%, next 25.0%, context 16.7%, answer 16.7%
温度 2: model 22.5%, text 18.4%, next 22.5%, context 18.4%, answer 18.4%
温度 0.2: 最頻の単語が選ばれた割合 83.30%
温度 1: 最頻の単語が選ばれた割合 51.25%
温度 3: 最頻の単語が選ばれた割合 43.85%
例(温度0.2): the next token is chosen from the next token . the text
例(温度3): the context . the answer can see . the next word from
温度ごとの、「the」の次の単語の確率温度 0.5多い語に集まるmodel30.0%text13.3%next30.0%context13.3%answer13.3%温度 1回数どおりmodel25.0%text16.7%next25.0%context16.7%answer16.7%温度 2差が縮まるmodel22.5%text18.4%next22.5%context18.4%answer18.4%濃い色:最も多い語(model と next)
図3 「the」の次の単語の確率(本文の実行結果と同じ数値)。温度を下げると多い語に集まり、上げると差が縮まる。

「the」の次は、modelとnextが各3回、残りが各2回です。温度1では、回数どおりの確率(25%と16.7%)になります。温度を下げると、多い語に確率が集まります(温度0.5で30%)。温度を上げると、差が縮まります(温度2で22.5%)。2000回の抽選で、最頻の語が選ばれた割合は、温度0.2で83.30%、温度1で51.25%、温度3で43.85%でした。理論値(83.5%、50.0%、43.3%)に近い値です。公式の用語集の説明も同じ向きで、温度が高いほど多様な出力になり、低いほど最も確からしい語に寄ります。生成例では、温度0.2は元の文章をほぼなぞり、温度3は元にない組み合わせ(the answer can see)が出ました。

温度を0にしても、APIの結果が完全に同じになるとは限りません。同じ入力でも、呼び出しごとに出力が変わることがあります(公式の用語集)。

温度を、動かして確かめる

スライダーを動かすと、「the」の次の単語の確率が、記事のおもちゃのモデルと同じ式で、その場で計算されます。サイコロを振ると、実際の出方も見られます。振った回数が増えるほど、出方が理論値に近づきます。

この部品は、JavaScriptが必要です。

コンテキストウィンドウ:作業用の記憶

コンテキストウィンドウは、モデルが応答を作るときに参照できるテキスト全体で、いわば「作業用の記憶」です。学習に使った大量のデータとは別のものです。ここには、システムプロンプト、これまでのすべてのメッセージ、ツールの結果、画像や文書が入り、モデルが生成する出力も含まれます。会話が進むほど、前のやり取りがすべて積み重なります。大きさはモデルによって違い、2026年10月時点のドキュメントでは、多くの現行モデルが100万トークン、それ以外は20万トークンです。

コンテキストウィンドウの中身と、会話が進んだときの変化最初のやり取り上限 |会話が進んだあとシステムプロンプトとツールの定義これまでの会話(すべての発言)ツールの結果、画像、文書今回の出力(これも数える)空き(なくなると上限に達する)
図4 コンテキストウィンドウには、入力だけでなく出力も入る。会話が進むほど履歴が積み重なり、空きが減る。割合は説明用の概念図で、実際の値ではない。
  • 大きければ良いとは限らない。トークンが増えるほど精度と再現率が下がる「コンテキストロット」が起きる(公式)
  • 入力だけで上限を超えると、APIは400エラー(prompt is too long)を返す
  • Claude 4.5以降のモデルでは、入力とmax_tokensの合計が上限を超えても受け付け、生成が上限に達した時点で止まる(stop_reason: model_context_window_exceeded)

Claude Codeで、長い作業のあとに指示が守られにくくなるのは、このためかもしれません。必要なものだけを文脈に残す(新しいセッションにする、調査を別の文脈に逃がす)のが対策です。

なぜ間違えるのか

LLMは、事実を調べて答えているのではなく、文脈に続く確からしいトークンを選んでいます。そのため、もっともらしいのに事実と違う文章(ハルシネーション)が出ることがあります。公式は、どれほど進んだモデルでも起こりうるとしています。おもちゃのモデルでも、元の文章にない組み合わせが、確率どおりに出ました。仕組みとして、起こりうることです。公式が挙げる軽減策は、次のとおりです。

  • 分からないときは「分からない」と言ってよいと、はっきり伝える
  • 長い文書では、先に原文の引用を抜き出させて、その引用だけを根拠に答えさせる
  • 主張ごとに、根拠になる引用を探させる。見つからなければ撤回させる
  • 同じ質問を複数回して、答えのずれを見る(Best-of-N)
  • 提供した文書の情報だけを使うよう指示する

これらで大きく減らせますが、なくせるわけではありません。重要な情報は、必ず自分で確かめてください(公式)。

仕組みから、使い方を決める

ここまでの仕組みから、使い方の原則が出てきます。

  • 必要な情報は、文脈に入れる。モデルが知っているはずと決めつけない(学習データと文脈は別)
  • 貼った情報は文脈に入る。秘密のキーや個人情報は、取り除いてから共有する
  • 同じ依頼でも、答えは変わりうる。結果は毎回確かめる
  • 長い会話は、品質が落ちる前に区切る

具体的な使い方は、Claude Codeの記事(始め方、CLAUDE.md、権限、ワークフロー)で扱っています。

おもちゃのモデルとの違い

確率で次を選ぶ、温度で偏りを変える、という形は、実際のLLMと同じです。違うのは、確率の計算です。

このおもちゃのモデル実際のLLM
次の予測に使う情報直前の1語だけ文脈全体
学習回数を数えるだけ大量のテキストで事前学習し、ファインチューニングとRLHFで調整
扱う単位学習文に出た語だけトークン(単語の一部や文字も含む)
知らない語扱えない(確率がない)小さなトークンの組み合わせで扱える(公式の用語集)

確率を計算している部分の中身は、Transformerの中身をのぞくで、図とコードで確かめています。

公式リファレンス

Claude Docs — Glossary ↗Claude Docs — Context windows ↗Claude Docs — Reduce hallucinations ↗
PAIBOT / DEVELOPMENT JOURNAL記事一覧に戻る →

知りたいことを探す

タイトル・タグ・本文から検索 esc で閉じる