# 低配机器跑 AI Agent 不崩的配置技巧:内存监控 + 任务队列 + 失败自动重试
先说结论:2G 内存的机器也能跑本地 AI Agent,但得精打细算。
我在 1G 和 2G 内存的机器上都试过,踩了不少 OOM 的坑。这篇把我总结出来的配置技巧都写下来,给用小鸡的朋友参考。
一、选对模型是第一要务
模型推荐(按内存排序)
| 模型 | 最低内存 | 量化 | 适合场景 |
|
|
|
|
|
|---|---|---|---|
| phi3:mini | 2G | Q4_K_M | 简单问答、分类 |
| qwen2.5:1.5b | 2G | Q4_K_M | 中文理解、翻译 |
| qwen2.5:3b | 4G | Q4_K_M | 摘要、分析 |
| qwen2.5:7b | 8G | Q4_K_M | 复杂任务、长文本 |
| llama3.2:3b | 4G | Q4_K_M | 英文为主 |
2G 内存的机器,只推荐 phi3:mini 或 qwen2.5:1.5b。
别贪心上 7B,就算能加载,推理时也容易被系统杀掉。
# 拉取小模型
ollama pull phi3:mini
# 或者
ollama pull qwen2.5:1.5b
量化版本的选择
Ollama 默认拉取的就是量化版(Q4_K_M),不用额外操作。但如果你手动拉取 GGUF 文件的话,记住:
- Q2_K:最小,但质量损失明显
- Q4_K_M:性价比最高,推荐
- Q8_0:接近原始,但内存翻倍
- FP16:别想了,小鸡跑不动
OLLAMA_NUM_PARALLEL=1:只允许一个并发请求OLLAMA_MAX_LOADED_MODELS=1:内存里只留一个模型OLLAMA_CONTEXT_LENGTH=2048:上下文窗口砍到 2048- 超时设 120 秒(小模型推理慢)
- 重试间隔递增(10s → 20s → 30s)
- 最多重试 3 次,别无限重试
二、Ollama 配置优化
限制上下文窗口
默认上下文是 8192 token,会吃掉不少内存。2G 机器建议砍到 2048:
# 创建 Ollama 配置
mkdir -p /etc/systemd/system/ollama.service.d
cat > /etc/systemd/system/ollama.service.d/override.conf << 'EOF'
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_CONTEXT_LENGTH=2048"
EOFsystemctl daemon-reload && systemctl restart ollama
关键参数:
设置自动卸载
Ollama 加载模型后默认 5 分钟才卸载,期间一直占内存。改成 1 分钟:
# 在同一个 override.conf 里加
Environment="OLLAMA_KEEP_ALIVE=1m"
或者在 API 调用时指定:
curl http://localhost:11434/api/generate -d '{
"model": "phi3:mini",
"prompt": "你好",
"keep_alive": "1m",
"stream": false
}'
三、内存监控
脚本
cat > /opt/n8n/mem-monitor.sh << 'SCRIPT'
#!/bin/bashMEM_TOTAL=$(free -m | awk '/Mem:/{print $2}')
MEM_USED=$(free -m | awk '/Mem:/{print $3}')
MEM_PCT=$(free -m | awk '/Mem:/{printf "%.0f", $3/$2*100}')
SWAP_USED=$(free -m | awk '/Swap:/{print $3}')
echo "内存: ${MEM_USED}/${MEM_TOTAL}MB (${MEM_PCT}%)"
echo "Swap: ${SWAP_USED}MB"
# 内存占用 Top 5
echo ""
echo "进程内存 Top 5:"
ps aux --sort=-%mem | head -6 | awk '{printf " %-8s %sn", $4"%", $11}'
# OOM 风险判断
if [ "$MEM_PCT" -ge 90 ]; then
echo ""
echo "⚠️ 内存使用率超过 90%!"
echo "建议操作:"
echo " 1. 杀掉不用的 Docker 容器: docker stop "
echo " 2. 清理 Ollama 模型: ollama stop "
echo " 3. 清理系统缓存: sync && echo 3 > /proc/sys/vm/drop_caches"
fi
SCRIPT
chmod +x /opt/n8n/mem-monitor.sh
配合 cron 使用
# 每 30 分钟检查一次
(crontab -l 2>/dev/null; echo "*/30 * * * * bash /opt/n8n/mem-monitor.sh >> /var/log/mem-check.log 2>&1") | crontab -
四、任务队列(防止并发撑爆)
问题
n8n 如果同时触发多个工作流(比如你设了 3 个工作流都在早上 8 点跑),Ollama 会尝试并行处理,内存直接爆。
解决:用队列串行执行
在 n8n 设置里:
# docker-compose.yml 里加
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_URL=redis://redis:6379
- N8N_CONCURRENCY_PRODUCTION_LIMIT=1
- GENERIC_TIMEZONE=Asia/Shanghai
- TZ=Asia/Shanghai
加上 Redis:
services:
n8n:
# ... 原有配置
depends_on:
- redis
redis:
image: redis:7-alpine
container_name: n8n-redis
restart: unless-stopped
command: redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru
deploy:
resources:
limits:
memory: 64M
N8N_CONCURRENCY_PRODUCTION_LIMIT=1 保证同一时间只有一个工作流在跑,其他的排队等。
五、失败自动重试
工作流级别的配置
n8n 每个节点都支持错误重试:
1. 点开节点设置
2. On Error → Retry
3. Max Retries → 3
4. Retry Interval → 30s(或指数退避)
脚本层面的重试
#!/bin/bash
# 带重试的 Ollama 调用call_ollama() {
local prompt="$1"
local max_retries=3
local retry=0
while [ $retry -lt $max_retries ]; do
response=$(curl -s -m 120 http://127.0.0.1:11434/api/generate
-d "{"model":"phi3:mini","prompt":"$prompt","stream":false}" 2>/dev/null)
if [ $? -eq 0 ] && [ -n "$response" ]; then
echo "$response"
return 0
fi
retry=$((retry + 1))
echo "调用失败,第 $retry 次重试..."
sleep $((retry * 10)) # 指数退避
done
echo "错误:调用 Ollama 失败,已重试 $max_retries 次"
return 1
}
# 使用
result=$(call_ollama "总结一下今天的新闻")
关键:
六、Swap 配置
2G 内存的机器,强烈建议加 Swap。虽然慢,但比 OOM 强。
# 创建 2G Swap 文件
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile# 写入 fstab 持久化
echo '/swapfile none swap sw 0 0' >> /etc/fstab
# 调整 swappiness(降低对 swap 的依赖)
sysctl vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.conf
vm.swappiness=10 的意思是:只有内存真的不够了才用 swap,平时尽量用物理内存。
七、日常维护
每周清理
cat > /opt/n8n/weekly-cleanup.sh << 'SCRIPT'
#!/bin/bash
# 每周清理脚本echo "=== $(date) 清理开始 ==="
# 停止不用的容器
docker ps -a --filter "status=exited" -q | xargs -r docker rm
echo "已清理停止的容器"
# 清理悬空镜像
docker image prune -f
echo "已清理悬空镜像"
# 清理 n8n 旧执行记录
sqlite3 /opt/n8n-data/database.sqlite "DELETE FROM execution_data WHERE createdAt < datetime('now', '-7 days');"
echo "已清理 7 天前的执行记录"
# 清理系统日志
journalctl --vacuum-time=3d
echo "已清理 3 天前的系统日志"
echo "=== 清理完成 ==="
SCRIPT
chmod +x /opt/n8n/weekly-cleanup.sh
# 每周日 3 点执行
(crontab -l 2>/dev/null; echo "0 3 * * 0 bash /opt/n8n/weekly-cleanup.sh >> /var/log/cleanup.log 2>&1") | crontab -
总结:2G 机器的配置清单
| 项目 | 推荐值 |
|
|
— |
|---|---|
| 模型 | phi3:mini 或 qwen2.5:1.5b |
| 上下文窗口 | 2048 |
| 并发数 | 1 |
| n8n 内存限制 | 256MB |
| Redis 内存限制 | 64MB |
| Swap | 2GB |
| swappiness | 10 |
| 工作流执行间隔 | 至少间隔 15 分钟 |
| 执行记录保留 | 3 天 |
按这个配,2G 机器跑一个轻量 AI Agent 问题不大。但别指望它能跑 7B 模型同时处理长文本——那是 8G 以上机器的事。
量力而行,够用就行。