1. 为什么“会说话”的 AI 到了你电脑上还是得自己动手
很多人第一次用大模型都有种落差感:聊得挺热闹,真让它干点活,它给你一段“操作建议”,然后活还是你的。比如你说“帮我把下载目录里的 PDF 按月份归档”,它回你一段 Python 思路,你还得自己复制、装依赖、改路径、跑脚本。问题不在模型笨,而在于传统对话式 AI 只有“嘴”,没有“手”——它拿不到你本地的文件系统、终端和浏览器。
OpenClaw 这类本地优先 AI Agent 想解决的就是这一段。它把大模型当成大脑,再给它接上工具调用能力:读写文件、执行 shell、访问网页、调用 API,让模型从“给建议”变成“真执行”。而 Ollama 负责把模型跑在你自己的机器上,数据不出本地,断网也能用。两者组合起来,就是一套完整的“本地会干活”链路。
这篇面向三类人:一是想入门 AI Agent 但被各种框架劝退的开发者;二是对数据隐私敏感、不想把文件传到云端的个人用户;三是想在自己电脑上跑通一个最小可执行 Agent 的折腾党。目标很明确——不聊概念,直接给你能复制的 Ollama 拉取命令、OpenClaw 配置片段,以及一次真实的任务执行验证,让你在本地看到 Agent 真的动了手。
需要提前说清楚一个边界:本地 Agent 能操作你的文件系统和终端,权限很大。建议先在测试目录或 Docker 沙箱里跑,别一上来就对着主力工作目录下指令。下面所有操作我都按“可回滚、可隔离”的思路来写。
2. 前置准备:Ollama 拉模型与 TaoToken 接入配置
先说模型侧。Ollama 的安装很直接,macOS 和 Linux 用一条脚本,Windows 下官方安装包即可。装完后确认服务在跑:
ollama --version ollama serveollama serve默认监听127.0.0.1:11434,这是本地 Agent 调用模型的入口。接着拉一个支持工具调用(tool calling)的模型,这是 Agent 能不能“干活”的关键——不是所有模型都能稳定输出结构化的工具调用请求。实测下来,Qwen 系列和 Llama 系列的 instruct 版本对 function calling 支持较好:
ollama pull qwen2.5:7b ollama pull llama3.1:8b拉完后验证模型能正常对话:
ollama run qwen2.5:7b "用一句话说明你能调用工具吗"如果显存或内存有限,7B/8B 量化版在 16G 内存的机器上能跑,但复杂任务会慢。想更稳,可以用 14B 以上,代价是响应时间变长。
再说接入层。OpenClaw 本身是 Agent 框架,它需要一个模型后端。你可以纯本地用 Ollama,也可以在需要更强推理时,把部分请求路由到云端模型。这里我用 TaoToken 作为统一接入层,原因是它提供 OpenAI 兼容的接口格式,OpenClaw 这类框架大多支持自定义 Base URL,改起来成本低。
TaoToken 的 API 地址是https://taotoken.net/api,兼容 OpenAI 的/v1/chat/completions路径。你需要在控制台创建一个 API Key,然后把它写进环境变量,别硬编码进配置文件:
export TAOTOKEN_API_KEY="sk-你的key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"模型 ID 按你实际要用的填,比如gpt-4o-mini、claude-3-5-sonnet这类。注意 Base URL 和 Model ID 必须成对出现,缺一个就会在请求时报 404 或 401。如果你只是纯本地跑,这一步可以跳过,直接用 Ollama 的http://127.0.0.1:11434/v1作为 Base URL,模型 ID 填qwen2.5:7b。
这里有个容易踩的坑:Ollama 的 OpenAI 兼容层路径是/v1,不是根路径。很多人填http://127.0.0.1:11434然后报404 page not found,就是漏了/v1。同理,TaoToken 的 Base URL 填到/api即可,框架会自动拼/v1/chat/completions,别自己重复加。
3. 可复制配置:OpenClaw 的 settings 与工具声明片段
OpenClaw 的配置核心是两块:模型后端和工具集。下面给一份可直接改的 JSON 配置,路径按你本地实际安装目录调整。假设配置文件在~/.openclaw/config.json:
{ "model": { "provider": "openai-compatible", "base_url": "http://127.0.0.1:11434/v1", "api_key": "ollama", "model_id": "qwen2.5:7b", "temperature": 0.2, "max_tokens": 2048 }, "fallback_model": { "provider": "openai-compatible", "base_url": "https://taotoken.net/api", "api_key": "${TAOTOKEN_API_KEY}", "model_id": "gpt-4o-mini" }, "tools": { "filesystem": { "enabled": true, "root": "/Users/yourname/agent_workspace", "read_only": false }, "shell": { "enabled": true, "timeout_seconds": 30, "allowlist": ["ls", "mkdir", "mv", "cp", "find", "cat"] }, "http": { "enabled": true, "timeout_seconds": 15 } }, "agent": { "max_steps": 8, "verbose": true } }几个关键点解释一下。root把文件系统工具限制在agent_workspace目录内,Agent 无法越界访问你的整个硬盘,这是最基本的安全边界。allowlist只放行安全的只读或整理类命令,别一上来就开rm、curl这种。max_steps限制单次任务的最大工具调用轮数,防止模型陷入死循环把 token 烧光。
如果你用 TOML 格式(部分 OpenClaw 版本支持),等价写法是:
[model] provider = "openai-compatible" base_url = "http://127.0.0.1:11434/v1" api_key = "ollama" model_id = "qwen2.5:7b" temperature = 0.2 [tools.filesystem] enabled = true root = "/Users/yourname/agent_workspace" read_only = false [tools.shell] enabled = true timeout_seconds = 30 allowlist = ["ls", "mkdir", "mv", "cp", "find", "cat"]配置写完后,先做一次“干跑”验证:只加载配置、不执行任务,看模型和工具是否都能正常初始化。OpenClaw 一般有--dry-run或validate子命令:
openclaw validate --config ~/.openclaw/config.json如果输出里能看到model: ok、tools: filesystem, shell, http,说明配置结构没问题。这一步能提前拦掉大部分拼写错误和路径错误,比直接跑任务再报错省时间。
4. 验证请求:一次真实的任务执行与成功结果
现在到了最关键的一步——让 Agent 真的干活。我在agent_workspace里造了一堆乱文件来模拟真实场景:
mkdir -p ~/agent_workspace cd ~/agent_workspace touch report_2024_01.pdf report_2024_02.pdf invoice_2024_01.txt \ photo_a.jpg photo_b.png notes.md script.py ls然后给 OpenClaw 下一条自然语言指令:
openclaw run --config ~/.openclaw/config.json \ "把当前目录下的文件按扩展名分类,分别放进 pdf、txt、image、code 四个子文件夹,完成后列出每个文件夹里的文件"执行时你会看到 Agent 的思考过程(因为开了verbose):它先调用filesystem.list拿到目录内容,然后规划出分类规则,接着连续调用shell.mkdir建目录、shell.mv移动文件,最后再ls一次确认结果。整个过程不需要你写一行脚本。
成功输出大致是这样:
[step 1] tool=filesystem.list result=7 files found [step 2] tool=shell.mkdir args=["pdf","txt","image","code"] result=ok [step 3] tool=shell.mv args=["report_2024_01.pdf","pdf/"] result=ok ... [final] 已完成。pdf/ 含 2 个文件,txt/ 含 1 个,image/ 含 2 个,code/ 含 2 个。验证一下真实结果:
find ~/agent_workspace -type f | sort你应该看到文件确实被分到了四个子目录里。这一步的意义在于:模型不只是“说”它分类了,而是通过工具调用真的改了磁盘状态。这就是“会说话”到“会干活”的分界线。
如果你想验证云端 fallback 是否生效,可以把本地 Ollama 停掉,再跑一次同样的指令,观察它是否自动切到 TaoToken 的模型继续执行。切换成功的话,日志里会出现fallback_model activated。这个机制在本地模型处理复杂任务力不从心时很有用——简单整理用本地,复杂推理走云端。
5. 常见报错排查:401、local proxy failed 与 reading choices
跑本地 Agent 最容易卡在几个固定报错上,我按实际遇到的频率排一下。
401 Unauthorized:九成是 API Key 没读到。如果你用${TAOTOKEN_API_KEY}这种环境变量写法,确认它在当前 shell 里真的 export 了,echo $TAOTOKEN_API_KEY能看到值。另一个常见原因是 Base URL 和 Key 不匹配——把 Ollama 的地址配了 TaoToken 的 Key,或者反过来。检查base_url和api_key是否属于同一后端。
local proxy failed / connection refused:这个报错说明 Agent 连不上模型服务。先确认ollama serve在跑,再curl http://127.0.0.1:11434/v1/models看有没有返回模型列表。如果 curl 通但 Agent 不通,多半是配置里的base_url少了/v1,或者端口写错。Docker 里跑 Agent 的话,127.0.0.1指向容器自身,要用host.docker.internal才能访问宿主机上的 Ollama。
Error reading choices / choices field missing:这是响应格式解析失败。原因通常是模型返回的不是标准 OpenAI 格式,或者返回了空内容。本地小模型在工具调用时偶尔会输出非结构化文本,导致框架解析choices[0].message.tool_calls时拿到 null。解决办法有两个:一是换工具调用能力更强的模型,二是把temperature调低到 0.1 以下,减少模型“自由发挥”。如果用的是 TaoToken,确认model_id拼写正确,写错的模型名有时会返回一个错误结构,被框架误当成正常响应去解析choices。
OAuth / token expired:如果你接的是需要 OAuth 的后端,token 过期后会报这个。重新走一遍授权流程拿新 token 即可。纯 API Key 模式不会遇到这个问题。
排查顺序建议固定下来:先curl直连模型服务确认通不通,再看配置文件字段是否成对,最后看模型本身是否支持工具调用。这三步能覆盖 90% 的启动失败。
6. 把本地 Agent 用顺手的几个实操建议
跑通最小链路之后,真正决定体验的是细节。第一,给不同任务配不同模型:文件整理、格式转换这类确定性任务用本地 7B 就够,省 token 也快;涉及多步推理、需要理解模糊指令的,切到云端模型。OpenClaw 的 fallback 机制正好支持这种分层。
第二,工具权限按最小必要开。我一开始图省事把 shell 全开了,结果模型有一次试图执行一个带通配符的mv,差点把测试目录外的文件也扫进去。后来改成 allowlist 加固定 root,再没出过意外。本地 Agent 的能力越强,边界就越要画清楚。
第三,善用max_steps和超时。模型偶尔会陷入“调用工具→看结果→再调用”的循环,尤其是任务描述模糊的时候。设一个合理的步数上限,超了就让它停下来汇报当前进度,比无限跑下去强。
第四,日志一定开 verbose。Agent 的价值在于过程可观测,你能看到它每一步调了什么工具、传了什么参数、拿到什么结果。出问题时这些日志就是排查依据,比猜模型在想什么高效得多。
如果你想把这条链路用到日常编码或长期自动化任务上,可以进一步了解 Coding Plan 这类面向持续任务的方案;需要统一管理多个模型的 Key 和额度,API Keys 页面能集中处理;想先直观感受不同模型在工具调用上的差异,模型对话入口可以直接对比。接入细节和字段说明都在接入文档里,配置前扫一遍能少走弯路。
本地优先 Agent 这条路,门槛没有想象中高,但坑都集中在配置和权限这两块。把 Ollama 跑起来、把 OpenClaw 的工具边界画好、用一条真实任务验证闭环,剩下的就是按自己的场景慢慢加技能了。