0Pricing
AI Prompt Engineering · レッスン

コンテキスト圧縮

重要な情報に絞ってコンテキストを短縮します。

「コンテキスト圧縮」はCoddyKit上の無料AI Prompt Engineeringレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Prompt Engineering学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Prompt Engineeringコースには全4レッスンが含まれています。

コンテキストを圧縮する理由

検索されたチャンクにはノイズがあります。関連するチャンクでも、大部分が定型文で、実際に重要なのは1文だけということがあります。コンテキスト圧縮は、生成モデルに渡す前に、検索テキストをクエリへの回答に実際に必要な部分だけに絞り込みます。

その効果は積み重なります。トークンコストとレイテンシーを削減し、ノイズを減らし、モデルがたどるコンテキストを小さくすることで lost-in-the-middle の影響も和らげます。

def compress(query, chunks):
    # Goal: keep only spans that bear on the query,
    # dropping boilerplate, navigation, and off-topic sentences.
    return [extract_relevant(query, c) for c in chunks]

抽出型と抽象型

抽出型圧縮は、クエリに関連するスパン(文やパッセージ)を原文どおりに選択し、正確な表現と出典情報を保持します。抽象型圧縮は言い換えや要約を行うため、より高い圧縮率を実現できますが、情報の損失や新たな誤りが生じるリスクがあります。

引用付きの事実ベースの RAG では、主張を出典まで追跡できるよう、抽出型を優先してください。抽象型は、忠実性を検証できる場合にのみ使用します。

def extractive(query, chunk):
    sents = split_sentences(chunk.text)
    scored = [(s, relevance(query, s)) for s in sents]
    kept = [s for s, r in scored if r > TAU]
    return ' '.join(kept) or top1(scored)   # never return empty

文レベルのフィルタリング

軽量で堅牢な手法です。各チャンクの各文について、小型の cross-encoder または埋め込みの類似度を使ってクエリとの関連性をスコアリングし、スコアの低い文を削除します。これにより、価値の高い文を残しながら埋め草を取り除けます。

事実の意味を与える周辺の文まで削ってしまわないよう、チャンクごとに最低限のコンテキストを残します。

def sentence_filter(query, chunk, keep_ratio=0.4):
    sents = split_sentences(chunk.text)
    scores = embed_sim_batch(query, sents)
    n_keep = max(1, int(len(sents) * keep_ratio))
    idx = sorted(range(len(sents)), key=lambda i: -scores[i])[:n_keep]
    return ' '.join(sents[i] for i in sorted(idx))  # keep original order

LLMベースのコンテキスト圧縮

LLMはチャンク単位で圧縮できます。パッセージからクエリに関連する部分だけを抽出するようプロンプトで指示し、不要部分を除いた原文どおりのチャンクを返させます。何も関連しない場合は、空のマーカーを返させます。

これは LangChain ContextualCompressionRetriever パターンです。埋め込みフィルターより正確ですが、チャンクごとにLLM呼び出しが1回追加されるため、重要度の高いパイプラインに限定するか、バッチ処理してください。

def llm_compress(query, chunk):
    prompt = (
        'Extract ONLY sentences from the passage relevant to the query. '
        'If none are relevant, output NONE. Do not paraphrase.\n'
        'Query: ' + query + '\nPassage: ' + chunk.text
    )
    out = llm(prompt, temperature=0).strip()
    return None if out == 'NONE' else out

トークンレベルのプルーニング(LLMLingua)

LLMLinguaのような手法は、小型モデルを使ってトークンの情報量を推定し、情報量の低いトークンを削除することで、トークンレベルの圧縮を行います。大規模モデルが必要とするシグナルを保ちながら、大幅な圧縮率を実現できます。

トレードオフとして、圧縮後のテキストは人間には読みにくくなります。そのため、これはユーザー向けの表示ではなく、機械だけが扱うコンテキストに適しています。

def token_prune(context, target_ratio=0.3):
    # small LM estimates per-token information (perplexity-based);
    # drop the least informative tokens down to target_ratio length
    scores = small_lm_token_importance(context)
    return keep_top_fraction(context, scores, target_ratio)

クエリ依存とクエリ非依存

クエリ依存の圧縮は、このクエリに関連する情報を残すため、最も絞り込まれたコンテキストになりますが、リクエストごとに実行する必要があります。クエリ非依存の圧縮(事前計算したチャンク要約)はリクエスト時のコストを下げられますが、特定の質問に焦点を合わせることはできません。

ハイブリッド構成では、オフラインで凝縮したチャンク版を保存し、オンラインで軽いクエリ依存のトリミングを適用します。

# Offline: precompute a dense summary per chunk (query-agnostic)
chunk.summary = summarize(chunk.text)
# Online: query-aware trim over summaries (cheap) then verify on full
ctx = [sentence_filter(query, Chunk(c.summary)) for c in top_chunks]

情報損失の防止

