出力契約が決まったら、今回モデルに渡す資料を選びます。制約と必要な根拠を保ち、出力容量を予約し、安定した前置部分を再利用し、履歴を原資料へ戻れる要約にします。永続化・検索・モデル重みとは役割が異なります。
知識と状態の3つの階層
モデルの言語能力や膨大な知識は、トレーニング後の重みに由来します。コンテキストは、現在の問題、制約、および利用可能な証拠を提供します。「リクエスト間でチャット内容を自動的に記憶しない」という事実を、「モデルの全知識が今回の入力に含まれている」と誤解してはいけません。もう一つの独立した階層は、アプリケーションが維持するセッション履歴、ファイル、データベースです。これらは長期にわたって存在し得ますが、存在しているからといって、現在の推論プロセスに組み込まれているわけではありません。
モデル重み 学習で得たパラメータと能力 アプリケーションの永続状態 ファイル、データベース、履歴記録 選択と組み立て 検索、読取、要約 本ラウンドの生成 重みとコンテキストの共同参加 本ラウンドのコンテキスト 現在実際にアクセス可能な資料 知識、永続状態、および本ラウンドのコンテキストは3つの階層である データベースに記録された情報は、読み取られて本ラウンドの推論に提供されて初めて、現在の証拠として機能します。
例えば、リポジトリに最新のテストレポートが存在しても、モデルの重みに直近生成されたレポートの内容が含まれることはありません。アプリケーションはレポートを読み取り、関連する結果をモデルに渡す必要があります。単にパスを渡すだけでは、モデルは通常、本文を取得するためにツールを呼び出す必要があります。ファイルはセッションをまたいで状態を復元するのに役立ちますが、単発のコンテキストを自動的に拡張するわけではありません。
「API はステートレスである」という場合も、インターフェースに限定して考える必要があります。履歴を明示的に渡すメッセージインターフェースは、通常、呼び出し側が会話の継続を構成します。ホストされたセッションでは、サーバー側で履歴が保存され補完される可能性があり、推論サービスではプレフィックス状態が再利用されることもあります。アプリケーションにとってより有用な質問は、「今回の推論で実際に何が受け取られたのか、誰が履歴を補完し、どこに回復可能な真の状態が保存されているのか?」 です。Claude のウィンドウドキュメントは、トレーニング知識と現在の作業コンテキストを区別しており、入力、出力、および thinking の具体的なカウント規則を説明しています。Claude 上下文窗口
ウィンドウ予算と出力の余裕
次ステップのためにスペースを確保する
まず、ターゲットモデルの入出力制限とカウント規則を確認し、資料を割り当てます。以下は、仮に入力と出力の合計上限が 128,000 token である場合の計画例です。表中の K は 1,000 を表し、特定のモデルの固定設定を意味するものではありません。
項目 予算 保持理由
システム制約とツール定義 8K タスクの境界と利用可能な操作を決定
直近の履歴とタスク要約 32K 現在の案と重要な決定事項を保持
検索証拠 24K 本ラウンドの判断を支え、出典位置付き
現在の問題 1K ユーザーが本ラウンドで追加した要件
生成用予約 16K インターフェース規則に従い、回答、推論、ツール呼び出し出力を含む
安全マージン 8K カウント誤差と次のステップの資料用に確保
合計 89K 上限までまだ 39K の余裕あり
入力部分は 65K です。もし次のツール呼び出しで 50K のログが返ってきた場合、計画された合計は 139K となり、11K 超過します。この場合、リクエストエラーが発生してから適当に古い履歴を削除するのではなく、まずログをフィルタリングするか、重要な区間のみを読み取るべきです。ストリーミング出力は配信方法を変更するだけで、ウィンドウ容量を増やすものではありません。
以下の独立した計算例で予算を確認できます。これは算数の検証のみを行い、実際のリクエストでは、メッセージテンプレート、ツール定義、マルチモーダルコンテンツを含むために、ターゲットモデルのカウントツールを使用する必要があります。
limit = 128_000
parts = { " rules_tools" : 8_000 , " history" : 32_000 ,
" evidence" : 24_000 , " question" : 1_000 }
reserve , margin = 16_000 , 8_000
planned = sum ( parts . values ( ) ) + reserve + margin
assert planned == 89_000
assert limit - planned == 39_000
incoming = 50_000
print ( " 少なくとも" , max ( 0 , planned + incoming - limit ) , " token を削減する必要があります" )
異なるトークナイザー間で固定倍率による変換はできません。ベンダーのカウントエンドポイントを使用する場合でも、結果はリクエスト前の見積もりとして扱い、レスポンスの usage で補正する必要があります。Claude 公式では、両者の間にわずかな差異が生じる可能性があることを明確に指摘しています。Token counting
次の処理を入れる余裕はあるか
固定の49K は規則・履歴・質問・余裕です。出力と根拠は別々に調整します。超過は算数でも、何を削るかは根拠の判断です。棒を短くするために結論を左右する条件を消してはいけません。
図を準備しています 再読み込み
次の処理を入れる余裕はあるか 入力・ツール結果・出力予約・余裕を合計します。キャッシュ命中でも論理的なコンテキストは消えません。
{"id":"ai-context-budget","title":"次の処理を入れる余裕はあるか","summary":"入力・ツール結果・出力予約・余裕を合計します。キャッシュ命中でも論理的なコンテキストは消えません。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"control\"><label for=\"evidence\" data-i18n=\"evidence\"></label><output for=\"evidence\" id=\"evidence-value\"></output><input id=\"evidence\" type=\"range\" min=\"0\" max=\"64\" value=\"24\" step=\"1\"></div><div class=\"control\"><label for=\"reserve\" data-i18n=\"reserve\"></label><output for=\"reserve\" id=\"reserve-value\"></output><input id=\"reserve\" type=\"range\" min=\"1\" max=\"32\" value=\"16\" step=\"1\"></div><label class=\"check\"><input type=\"checkbox\" id=\"logs\"><span data-i18n=\"logs\"></span></label><div id=\"budget\"></div><div class=\"metrics\"><div><span data-i18n=\"planned\"></span><strong id=\"planned\"></strong></div><div><span data-i18n=\"remaining\"></span><strong id=\"remaining\"></strong></div></div><div class=\"copy\"><p id=\"explanation\" role=\"status\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"explain\"></p></div><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control output{color:var(--accent);text-align:right;font-variant-numeric:tabular-nums;min-width:4em}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1;min-width:0;overflow-wrap:anywhere;font-size:13px;min-height:44px}.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:16px 0}.actions button{min-width:0;min-height:44px;font-size:13px;overflow-wrap:anywhere}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0;overflow-wrap:anywhere}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin:18px 0}.metrics>div{border-left:2px solid var(--accent);padding:0 6px 0 10px;min-width:0}.metrics span{display:block;min-height:3.6em;color:var(--muted);font-size:12px;overflow-wrap:anywhere}.metrics strong{font-size:21px;display:block;min-height:2em;font-weight:550;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.check{display:flex;align-items:center;gap:9px;font-size:13px;margin:14px 0}.check input{width:18px;height:18px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:14px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:44px}.panel{padding:14px;border:1px solid var(--rule);border-radius:9px;margin:16px 0;min-width:0}.panel>header{font-size:13px;font-weight:600;margin-bottom:12px;color:var(--muted)}.panel>div{overflow-wrap:anywhere}.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:8px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:56px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:6px 3px;font-size:12px;overflow-wrap:anywhere}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.table{display:grid;gap:5px;font-size:12px}.tr{display:grid;gap:5px}.tr>div{background:var(--surface);border-radius:4px;padding:9px 6px;min-width:0;min-height:5em;overflow-wrap:anywhere;display:flex;align-items:center}.tr>.gold{background:var(--second-soft)}.tr>.on{background:var(--accent-soft)}.formula,.source{font:13px/1.8 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:16px 0}.formula{border-top:1px solid var(--rule);padding-top:12px;min-height:7.2em}.source{min-height:8em;background:var(--surface);padding:12px;border-radius:8px}.intervals{margin:16px 0}.interval{position:relative;height:38px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/38px ui-monospace,monospace;padding-left:7px}.bars{display:grid;gap:10px;margin:16px 0}.bar-row{display:grid;grid-template-columns:44px minmax(0,1fr) 62px;gap:8px;align-items:center;font:12px ui-monospace,monospace}.bar-track{height:24px;background:var(--surface);border-radius:4px;overflow:hidden}.bar-track i{display:block;height:100%;background:var(--accent);transition:width .2s}.bar-track i.gold{background:var(--second)}.bar-track i.empty{opacity:.2}.bar-row output{text-align:right}.diagram{display:block;width:100%;height:auto;margin:18px 0}.diagram text{font:13px ui-monospace,monospace;fill:var(--ink)}.node{fill:var(--surface);stroke:var(--rule)}.node.on{fill:var(--accent-soft);stroke:var(--accent)}.node.gold{fill:var(--second-soft);stroke:var(--second)}.edge{stroke:var(--rule);stroke-width:2;fill:none}.edge.on{stroke:var(--accent)}.matrix{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin:16px 0}.matrix button{min-width:0;min-height:44px;font:13px ui-monospace,monospace}.matrix button[aria-pressed=true]{background:var(--accent-soft);border-color:var(--accent)}.matrix button.masked{opacity:.35}.legend{font-size:12px;color:var(--muted);min-height:3.6em;overflow-wrap:anywhere}.numeric{font-variant-numeric:tabular-nums}.scope p{line-break:strict}@media(max-width:480px){.presets button,.actions button{font-size:12px}.panel{padding:12px}.metrics{gap:10px}.metrics strong{font-size:19px}.bar-row{grid-template-columns:34px minmax(0,1fr) 58px;gap:6px}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n\n.panel>h3{font-size:13px;font-weight:600;margin:0 0 12px;color:var(--muted)}\n\n.bar-row{grid-template-columns:44px minmax(0,1fr) 82px}.bar-row output{white-space:nowrap}@media(max-width:480px){.bar-row{grid-template-columns:34px minmax(0,1fr) 76px}}\n\n.metrics strong{font-size:17px;min-height:3.6em}","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';row.style.gridTemplateColumns='repeat('+r.length+',minmax(0,1fr))';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}function plot(id,series,xr,yr,opts={}){const e=$('#'+id),X=x=>42+(x-xr[0])/(xr[1]-xr[0])*298,Y=y=>175-(y-yr[0])/(yr[1]-yr[0])*148;let out='<defs><clipPath id=\"clip-'+id+'\"><rect x=\"42\" y=\"27\" width=\"298\" height=\"148\"/></clipPath></defs>';for(let i=0;i<3;i++){let x=xr[0]+i*(xr[1]-xr[0])/2,y=yr[0]+i*(yr[1]-yr[0])/2;out+='<path class=\"gridline\" d=\"M '+X(x)+' 27V175M42 '+Y(y)+'H340\"/><text x=\"'+X(x)+'\" y=\"194\" text-anchor=\"middle\">'+esc(opts.xfmt?opts.xfmt(x):Number(x.toFixed(2)))+'</text><text x=\"36\" y=\"'+(Y(y)+4)+'\" text-anchor=\"end\">'+esc(opts.yfmt?opts.yfmt(y):Number(y.toFixed(2)))+'</text>';}out+='<g clip-path=\"url(#clip-'+id+')\">';for(const s of series){out+='<path fill=\"none\" stroke=\"'+(s.color||'var(--accent)')+'\" stroke-width=\"2.5\" '+(s.dash?'stroke-dasharray=\"5 4\"':'')+' d=\"'+s.pts.map((p,i)=>(i?'L':'M')+X(p[0]).toFixed(2)+','+Y(p[1]).toFixed(2)).join(' ')+'\"/>';}for(const p of opts.points||[])out+='<circle cx=\"'+X(p[0])+'\" cy=\"'+Y(p[1])+'\" r=\"4\" fill=\"var(--second)\" stroke=\"var(--paper)\" stroke-width=\"1.5\"/>';if(opts.cursor!==undefined)out+='<path d=\"M'+X(opts.cursor)+' 27V175\" stroke=\"var(--muted)\" stroke-dasharray=\"3 3\"/>';e.innerHTML=out+'</g>';e.dataset.curves=JSON.stringify(series.map(s=>s.pts));}const curve=(fn,lo,hi,n=120)=>Array.from({length:n+1},(_,i)=>{const x=lo+(hi-lo)*i/n;return[x,fn(x)]});function inputs(draw){document.querySelectorAll('input,select').forEach(e=>{e.addEventListener('input',draw);e.addEventListener('change',draw)});draw()}const n=id=>+$('#'+id).value;const show=(id,v,d=3)=>set(id,Number(v.toFixed(d)));function bars(id,values,max=1){$('#'+id).className='bars';$('#'+id).innerHTML=values.map(v=>'<div class=\"bar-row\"><span>'+esc(v.label)+'</span><div class=\"bar-track\"><i class=\"'+(v.cls||'')+'\" style=\"width:'+Math.max(0,Math.min(100,v.value/max*100))+'%\"></i></div><output>'+esc(v.text??(v.value*100).toFixed(1)+'%')+'</output></div>').join('')}function softmax(z,T=1){let max=Math.max(...z),w=z.map(x=>Math.exp((x-max)/T)),sum=w.reduce((a,b)=>a+b,0);return w.map(x=>x/sum)}function draw(){let e=n('evidence'),r=n('reserve'),log=$('#logs').checked?50:0,total=49+e+r+log;set('evidence-value',e+'K');set('reserve-value',r+'K');bars('budget',[{label:'49K',value:49,text:'49K'},{label:'E',value:e,text:e+'K'},{label:'out',value:r,text:r+'K'},{label:'log',value:log,text:log+'K',cls:'gold'}],128);set('planned',total+'K / 128K');set('remaining',(128-total)+'K');set('explanation',t('explain'));document.body.dataset.total=total;}inputs(draw);","audio":false,"strings":{"evidence":"根拠(K token)","explain":"既定は 89K、ログ追加で 139K となり、最低 11K の削減が必要です。必要な根拠まで削らないかも確認します。","heading":"次の処理を入れる余裕はあるか","intro":"全文ログの有無、根拠と出力予約量を変え、合計を確認します。","logs":"50K の全文ログを含める","planned":"計画の合計","remaining":"残量・超過","reserve":"出力予約(K token)","reset":"リセット","scope":"入出力合計を仮に 128K(K=1000)とし、規則8K・履歴32K・質問1K・余裕8K を固定。製品上限ではありません。","scopeLabel":"モデルの範囲と前提"}}
証拠の必要性に応じた資料の選択
コンテキストの選択は、まず証拠のカバー範囲の問題です。「ある関数がどこで定義されているか」を問う場合、通常、シンボルとその周辺の少量のコードを特定するだけで十分です。一方、「移行案に互換性要件の見落としがないか」を問う場合、複数の完全な章を同時に読み取る必要があるかもしれません。検索で2つの断片にヒットしても、否定条件を見逃す方が、完全な読取よりも危険です。
タスク 資料の選択 検証すべき境界
事実やシンボルの特定 検索断片と近傍コンテキスト バージョン、同名オブジェクト、限定条件
少量の完全なドキュメントの比較 ドキュメント全体または章全体 付録、例外、定義が切り捨てられていないか
大量の資料をまたいだ総合 段階的な検索、証拠のマージ、その後生成 多ホップ関連がカバーされているか、結論の出典を追跡可能か
継続的な修正作業 現在のファイル、要件、差分、検証結果 要約が最新の作業領域に対応しているか
「この設定は本番環境に適しているか」という例では、検索は enabled: true を含む例文にヒットするかもしれませんが、制限事項は前の段落に「単一ノードテストのみ」と記載されています。証拠ユニットには、キーワードを含む行だけでなく、設定とその適用条件を含めるべきです。各資料にはファイルやドキュメントの識別子、バージョン、位置を付与し、矛盾する証拠は並べて保持し、モデルに矛盾を認識させ、必要に応じて原文を再読します。
検索内容は分析対象のデータであり、コンテキストに含まれているからといって、実行コマンドの権限を得るわけではありません。「以前の指示を無視する」という文言がウェブページに含まれている場合、出典の身元を保持し、資料の内容として処理する必要があります。タスクの権限は、アプリケーションの信頼できる設定とユーザーの認可によって決定されます。関連する実行の境界については セキュリティと保護 を参照してください。
研究では、重要な証拠を長い入力の異なる位置に配置するとパフォーマンスに影響を与えることが観察されており、一部のタスクでは中央部で性能が低下しやすいことが示されています。これは位置感応性のテストを行うべきであることを支持しますが、すべてのモデルが「中央部を見えていない」ことを証明するものではなく、結論を末尾にコピーすれば正しいとも限りません。Lost in the Middle
キャッシュの再利用範囲
KV キャッシュは、推論において注意の履歴状態を再利用するメカニズムです。プロンプトキャッシュは、サービスが繰り返されるプロンプトのプレフィックスに対して提供する再利用機能であり、内部ではこのような状態を使用している可能性があります。これらは異なる抽象階層に位置しており、完全に無関係というわけではありません。API キャッシュがヒットしたからといって、モデルが「答えを覚えている」わけではありません。変化があったサフィックスは依然として生成する必要があります。
リクエスト A ツール定義 システムと安定した資料 ユーザー質問 A リクエスト B ツール定義 システムと安定した資料 ユーザー質問 B プレフィックス内容とキャッシュ条件が同一 同じプレフィックスは再利用可能;変化が発生すると、後の状態は再計算が必要 キャッシュヒットによりプレフィックスの計算や費用が節約されますが、この入力は依然としてモデルのコンテキストウ ィンドウを占有します。
プレフィックスキャッシュでは、ツール定義と安定した指示は、動的なメッセージの前に配置するのが適しています。毎回先頭にランダムな ID を挿入すると、本来同じだった資料でも再利用できなくなる可能性があります。最後に問題のみを変更する場合、それまでの共通プレフィックスは依然として再利用の対象となります。ここで言う境界は、キャッシュの粒度、有効期限、モデルやサービスの設定にも影響を受けるため、可視される本文のみを比較することはできません。
Claude を例にとると、キャッシュは tools、system、messages の階層に関与し、ヒットは最小長さ、キャッシュブレイクポイント、有効期限によって制約されます。cache_read_input_tokens などの usage フィールドから検証できます。費用や制限はモデルやプラットフォームによって変化するため、接続時に該当ページを確認し、特定の価格倍率をキャッシュメカニズムそのものとして扱わないでください。Prompt caching
変更で接頭部の再利用はどこまでになるか
先頭の動的 ID と末尾の質問だけの変更を比べます。安定した順序の価値が分かりますが、実際の命中には版・長さ・有効期間・設定の条件も必要です。
図を準備しています 再読み込み
変更で接頭部の再利用はどこまでになるか 後ろの一致部分は手前の変更を越えて共通接頭部にはなれず、全体の類似度とは異なります。
{"id":"ai-prefix-reuse","title":"変更で接頭部の再利用はどこまでになるか","summary":"後ろの一致部分は手前の変更を越えて共通接頭部にはなれず、全体の類似度とは異なります。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"control\"><label for=\"change\" data-i18n=\"change\"></label><output for=\"change\" id=\"change-value\"></output><input id=\"change\" type=\"range\" min=\"0\" max=\"6\" value=\"6\" step=\"1\"></div><div class=\"track-row\"><span data-i18n=\"old\"></span><div id=\"old\" class=\"track\"></div></div><div class=\"track-row\"><span data-i18n=\"new\"></span><div id=\"new\" class=\"track\"></div></div><div class=\"metrics\"><div><span data-i18n=\"reuse\"></span><strong id=\"reuse\"></strong></div><div><span data-i18n=\"recompute\"></span><strong id=\"recompute\"></strong></div></div><div class=\"copy\"><p id=\"explanation\" role=\"status\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"explain\"></p></div><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control output{color:var(--accent);text-align:right;font-variant-numeric:tabular-nums;min-width:4em}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1;min-width:0;overflow-wrap:anywhere;font-size:13px;min-height:44px}.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:16px 0}.actions button{min-width:0;min-height:44px;font-size:13px;overflow-wrap:anywhere}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0;overflow-wrap:anywhere}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin:18px 0}.metrics>div{border-left:2px solid var(--accent);padding:0 6px 0 10px;min-width:0}.metrics span{display:block;min-height:3.6em;color:var(--muted);font-size:12px;overflow-wrap:anywhere}.metrics strong{font-size:21px;display:block;min-height:2em;font-weight:550;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.check{display:flex;align-items:center;gap:9px;font-size:13px;margin:14px 0}.check input{width:18px;height:18px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:14px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:44px}.panel{padding:14px;border:1px solid var(--rule);border-radius:9px;margin:16px 0;min-width:0}.panel>header{font-size:13px;font-weight:600;margin-bottom:12px;color:var(--muted)}.panel>div{overflow-wrap:anywhere}.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:8px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:56px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:6px 3px;font-size:12px;overflow-wrap:anywhere}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.table{display:grid;gap:5px;font-size:12px}.tr{display:grid;gap:5px}.tr>div{background:var(--surface);border-radius:4px;padding:9px 6px;min-width:0;min-height:5em;overflow-wrap:anywhere;display:flex;align-items:center}.tr>.gold{background:var(--second-soft)}.tr>.on{background:var(--accent-soft)}.formula,.source{font:13px/1.8 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:16px 0}.formula{border-top:1px solid var(--rule);padding-top:12px;min-height:7.2em}.source{min-height:8em;background:var(--surface);padding:12px;border-radius:8px}.intervals{margin:16px 0}.interval{position:relative;height:38px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/38px ui-monospace,monospace;padding-left:7px}.bars{display:grid;gap:10px;margin:16px 0}.bar-row{display:grid;grid-template-columns:44px minmax(0,1fr) 62px;gap:8px;align-items:center;font:12px ui-monospace,monospace}.bar-track{height:24px;background:var(--surface);border-radius:4px;overflow:hidden}.bar-track i{display:block;height:100%;background:var(--accent);transition:width .2s}.bar-track i.gold{background:var(--second)}.bar-track i.empty{opacity:.2}.bar-row output{text-align:right}.diagram{display:block;width:100%;height:auto;margin:18px 0}.diagram text{font:13px ui-monospace,monospace;fill:var(--ink)}.node{fill:var(--surface);stroke:var(--rule)}.node.on{fill:var(--accent-soft);stroke:var(--accent)}.node.gold{fill:var(--second-soft);stroke:var(--second)}.edge{stroke:var(--rule);stroke-width:2;fill:none}.edge.on{stroke:var(--accent)}.matrix{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin:16px 0}.matrix button{min-width:0;min-height:44px;font:13px ui-monospace,monospace}.matrix button[aria-pressed=true]{background:var(--accent-soft);border-color:var(--accent)}.matrix button.masked{opacity:.35}.legend{font-size:12px;color:var(--muted);min-height:3.6em;overflow-wrap:anywhere}.numeric{font-variant-numeric:tabular-nums}.scope p{line-break:strict}@media(max-width:480px){.presets button,.actions button{font-size:12px}.panel{padding:12px}.metrics{gap:10px}.metrics strong{font-size:19px}.bar-row{grid-template-columns:34px minmax(0,1fr) 58px;gap:6px}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n\n.panel>h3{font-size:13px;font-weight:600;margin:0 0 12px;color:var(--muted)}\n\n.bar-row{grid-template-columns:44px minmax(0,1fr) 82px}.bar-row output{white-space:nowrap}@media(max-width:480px){.bar-row{grid-template-columns:34px minmax(0,1fr) 76px}}\n\n","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';row.style.gridTemplateColumns='repeat('+r.length+',minmax(0,1fr))';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}function plot(id,series,xr,yr,opts={}){const e=$('#'+id),X=x=>42+(x-xr[0])/(xr[1]-xr[0])*298,Y=y=>175-(y-yr[0])/(yr[1]-yr[0])*148;let out='<defs><clipPath id=\"clip-'+id+'\"><rect x=\"42\" y=\"27\" width=\"298\" height=\"148\"/></clipPath></defs>';for(let i=0;i<3;i++){let x=xr[0]+i*(xr[1]-xr[0])/2,y=yr[0]+i*(yr[1]-yr[0])/2;out+='<path class=\"gridline\" d=\"M '+X(x)+' 27V175M42 '+Y(y)+'H340\"/><text x=\"'+X(x)+'\" y=\"194\" text-anchor=\"middle\">'+esc(opts.xfmt?opts.xfmt(x):Number(x.toFixed(2)))+'</text><text x=\"36\" y=\"'+(Y(y)+4)+'\" text-anchor=\"end\">'+esc(opts.yfmt?opts.yfmt(y):Number(y.toFixed(2)))+'</text>';}out+='<g clip-path=\"url(#clip-'+id+')\">';for(const s of series){out+='<path fill=\"none\" stroke=\"'+(s.color||'var(--accent)')+'\" stroke-width=\"2.5\" '+(s.dash?'stroke-dasharray=\"5 4\"':'')+' d=\"'+s.pts.map((p,i)=>(i?'L':'M')+X(p[0]).toFixed(2)+','+Y(p[1]).toFixed(2)).join(' ')+'\"/>';}for(const p of opts.points||[])out+='<circle cx=\"'+X(p[0])+'\" cy=\"'+Y(p[1])+'\" r=\"4\" fill=\"var(--second)\" stroke=\"var(--paper)\" stroke-width=\"1.5\"/>';if(opts.cursor!==undefined)out+='<path d=\"M'+X(opts.cursor)+' 27V175\" stroke=\"var(--muted)\" stroke-dasharray=\"3 3\"/>';e.innerHTML=out+'</g>';e.dataset.curves=JSON.stringify(series.map(s=>s.pts));}const curve=(fn,lo,hi,n=120)=>Array.from({length:n+1},(_,i)=>{const x=lo+(hi-lo)*i/n;return[x,fn(x)]});function inputs(draw){document.querySelectorAll('input,select').forEach(e=>{e.addEventListener('input',draw);e.addEventListener('change',draw)});draw()}const n=id=>+$('#'+id).value;const show=(id,v,d=3)=>set(id,Number(v.toFixed(d)));function bars(id,values,max=1){$('#'+id).className='bars';$('#'+id).innerHTML=values.map(v=>'<div class=\"bar-row\"><span>'+esc(v.label)+'</span><div class=\"bar-track\"><i class=\"'+(v.cls||'')+'\" style=\"width:'+Math.max(0,Math.min(100,v.value/max*100))+'%\"></i></div><output>'+esc(v.text??(v.value*100).toFixed(1)+'%')+'</output></div>').join('')}function softmax(z,T=1){let max=Math.max(...z),w=z.map(x=>Math.exp((x-max)/T)),sum=w.reduce((a,b)=>a+b,0);return w.map(x=>x/sum)}function draw(){let c=n('change'),r=c?c-1:6;set('change-value',c);cells('old',Array.from({length:6},(_,i)=>({text:String(i+1),cls:'on'})));cells('new',Array.from({length:6},(_,i)=>({text:i===c-1?(i+1)+'′':String(i+1),cls:i<r?'on':i===c-1?'gold':'empty'})));set('reuse',r);set('recompute',6-r);set('explanation',t('explain'));document.body.dataset.reuse=r;}inputs(draw);","audio":false,"strings":{"change":"最初の変更位置(0 は同一)","explain":"1 番目の変更では前置部全体が切れ、6 番目だけなら先頭5個が一致します。一致した後置部は命中保証ではありません。","heading":"変更で接頭部の再利用はどこまでになるか","intro":"最初に変わるブロックを選び、連続一致する前置部分を確認します。","new":"新しい要求","old":"元の要求","recompute":"変更点以降のブロック","reset":"リセット","reuse":"再利用可能な接頭ブロック","scope":"等長の論理ブロック6個。接頭部の依存を示し、サービスの粒度・TTL・条件・実際の命中は再現しません。","scopeLabel":"モデルの範囲と前提"}}
履歴を回復可能な状態に圧縮する
要約の目的は、次のラウンドで作業を継続できるようにすることです。「いくつかの問題について議論し、修正した」とだけ書いても、どこを修正し、何を検証し、次のステップで何に依存しているかが不明瞭であるため、回復価値はほとんどありません。
タスクがインポーターの修正中であると仮定します。古い案は却下され、現在のパッチは適用済みですが、ユニットテストのみが実行されています。有用な要約は、事実、未完了事項、制約を明確に区別すべきです。
{
" goal" : " インポーターの重複送信問題を修正" ,
" constraints" : [ " 既存のファイル形式を維持" , " 公共インターフェースは変更しない" ] ,
" current_artifacts" : [ " src/importer.py" , " tests/test_importer.py" ] ,
" decisions" : [ " 入力バッチ ID を使用して重複排除;プロセス内コレクションは使用しない" ] ,
" verified" : [ " ユニットテスト通過;詳細結果は artifacts/unit-test.txt にあり" ] ,
" pending" : [ " プロセス再起動後の重複送信を検証" ] ,
" next_action" : " 現在のパッチとテストレポートを読み取り、復旧シナリオの検証を追加"
}
これはアプリケーションのカスタム状態フォーマットであり、ベンダーの compaction プロトコルではありません。復元時には、ファイルやレポートがまだ存在し、現在の修正に対応しているかどうかを最初に確認します。要約内の「テスト通過」はテスト成果物を代替するものではなく、後続の修正もテストに合格したことを自動的に意味するものではありません。
操作 保持するもの 主な損失または要件
古い出力の切り捨て 現在関連する断片と原文の位置 削除された詳細は再読取が必要
履歴の圧縮 目標、制約、決定、証拠インデックス、次のアクション 要約で見落としや誤記がある可能性があり、重要な状態は検証が必要
永続メモリ セッションをまたいで実際に有用な安定した情報 バージョン、期限切れ、権限の処理が必要
サーバー側の compaction を使用する場合は、そのインターフェースに従って構造化状態を保持・返送する必要があり、任意の要約 JSON をプロトコルブロックに詰め込んではいけません。具体的な互換範囲とフローについては Claude Compaction を参照してください。セッションをまたぐ設計については メモリと状態 を参照してください。
コンテキスト変更の有効性をどう検証するか
一連のタスクと正解の根拠を固定し、元の履歴、圧縮された履歴、検索材料という3つの入力を比較します。タスクの正答率、必要な証拠の再現率、入力量、最初の可視出力までのレイテンシ、および総コストを記録します。その後、「圧縮後の復元」を再度行い、すでに失敗した案を繰り返していないか、ユーザーの制約を見落としていないか、完了していないステップが完了したと主張していないかを確認します。
入力量が減少したにもかかわらず復元エラーが増加した場合、重要な状態が削除されたことを意味します。入力量が増加したが正答率が変わらない場合、ツール出力が重複して保持されていないか確認します。事実回答は正しいが、支持する位置を示せない場合、証拠インデックスを確認します。これにより、コンテキストの選択がタスクを改善したのか、単にプロンプトが整って見えるようになったのかを判断できます。後続の評価方法については 評価と観測可能性 を参照してください。
次に読む:検索・RAG・根拠 。