45395 - シコウサクゴ -

Ollamaのタイムアウト問題を解決する:ローカルLLMのモデル選定と運用の実践知見

2026-04-08
AI駆動開発
AI駆動開発
Ollama
ローカルLLM
トラブルシューティング
Last updated:2026-04-08
8 Minutes
1571 Words

概要

claudelogプロジェクト(Claude Code会話ログをOllamaで要約するCLIツール)の開発中に、HeadersTimeoutErrorが環境変数の設定では解決しないという問題に遭遇しました。

原因はOllama側ではなく、Node.jsのfetch API(undici由来)のデフォルトタイムアウトにありました。本記事では、問題の切り分け、試した対策、最終的な解決策、そしてモデルサイズと精度のトレードオフについて記録します。


発生した問題

エラー内容

1
HeadersTimeoutError: Headers Timeout Error
2
at Timeout.onParserTimeout [as callback] (node:internal/deps/undici/undici:...)
3
code: 'UND_ERR_HEADERS_TIMEOUT'

発生状況

  • 使用モデル: llama3.2:3b
  • 処理内容: Claude Codeの会話ログ(数千行)をOllamaに送信して要約を生成
  • タイミング: 長いログの要約時に発生。短いログでは発生しない

claudelogの用途

claudelogは、Claude Codeのセッションログを解析・要約するCLIツールです。ログファイルを読み込み、Ollamaのローカルモデルで要約を生成し、検索可能な形式で保存します。


試した対策と結果

対策1:OLLAMA_TIMEOUT環境変数(効果なし)

最初に試したのは、Ollamaの環境変数によるタイムアウト延長です。

Terminal window
1
export OLLAMA_TIMEOUT=6000000 # 6000秒(100分)
2
ollama serve

結果: 効果なし。同じHeadersTimeoutErrorが発生しました。

OLLAMA_TIMEOUT=6000000に設定してもまだタイムアウトするのは、エラーの発生箇所がOllamaではなかったためです。

対策2:Ollamaのkeep_aliveパラメータ(効果なし)

API呼び出し時にkeep_aliveパラメータを指定する方法も試しました。

1
const response = await fetch('http://localhost:11434/api/generate', {
2
method: 'POST',
3
body: JSON.stringify({
4
model: 'llama3.2:3b',
5
prompt: longPrompt,
6
keep_alive: '60m'
7
})
8
});

結果: 効果なしkeep_aliveはモデルのメモリ保持時間の設定であり、HTTPリクエストのタイムアウトとは無関係でした。

原因の特定:Node.js fetch APIのデフォルトタイムアウト

エラーコードUND_ERR_HEADERS_TIMEOUTを調査したところ、これはNode.jsのfetch実装(undici)が持つデフォルトのヘッダータイムアウトでした。

1
Node.js fetch (undici)
2
└── デフォルトのheadersTimeout: 300000ms(5分)
3
└── OllamaのAPI応答が5分を超えると → HeadersTimeoutError

Ollama側の設定をいくら変更しても、HTTPクライアント側のタイムアウトが5分で切れていたのが原因です。


解決策

Node.js側のタイムアウト設定

fetchの代わりに、undiciのrequestを直接使うか、AbortControllerでタイムアウトを制御します。

1
// AbortControllerによるタイムアウト制御
2
const controller = new AbortController();
3
const timeout = setTimeout(() => controller.abort(), 600000); // 10分
4
5
try {
6
const response = await fetch('http://localhost:11434/api/generate', {
7
method: 'POST',
8
body: JSON.stringify({
9
model: 'llama3.2:3b',
10
prompt: longPrompt,
11
stream: false
12
}),
13
signal: controller.signal
14
});
15
const data = await response.json();
4 collapsed lines
16
return data.response;
17
} finally {
18
clearTimeout(timeout);
19
}

ストリーミングモードの活用

Ollamaのstream: trueオプションを使うと、レスポンスがチャンク単位で返されるため、ヘッダータイムアウトの問題を回避できます。

1
const response = await fetch('http://localhost:11434/api/generate', {
2
method: 'POST',
3
body: JSON.stringify({
4
model: 'llama3.2:3b',
5
prompt: longPrompt,
6
stream: true // ストリーミングモード
7
})
8
});
9
10
let result = '';
11
const reader = response.body.getReader();
12
const decoder = new TextDecoder();
13
14
while (true) {
15
const { done, value } = await reader.read();
4 collapsed lines
16
if (done) break;
17
const chunk = JSON.parse(decoder.decode(value));
18
result += chunk.response;
19
}