過度な圧縮によって、重要な唯一の節が削除されることがあります。再現率チェックで対策します。圧縮後のコンテキストから回答を依然として導けることを検証するか、圧縮結果が疑わしいほど少ない場合に備えて、圧縮前のチャンクに戻せるようにします。

再ランキング器が高い関連性と評価したチャンクを、圧縮によって空にしてはいけません。それは無関係だという意味ではなく、圧縮器の失敗を示しています。

def safe_compress(query, chunk):
    out = llm_compress(query, chunk)
    if out is None and chunk.rerank_score > 0.7:
        return chunk.text          # trust re-ranker over compressor
    return out or chunk.text

出典情報の保持

圧縮では出典の帰属を保持する必要があります。保持した各スパンにチャンクIDとドキュメントIDのタグを付け、生成モデルが引用できるようにします。メタデータを圧縮で削除すると、検証可能性と幻覚を検出する能力が失われます。

IDは構造化フィールドとしてパイプライン全体で引き継ぎ、圧縮で削られる可能性のある自由形式のテキストには決して埋め込まないでください。

def compress_with_ids(query, chunks):
    out = []
    for c in chunks:
        span = safe_compress(query, c)
        out.append({'id': c.id, 'doc': c.meta['doc_id'], 'text': span})
    return out   # generator cites id; provenance preserved

圧縮とトークン予算

圧縮すると、最終プロンプトを小さく保ちながら、再現率のためにより多くの候補を検索できます。コンテキストウィンドウのトークン予算を設定し、予算に達するまで価値の高い圧縮済みスパンを貪欲に詰め込みます。

これにより、検索量と生成に費やす量を切り離せます。これは効率を高める重要な手段です。

def pack(spans, budget_tokens, tok):
    spans = sorted(spans, key=lambda s: -s['score'])
    used, packed = 0, []
    for s in spans:
        t = tok(s['text'])
        if used + t > budget_tokens:
            continue
        packed.append(s); used += t
    return packed

圧縮品質の測定

3つの数値を追跡します。圧縮率(削減したトークン数)、回答精度(品質を維持できたか)、忠実性(圧縮器が事実を変更しなかったか)です。目標は、回答精度を変えずに達成できる最高の圧縮率です。

圧縮の強さを変えて評価し、品質を損なわずにコスト目標を満たすパレート点を選びます。

def eval_compression(eval_set, levels):
    return {
        lvl: {
            'ratio': mean_ratio(eval_set, lvl),
            'acc':   answer_accuracy(eval_set, lvl),
            'faith': faithfulness(eval_set, lvl),
        } for lvl in levels
    }

圧縮対応パイプライン

エンドツーエンドでは、幅広く検索し、再ランキングし、残った各チャンクを出典情報付きで圧縮し(抽出型またはLLMベース)、過剰なトリミングを防ぎ、トークン予算に収まるよう詰め込み、引用付きで生成します。

圧縮は、高い再現率の検索を手頃なコストで実現し、生成モデルを重要な情報に集中させるための層です。

def pipeline(query):
    top = rerank(query, hybrid_retrieve(query, 50))[:12]
    spans = compress_with_ids(query, top)
    spans = [s for s in spans if s['text']]
    packed = pack(spans, budget_tokens=2000, tok=count_tokens)
    return generate_with_citations(query, packed)

クイックチェック

事実ベースで引用付きの RAG システムに適した圧縮方法を選んでください。

まとめ

主なポイント:

  • 圧縮によって、検索したチャンクをクエリに関連する内容に絞り込み、コスト、レイテンシー、ノイズを削減します。
  • 引用付きの事実ベースの RAG では、抽象型よりも抽出型(原文どおりで追跡可能)を優先します。トークンレベルのプルーニングは、機械だけが扱うコンテキストに適しています。
  • クエリ依存の圧縮は最も絞り込めますが、リクエストごとに必要です。効率化のため、オフラインの要約と組み合わせます。
  • 情報損失を防ぎ、引用のためにチャンクとドキュメントの出典情報を保持します。
  • 圧縮を使って幅広く検索しながらプロンプトを小さく保ち、回答精度を損なわずに最大の圧縮率となるよう調整します。

よくある質問

「コンテキスト圧縮」レッスンは無料ですか?

はい。「コンテキスト圧縮」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Prompt Engineeringコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Prompt Engineeringコースには全4レッスンが含まれています。

「コンテキスト圧縮」で何を学びますか?

重要な情報に絞ってコンテキストを短縮します。 ブラウザで直接実行するハンズオンコードでAI Prompt Engineeringを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Prompt Engineeringを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Prompt Engineeringは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「コンテキスト圧縮」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Prompt Engineeringレッスンでコードを書いて実行できますか?

はい。すべてのAI Prompt Engineeringレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 素朴なRAGを超えて
  2. 取得チャンクの再ランキング
  3. コンテキスト圧縮
  4. クエリ書き換えとHyDE
← AI Prompt Engineeringに戻る