April 15, 2026 • 版本: 2026.4.10

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": 300

2. 嵌套路径假设

不要假设在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.requestTimeoutSeconds

3. 时间单位不匹配

不同的配置字段使用不同的单位:

  • 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 teardown

5. 环境变量覆盖

环境变量优先于配置文件。检查冲突设置:

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超时

依据与来源

本故障排除指南由 FixClaw 智能管线从社区讨论中自动合成。