ストリーミングモードでは、最初のチャンクがすぐに返されるため、ヘッダータイムアウトに引っかかりません。


モデルサイズと精度のトレードオフ

処理速度より精度を優先

claudelogの用途では、要約の品質が重要です。高速だが不正確な要約よりも、時間がかかっても正確な要約を得たいという判断をしました。

モデル選定の考え方

1
小さいモデル(llama3.2:3b)
2
├── メリット: 高速、メモリ消費少
3
└── デメリット: 長文の要約精度が低い、文脈を見失いやすい
4
5
大きいモデル(※要確認: 実際に試したモデル名)
6
├── メリット: 要約精度が高い、長文の文脈保持が良い
7
└── デメリット: 低速、メモリ消費大

最終的には「プロンプトを詳細版に戻す + 大きなモデル」のオプションを選択しました。ローカルLLMの場合、モデルサイズの変更はollama pullで即座に行えるため、試行錯誤のコストは低いです。

プロンプトの最適化

モデルを大きくするだけでなく、プロンプト自体も調整しました。

1
# 簡略プロンプト(3bモデルで使用していた)
2
「以下のログを要約してください。」
3
4
# 詳細プロンプト(大きなモデルで使用)
5
「以下はClaude Codeのセッションログです。
6
このログから以下の情報を抽出し、構造化された要約を生成してください。
7
1. セッションの目的(何を実現しようとしていたか)
8
2. 実施した主な作業(時系列順)
9
3. 発生した問題とその解決策
10
4. セッションの成果(作成/変更したファイル)
11
5. 未完了のタスク(あれば)」

詳細プロンプトの方が出力の品質は高くなりますが、トークン数が増えるため処理時間も長くなります。


ローカルLLM運用の実践知見

環境変数だけでは解決しない問題

今回の教訓は、エラーメッセージの発生箇所を正確に特定することの重要性です。

1
エラー: HeadersTimeoutError (UND_ERR_HEADERS_TIMEOUT)
2
3
直感: 「Ollamaのタイムアウト設定を変更すれば直る」
4
5
実際: Node.jsのfetch実装(undici)のデフォルトタイムアウト
6
7
解決: Node.js側のタイムアウト設定を変更

UND_ERR_HEADERS_TIMEOUTのプレフィックスUNDはundiciを示しています。エラーコードの命名規則を知っていれば、より早く原因を特定できたかもしれません。

Ollamaの運用チェックリスト

ローカルLLMをアプリケーションに組み込む際のチェックリストです。

  • HTTPクライアントのタイムアウト設定は十分か
  • ストリーミングモードを使用しているか
  • モデルサイズはタスクに対して適切か
  • プロンプトの長さとモデルのコンテキストウィンドウの関係は適切か
  • エラー発生時のリトライ処理はあるか
  • モデルがメモリにロードされていない場合の初回遅延を考慮しているか

Node.js fetch APIの注意点

Node.jsのfetchはundiciベースの実装であり、ブラウザのfetchとは異なるデフォルト値を持ちます。

設定undiciのデフォルトブラウザfetch
headersTimeout300000ms (5分)なし(無制限)
bodyTimeout300000ms (5分)なし(無制限)
keepAliveTimeout4000ms

ブラウザでは問題なく動作するコードが、Node.jsでタイムアウトする原因はここにあります。


まとめ

問題原因解決策
HeadersTimeoutErrorNode.js fetch (undici)のデフォルトタイムアウトAbortControllerまたはストリーミングモード
OLLAMA_TIMEOUT無効タイムアウトの発生箇所がOllamaではないNode.js側の設定変更
要約精度が低いモデルサイズが小さすぎる大きなモデル + 詳細プロンプト

ローカルLLMは「動かすだけ」は簡単ですが、アプリケーションに組み込んで安定運用するには、HTTPクライアントの挙動やモデル特性の理解が必要です。特にNode.js環境では、undici由来のデフォルト設定に注意してください。

Article title:Ollamaのタイムアウト問題を解決する:ローカルLLMのモデル選定と運用の実践知見
Article author:45395
Release time:2026-04-08

記事へのご質問・ご感想をお聞かせください

フィードバックを送る