Ollama LLM 超时不遵循配置的 timeoutSeconds
OpenClaw 忽略用户定义的 timeoutSeconds 配置,并在等待 Ollama 响应时回退到硬编码的 15 秒超时,导致在慢速 CPU 模型的场景下过早触发 failover。
🔍 症状
主要表现
尽管配置了500秒超时,agent仍然回退到备用模型,实际超时在15秒后触发:
openclaw-gateway-1 | 2026-04-12T22:02:44.589+00:00 [agent] embedded run timeout: runId=slug-gen-1776031345185 sessionId=slug-generator-1776031345185 timeoutMs=15000已应用的配置
用户应用了以下配置结构(根据社区讨论中的建议):
{
"agents": {
"defaults": {
"timeoutSeconds": 500,
"llm": {
"idleTimeoutSeconds": 500
}
}
}
}模型预热时间
Ollama模型仅预热就需要超过2分钟,这对于CPU推理来说是预期的:
$ time docker compose exec ollama ollama run qwen2.5:7b "warmup"
Sure! What kind of warm-up would you like?
real 2m32.193s
user 0m0.059s
sys 0m0.027s故障转移序列
日志中的完整失败序列:
ollama-1 | [GIN] 2026/04/12 - 22:02:45 | 500 | 16.171687684s | 127.0.0.1 | POST "/api/chat"
openclaw-gateway-1 | [agent] embedded run timeout: timeoutMs=15000
openclaw-gateway-1 | [agent] embedded run failover decision: decision=fallback_model reason=timeout
openclaw-gateway-1 | [diagnostic] lane task error: error="FailoverError: LLM request timed out."🧠 根因分析
配置路径不匹配
用户的配置使用了错误的嵌套路径结构。agents.defaults.llm路径在OpenClaw配置模式中不存在用于超时设置的字段。该超时值被静默忽略,OpenClaw回退到其硬编码默认值15秒(15000ms)。
硬编码超时行为
OpenClaw的agent运行时有一个内置的默认超时,无法通过agents.defaults配置块覆盖。相关的配置路径如下:
agents.defaults.timeoutSeconds— 控制整体agent运行超时,而非LLM请求超时llm.requestTimeoutSeconds— LLM HTTP请求超时的正确路径(不是agents.defaults.llm)llm.idleTimeoutSeconds— 控制连接空闲超时,独立于请求超时
配置解析失败
当OpenClaw解析配置时,它会对照模式验证路径。未知或未注册的路径会在debug级别记录,但不会导致启动失败。agents.defaults.timeoutSeconds中指定的超时值适用于agent编排层,而非底层LLM HTTP客户端超时。
技术深入分析
LLM提供商(Ollama)使用具有自己超时设置的HTTP客户端。在OpenClaw代码库中,请求超时通过provider选项传递:
// Pseudo-code representation of the timeout flow
llmClient := NewLLMClient(llm.Config{
RequestTimeout: config.GetInt("llm.requestTimeoutSeconds") * 1000, // defaults to 15000ms
})
// The agent orchestrator timeout (agents.defaults.timeoutSeconds) is separate
agentRunner := NewAgentRunner(AgentConfig{
RunTimeout: config.GetInt("agents.defaults.timeoutSeconds") * 1000,
})Ollama provider使用llm.requestTimeoutSeconds中的requestTimeout进行初始化,而不是从agents.defaults.timeoutSeconds获取。
🛠️ 逐步修复
步骤1:查找配置文件位置
定位活动中的OpenClaw配置文件:
# For Docker Compose deployments
docker compose config 2>/dev/null | grep -A5 "config:\|configFile:\|--config" || echo "Checking volumes..."
# Alternative: Find config file in container
docker compose exec openclaw-gateway find / -name "*.yaml" -o -name "*.json" 2>/dev/null | grep -v proc步骤2:使用正确路径更新配置
用修正后的结构替换现有配置:
之前(错误):
{
"agents": {
"defaults": {
"timeoutSeconds": 500,
"llm": {
"idleTimeoutSeconds": 500
}
}
}
}之后(正确):
{
"agents": {
"defaults": {
"timeoutSeconds": 500
}
},
"llm": {
"requestTimeoutSeconds": 300,
"idleTimeoutSeconds": 300
},
"providers": {
"ollama": {
"options": {
"requestTimeoutSeconds": 300
}
}
}
}步骤3:Provider特定覆盖(推荐)
由于您使用的是Ollama,请直接将超时应用到provider配置:
{
"providers": {
"ollama": {
"options": {
"requestTimeoutSeconds": 300
}
}
}
}步骤4:重启服务
docker compose down
docker compose up -d
docker compose logs -f openclaw-gateway 2>&1 | head -50步骤5:验证配置加载
# Check for configuration warnings on startup
docker compose logs openclaw-gateway 2>&1 | grep -i "warn\|config\|timeout"
Verify the config is loaded (look for validation messages)
docker compose exec openclaw-gateway cat /etc/openclaw/config.yaml 2>/dev/null ||
docker compose exec openclaw-gateway env | grep -i openclaw
🧪 验证
方法1:检查启动日志中的超时值
# Start fresh and capture startup
docker compose down
docker compose up -d
sleep 5
docker compose logs openclaw-gateway 2>&1 | grep -iE "timeout|llm|request"预期输出应显示已加载配置的超时值:
openclaw-gateway-1 | [init] LLM request timeout configured: 300s provider=ollama
openclaw-gateway-1 | [init] Configuration loaded successfully方法2:触发测试请求并测量
# Send a test request to the OpenClaw gateway
curl -X POST http://localhost:3000/api/v1/agent/run \
-H "Content-Type: application/json" \
-d '{
"agent": "default",
"input": "Hello, respond with just the word OK",
"model": "ollama/qwen2.5:7b"
}' 2>&1 | tee /tmp/ollama_test.log &
Monitor the actual timeout being applied
watch -n 1 ‘docker compose logs –since 30s openclaw-gateway 2>&1 | grep -i timeout’
方法3:确认Ollama响应时间超过旧超时时间
# Direct Ollama test (should take 2+ minutes for warmup)
time docker compose exec ollama ollama run qwen2.5:7b "Say hello"
Expected: Should complete without OpenClaw timeout error
Old behavior: Fail after 15 seconds with “LLM request timed out”
Fixed behavior: Wait for Ollama response up to configured timeout
方法4:通过诊断端点验证(如可用)
curl http://localhost:3000/api/v1/diagnostics 2>/dev/null | jq '.providers[] | select(.provider=="ollama") | .timeoutSeconds'预期输出:300
⚠️ 常见陷阱
1. 配置路径大小写敏感
OpenClaw配置键区分大小写。这些不等价:
# WRONG
"RequestTimeoutSeconds": 300
# CORRECT
"requestTimeoutSeconds": 3002. 嵌套路径假设
不要假设在agents.defaults.llm下嵌套超时设置会传播到LLM provider。配置模式使用扁平命名空间:
# WRONG - This path does not exist
agents.defaults.llm.requestTimeoutSeconds
# CORRECT - Top-level llm section
llm.requestTimeoutSeconds
# ALSO CORRECT - Provider-specific options
providers.ollama.options.requestTimeoutSeconds3. 时间单位不匹配
不同的配置字段使用不同的单位:
timeoutSeconds— 秒(整数)requestTimeoutSeconds— 秒(整数)idleTimeoutSeconds— 秒(整数)timeoutMs— 毫秒(如日志所示)
换算:300秒 = 300,000毫秒
4. Docker卷缓存
通过卷挂载的配置文件可能被缓存。强制重新加载:
docker compose down --remove-orphans
docker compose rm -f openclaw-gateway
docker compose up -d
# Do NOT just restart; perform full teardown5. 环境变量覆盖
环境变量优先于配置文件。检查冲突设置:
docker compose config 2>/dev/null | grep -iE "timeout|env|OPENCLAW"
docker compose exec openclaw-gateway env | grep -iE "TIMEOUT|OLLAMA"6. macOS特有:CPU节流
在Apple Silicon的macOS上,Ollama CPU模拟会导致极慢的速度。即使是简单查询,第一次响应也可能需要5分钟以上。确保配置的超时时间超过最坏情况延迟。
7. Ollama模型加载
初始模型加载时间(日志中显示:"llama runner started in 11.87 seconds")会占用LLM超时的一部分。对于基于CPU的模型,需要添加缓冲时间来应对冷启动。
🔗 相关错误
FailoverError: LLM request timed out— 当LLM provider超过配置超时时的主要错误embedded run timeout: timeoutMs=15000— 指示使用了15秒硬编码默认值的日志消息embedded run failover decision: fallback_model— 由于超时触发而做出的决策- Issue #46049 — 外部LLM provider的timeout配置问题
- Issue #24235 — OpenClaw中历史超时处理不一致
HTTP 500 from Ollama— Ollama在慢响应后返回服务器错误;常被误解为超时strconv.ParseInt: parsing "max"— Ollama容器中的CPU配额解析警告(无害,与超时无关)
故障排除矩阵
| 症状 | 根因 | 修复方法 |
|---|---|---|
| 尽管配置但仍在15s超时 | 错误的配置路径 | 使用 providers.{provider}.options.requestTimeoutSeconds |
| 尽管配置300s但仍在30s超时 | 环境变量覆盖 | 检查 OPENCLAW_LLM_TIMEOUT 环境变量 |
| 正好在60s后超时 | 负载均衡器/代理超时 | 检查nginx/docker代理设置 |
| Ollama在15s后返回500 | 上游超时 + Ollama错误 | 同时增加Ollama和OpenClaw超时 |