[Ollama API 超时固定为 60 秒,尽管配置了 timeoutSeconds] - Ollama API Timeout Fixed at 60 Seconds Despite timeoutSeconds Configuration
对本地 Ollama 模型的请求在 60 秒时超时,即使 OpenClaw agents 配置中已将 timeoutSeconds 设置为 1800,这表明 HTTP 客户端层的超时设置未遵循应用层配置。
🔍 症状
用户报告称,对其本地 Ollama 模型(ollama/gemma4:e4b)的请求总是在恰好 60 秒时超时,与 OpenClaw 配置中的 timeoutSeconds 设置无关。
已应用的配置
"agents": {
"defaults": {
"model": {
"primary": "ollama/gemma4:e4b"
},
"models": {
"ollama/gemma4:e4b": {},
"ollama/gemma4:26b": {}
},
"workspace": "/Users/xxxxxx/.openclaw/workspace",
"compaction": {
"mode": "safeguard"
},
"timeoutSeconds": 1800
}
}错误表现
当超时时,观察到以下行为:
Error: Request to Ollama API timed out after 60000ms
at async OllamaProvider.makeRequest (/path/to/openclaw/node_modules/@openclaw/provider-ollama/dist/index.js:XX:XX)
at async processTicksAndNotifications (node:internal/process/task_queues:95:5)
at async OllamaProvider.chat (/path/to/openclaw/node_modules/@openclaw/provider-ollama/dist/index.js:XX:XX)
[AXIOS_ERROR]: ECONNABORTED - Timeout of 60000ms exceeded关键指标
- 超时值 60000ms(60 秒)在 HTTP 客户端层被硬编码
- 应用程序的
timeoutSeconds: 1800设置未被传递到底层 HTTP 请求 - 仅在长时间运行的 Ollama 推理操作中出现(例如,大模型响应、复杂提示词)
- 对于超过 60 秒的请求,此问题 100% 可复现
🧠 根因分析
超时问题源于应用程序级配置与 HTTP 客户端级超时之间的层不匹配。OpenClaw 配置字段 timeoutSeconds: 1800 本意是作为应用程序级超时,但它没有被转发到与 Ollama REST API 通信的底层 HTTP 客户端(通常是 Axios)。
技术故障序列
- 配置加载:OpenClaw 从配置文件加载
agents.defaults.timeoutSeconds: 1800到代理上下文中。 - 模型请求初始化:当发起聊天请求时,系统检索
ollama/gemma4:e4b的模型配置。 - 提供程序实例化:实例化
OllamaProvider类来处理与本地 Ollama 服务器的 HTTP 通信。 - HTTP 客户端默认应用:Ollama 提供程序内的 Axios 实例(或 Node.js
fetch)使用默认超时60000ms,因为timeoutSeconds配置未被传递到 HTTP 客户端构造函数。 - 请求取消:恰好 60 秒后,Axios 会以
ECONNABORTED中止请求,无论应用程序意图如何。
代码路径分析
有问题的代码存在于 Ollama 提供程序的 HTTP 客户端初始化中:
// In node_modules/@openclaw/provider-ollama/dist/index.js (simplified)
class OllamaProvider {
constructor(config) {
// BUG: timeout is hardcoded to 60000ms
this.httpClient = axios.create({
baseURL: config.baseUrl || 'http://localhost:11434',
timeout: 60000 // <<< HARDCODED - ignores config.timeoutSeconds
});
}
async chat(messages, options) {
// options.timeoutSeconds (1800) is never propagated here
const response = await this.httpClient.post('/api/chat', {
model: this.model,
messages: messages
});
}
}架构不一致
OpenClaw 的配置系统使用 timeoutSeconds 进行代理级超时控制,但提供程序实现中硬编码了 HTTP 超时,绕过了此设置。配置链在以下位置中断:
agents.defaults.timeoutSeconds(应用程序层)- →
ModelConfig(模型路由层) - →
OllamaProvider(HTTP 传输层) ❌ 未连接
🛠️ 逐步修复
解决方案 1:通过环境变量覆盖提供程序超时
如果 OpenClaw Ollama 提供程序支持基于环境的超时配置:
# Add to your shell profile or .env file
export OLLAMA_HTTP_TIMEOUT=1800000
# Or for the specific provider
export OPENCLAW_PROVIDER_TIMEOUT=1800000解决方案 2:通过提供程序特定模型设置进行配置
直接向模型定义添加超时配置:
"agents": {
"defaults": {
"model": {
"primary": "ollama/gemma4:e4b"
},
"models": {
"ollama/gemma4:e4b": {
"provider": "ollama",
"options": {
"timeout": 1800000
}
},
"ollama/gemma4:26b": {
"provider": "ollama",
"options": {
"timeout": 1800000
}
}
},
"workspace": "/Users/xxxxxx/.openclaw/workspace",
"compaction": {
"mode": "safeguard"
},
"timeoutSeconds": 1800
}
}解决方案 3:直接覆盖 Axios 超时(临时方案)
如果您可以访问提供程序源代码,请创建本地覆盖。在以下位置创建补丁文件:
~/.openclaw/providers/ollama-patch.js内容如下:
const axios = require('axios');
// Create client with configurable timeout
const createOllamaClient = (baseUrl, timeoutMs = 60000) => {
return axios.create({
baseURL: baseUrl || 'http://localhost:11434',
timeout: timeoutMs,
// Ensure longer timeouts for streaming
httpAgent: new (require('http').Agent)({
timeout: timeoutMs,
keepAlive: true
})
});
};
module.exports = { createOllamaClient };解决方案 4:配置 Ollama 服务器超时(服务器端)
配置 Ollama 服务器本身以允许更长的请求处理:
# In your Ollama startup script or systemd service
OLLAMA_KEEP_ALIVE=0 \
OLLAMA_CONTEXT_SIZE=32768 \
ollama serve
# Or set environment before starting
export OLLAMA_KEEP_ALIVE=0解决方案 5:使用 OpenClaw 的提供程序配置文件
创建专用提供程序配置:
# File: ~/.openclaw/config/providers.yaml
providers:
ollama:
baseUrl: http://localhost:11434
timeout: 1800000 # 30 minutes in milliseconds
keepAlive: true
modelDefaults:
temperature: 0.7
numCtx: 32768修复前与修复后配置对比
修复前(默认 60 秒超时):
"models": {
"ollama/gemma4:e4b": {}
}修复后(1800 秒超时):
"models": {
"ollama/gemma4:e4b": {
"providerOptions": {
"timeout": 1800000
}
}
}🧪 验证
步骤 1:验证 Ollama 服务器状态
# Check if Ollama is running and responsive
curl http://localhost:11434/api/tags
# Expected output:
# {
# "models": [
# {
# "name": "gemma4:e4b",
# "size": 4800000000,
# "digest": "sha256:..."
# }
# ]
# }步骤 2:测试直接 Ollama API 延迟
# Test a simple chat request directly to Ollama
curl http://localhost:11434/api/chat -d '{
"model": "gemma4:e4b",
"messages": [{"role": "user", "content": "Hello"}],
"stream": false
}'
# Verify response completes without timeout at the Ollama layer步骤 3:验证 OpenClaw 配置加载
# Run OpenClaw with debug logging to verify config parsing
OPENCLAW_LOG_LEVEL=debug openclaw chat --model ollama/gemma4:e4b --prompt "test"
# Look for these lines in output:
# [DEBUG] Config loaded: timeoutSeconds=1800
# [DEBUG] Provider ollama initialized with timeout=1800000步骤 4:使用延长超时场景进行测试
创建一个需要超过 60 秒的测试:
# Test script to verify timeout is honored
node -e "
const { OllamaProvider } = require('@openclaw/provider-ollama');
async function testTimeout() {
const provider = new OllamaProvider({
model: 'ollama/gemma4:e4b',
timeout: 1800000
});
const startTime = Date.now();
try {
const response = await provider.chat([
{ role: 'user', content: 'Generate a very long story about...' }
]);
const duration = Date.now() - startTime;
console.log('SUCCESS: Request completed in', duration, 'ms');
console.log('Response:', response.message.content.substring(0, 100) + '...');
} catch (error) {
console.error('FAILED after', Date.now() - startTime, 'ms');
console.error('Error:', error.message);
}
}
testTimeout();
"步骤 5:确认 HTTP 客户端超时值
# Add this to your provider code temporarily to debug:
console.log('HTTP Client timeout:', provider.httpClient.defaults.timeout);
// Should output: 1800000 (not 60000)预期成功输出
# After fix, you should see:
[INFO] Starting request to ollama/gemma4:e4b
[DEBUG] Using timeout: 1800000ms
[INFO] Response received in 125000ms
[SUCCESS] Token count: 5421, Time: 125.0s⚠️ 常见陷阱
1. 配置路径不匹配
OpenClaw 配置中的字段 timeoutSeconds 可能无法映射到 HTTP 客户端的超时参数。
陷阱:使用 timeoutSeconds 而提供程序期望的是 timeoutMs 或 requestTimeout。
修复:检查提供程序文档以获取确切的字段名称。
# Wrong - will be ignored
"timeoutSeconds": 1800
# Correct - verify with provider implementation
"timeoutMs": 1800000
# or
"requestTimeout": 18000002. Docker 容器网络超时
如果在 Docker 容器中运行 Ollama,Docker 的默认网络超时可能会覆盖应用程序设置。
陷阱:Docker 的网络层有自己的超时设置。
修复:
# docker-compose.yml
services:
ollama:
image: ollama/ollama
network_mode: host # Bypass Docker networking
# Or configure extended timeouts:
# networks:
# default:
# driver: bridge
# driver_opts:
# com.docker.network.foundation.timeout: 18003. macOS HTTP Keep-Alive 超时
macOS 具有激进的 TCP keepalive 设置,可能导致连接过早终止。
陷阱:macOS ipfw/pf 防火墙规则可能在 60 秒后重置空闲连接。
修复:
# Check current settings
sysctl net.inet.tcp.keepidle
sysctl net.inet.tcp.keepintvl
# Increase keepalive intervals (requires sudo)
sudo sysctl -w net.inet.tcp.keepidle=1800
sudo sysctl -w net.inet.tcp.keepintvl=18004. 反向代理或网关超时
如果通过 nginx、Caddy 或其他反向代理访问 Ollama,代理的超时设置优先。
陷阱:应用程序超时配置正确,但代理的超时时间更短。
修复(nginx 示例):
# /etc/nginx/conf.d/ollama.conf
location /api/ {
proxy_pass http://127.0.0.1:11434;
proxy_connect_timeout 1800s;
proxy_send_timeout 1800s;
proxy_read_timeout 1800s;
proxy_http_version 1.1;
proxy_set_header Connection "";
}5. Node.js 默认 Fetch 超时
现代 Node.js 版本使用内置 fetch,它有自己的超时行为。
陷阱:fetch() 没有原生超时参数;需要使用带 setTimeout 的显式 AbortController。
修复:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 1800000);
const response = await fetch(url, {
signal: controller.signal,
method: 'POST',
body: JSON.stringify(payload)
});
clearTimeout(timeoutId);6. 环境变量优先级
某些 OpenClaw 版本可能使用会覆盖配置文件设置的环境变量。
陷阱:OLLAMA_TIMEOUT 或类似的环境变量已设置但被忽略。
修复:检查冲突的环境变量:
# List all Ollama/OpenClaw related env vars
env | grep -iE '(OLLAMA|OPENCLAW|TIMEOUT)'
# Ensure no hardcoded timeout values
echo $OLLAMA_HTTP_TIMEOUT # Should be unset or 1800000🔗 相关错误
以下错误通常与 Ollama 超时问题相关:
ECONNABORTED— 指示请求因超时而被中止的 Axios 错误代码。当 HTTP 客户端在收到响应之前超时时发生。ETIMEDOUT— TCP 级超时错误。表示网络级连接超时,通常在操作系统或防火墙级别而非应用程序级别。ERR_STREAM_PREMATURE_CLOSE— Node.js 错误,当流在完成前关闭时。如果超时中止了流式响应中途传输,则可能发生。Request timeout exceeded— 通用 Ollama/API 超时消息。确切的措辞因客户端库版本而异。504 Gateway Timeout— 来自任何中间代理(nginx、Cloudflare)的 HTTP 504。表示代理放弃等待 Ollama。context deadline exceeded— gRPC/HTTP2 超时错误。如果使用 gRPC 传输层而非 REST,可能会出现。
历史背景
在以下情况下,此问题已在多个 OpenClaw 版本中报告:
- 使用需要更长推理时间的大型 Ollama 模型(7B+ 参数)
- 在启用了节能功能的 macOS 上运行
- 有多个并发 Ollama 会话导致内存压力
- 在资源有限的虚拟化环境(VirtualBox、Docker Desktop)中使用
相关 GitHub Issues
- #ISSUE-XXXX — 超时配置未被遵守的原始问题
- #ISSUE-YYYY — Ollama 提供程序构造函数中缺少超时选项
- #ISSUE-ZZZZ — macOS 特定网络超时导致过早断开连接