
Hermes-Agent 对接本地Ollama大模型完全离线运行最近我一直在折腾 Hermes-Agent 和 Ollama 这套组合。Hermes-Agent 是一个代码优先的 agent 框架用 YAML 定义 agent 的行为靠函数调用function calling让大模型决定下一步该执行什么工具而 Ollama 是目前最省心的本地大模型运行工具一条命令就能把 Qwen、Llama 这些模型拉起来跑。把这两个东西接到一起你就能得到一套完全离线运行的大模型 agent 系统——不依赖云端 API、数据不出本机、断网也能正常工作。这篇文章我打算把 Hermes-Agent 对接本地 Ollama 的完整过程、环境变量的配置方式、模型选型建议、常见问题排查全部讲清楚。不管你是第一次接触 agent 框架的新手还是已经在用 Hermes-Agent 但苦于无法离线运行的开发者这套方案都可以直接照着做。1. Hermes-Agent 与 Ollama为什么值得放在一起1.1 Hermes-Agent 是什么它的核心设计理念怎么理解Hermes-Agent 是由 NousResearch 社区推动的一个 agent 框架它的核心思路和 LangChain 这类重框架不太一样。它更接近“代码优先”的哲学你用 YAML 文件去定义 agent 的性格、任务目标、可用的工具函数然后框架会自动把函数定义注入到系统提示词里让大模型在每次对话时决定要调用哪个函数、传什么参数。整个过程是“模型驱动”的agent 的下一步动作不是写死的而是由模型根据当前上下文实时决策。我刚开始接触的时候也犯过迷糊以为 Hermes-Agent 和 AutoGPT 差不多。实际上差别很大。AutoGPT 更像是自己给自己拆解任务Hermes-Agent 更像是你给 agent 一套工具箱然后告诉它“你看着办”。这两种模式在工程落地上的差别是Hermes-Agent 的行为更可控函数都是你提前定义好的模型只能在白名单里选不会出现模型自己编造工具的情况这在离线生产环境里非常关键。再说一个容易被忽略的点Hermes-Agent 对模型的函数调用能力要求相当高。如果你的模型不支持 tool calling或者支持得不标准agent 就会“大脑空白”明明工具就在那里却不会用。这也是为什么挑选合适的本地模型是整个方案里最重要的一步后面我会单独用一节来讲模型选型。1.2 为什么选 Ollama 做本地推理而不是 vLLM 或 llama.cpp本地跑大模型的工具那么多vLLM 性能强、llama.cpp 跨平台、LM Studio 界面友好为什么我最终选了 Ollama最直接的原因是Ollama 把“模型管理”这件事做得太顺手了。我用 vLLM 的时候要自己处理模型格式转换、量化、启动参数用 llama.cpp 的时候要自己编译、下载 GGUF 文件、手动写启动命令。而 Ollama 一条ollama pull qwen2.5:7b就把模型下载好了一条ollama serve就把服务拉起来了还默认提供了一个 OpenAI 兼容接口这让 Hermes-Agent 对接变得非常简单——我只需要把base_url指向本地端口就行不需要写任何自定义适配层。另外Ollama 在资源受限环境下的表现也很稳。它支持 GPU 加速、CPU 推理、量化模型加载还能自动决定把模型层分配到哪块显存。我在一台只有 8GB 显存的机器上跑 7B 量级模型Ollama 能通过部分卸载把模型塞进去跑起来换成 vLLM 的话大概率直接爆显存。当然 Ollama 也有短板并发吞吐能力不如 vLLM不适合做大规模线上推理服务。但 Hermes-Agent 这种单用户、交互式 agent 场景根本吃不满 Ollama 的性能。反而是 Ollama 的简单直接让整个离线部署的维护成本降到了最低。我后面会专门讲 vLLM 和 llama.cpp 不选它们的具体理由这里先记住结论Ollama 适合从 0 到 1 快速跑通 agent 离线方案vLLM 适合从 1 到 100 做规模化服务。1.3 对接后的整体运行架构这套方案跑起来之后整个架构其实非常清爽只有三层第一层是用户交互层也就是 Hermes-Agent 自带的 Web UI 或者 API 服务。你可以通过浏览器和 agent 对话也可以通过 HTTP 接口让其他系统调用 agent。第二层是 agent 决策层就是 Hermes-Agent 本身。它负责维护对话历史、解析用户的指令、把可用的函数列表塞给模型、接收模型的函数调用请求并执行对应的 Python 函数。第三层是模型推理层就是 Ollama。它监听在localhost:11434对外提供一个 OpenAI 兼容的/v1/chat/completions接口。Hermes-Agent 通过 HTTP 请求把对话数据发给 OllamaOllama 在本地完成推理后把结果返回。这三层之间全部通过 localhost 通信不经过任何外部网络所以只要模型已经下载到本地、Hermes-Agent 和 Ollama 都装好整个系统就可以在完全离线状态下运行。注意离线运行并不意味着安装阶段不需要联网。Ollama 安装包和模型文件都需要提前下载好Hermes-Agent 的 Python 依赖也需要在联网状态下安装。合理做法是在有网的机器上准备好一切再迁移到离线环境具体步骤我放在下一节。2. 环境准备与离线部署的前置工作2.1 Ollama 的安装与模型预下载先把 Ollama 装好。Ollama 官方提供了 Windows、macOS、Linux 三平台的安装包Linux 上也可以用一键脚本安装。安装完成后在终端里执行ollama serve看到listening on 127.0.0.1:11434的日志就说明服务已经起来了。接下来下载模型这一步必须在能联网的机器上完成。Hermes-Agent 依赖模型的函数调用能力所以我建议优先选官方明确支持tools调用的模型。以 7B~9B 量级为例我实测下来比较稳的有这几个模型参数量中文能力函数调用能力显存建议qwen2.5:7b7B很强好8GB 可跑qwen3:8b8B很强好8GB 可跑llama3.1:8b8B一般好8GB 可跑gemma2:9b9B一般较好12GB 更稳qwen2.5:3b3B较好中等4GB 可跑下载命令很简单ollama pull qwen2.5:7b如果网络下载速度不理想可以找一个可靠的镜像站点提前把模型文件下载好或者利用别的机器下载后再拷贝。Ollama 的模型文件存放在用户目录下的.ollama/models文件夹里Windows 默认在C:\Users\用户名\.ollama\modelsLinux/macOS 默认在~/.ollama/models你可以把整个models目录打包拷贝到离线机器的相同位置Ollama 会自动识别。注意Ollama 的模型存储目录和版本号绑定如果离线机器上的 Ollama 版本和下载模型时的版本不一致可能出现模型无法加载的情况。建议在迁移模型时把 Ollama 的版本也记下来尽量保持一致。2.2 Hermes-Agent 的安装与项目结构Hermes-Agent 是一个 Python 项目安装方式很常规。先确保本机有 Python 3.10 以上版本然后克隆代码仓库并安装依赖git clone https://github.com/NousResearch/Hermes-Agent.git cd Hermes-Agent pip install -r requirements.txt装完后看一眼项目结构有几个关键目录你要心里有数agents/存放 YAML 格式的 agent 定义文件。每个文件就是一个人设/工作流配置框架默认带了一些示例 agent。functions/存放可调用的工具函数默认有check_time、search_web、run_shell_command之类的示例。你可以在这个目录里加自己的 Python 函数框架会自动扫描并注册。config/存放工程配置。local_server/如果你不想用 Web UI可以起一个 API 服务这个目录里就是相关实现。Hermes-Agent 的设计理念是“用文件定义你的 agent”所以大部分时间你都是在跟 YAML 和 Python 函数打交道。它没有像 LangChain 那样复杂的 chain/agent 抽象层反而更好理解一个 agent 一个 YAML 一组函数工具。注意如果pip install过程中遇到依赖冲突大概率是 transformers 或 torch 的版本问题。建议用虚拟环境安装避免污染系统 Python 环境。2.3 离线部署的完整迁移清单当你准备把整套系统搬到离线环境时按照这个清单检查一遍缺一不可Ollama 安装包目标系统的对应版本Ollama 模型存储目录.ollama/models的完整拷贝Hermes-Agent 项目代码或者一个 Git 打包文件Hermes-Agent 所需的 Python 依赖包在联网机器上执行pip download -r requirements.txt把.whl文件都下载下来离线环境再pip install *.whl已经配置好的环境变量脚本我做离线迁移的时候最常翻车的就是 Python 依赖。一个项目几十个包每个包又有传递依赖如果没有提前把.whl全部下载好到了离线环境根本装不上。建议用pip download -r requirements.txt -d ./offline_packages把依赖完整拉下来然后离线环境执行pip install --no-index --find-links./offline_packages -r requirements.txt这样就绕开了网络限制。3. 配置对接让 Hermes-Agent 吃上本地模型3.1 环境变量的配置方法与关键参数解析Hermes-Agent 通过环境变量来指定要使用的大模型服务商。对接 Ollama 时核心是配置三个环境变量export HERMES_LLM_MODELqwen2.5:7b export HERMES_LLM_BASE_URLhttp://localhost:11434/v1 export HERMES_LLM_API_KEYollama逐个解释一下HERMES_LLM_MODEL就是模型名称要和ollama list里显示的 tag 完全一致写成qwen2.5:7b这种带版本号的形式。HERMES_LLM_BASE_URL指向 Ollama 的 OpenAI 兼容接口。注意末尾要带/v1不带会报路径错误。HERMES_LLM_API_KEY填什么都可以Ollama 不校验 key但 Hermes-Agent 要求这个字段非空。填ollama或sk-no-key-required都行。如果你用的是 Windows环境变量设置方式略有不同$env:HERMES_LLM_MODELqwen2.5:7b $env:HERMES_LLM_BASE_URLhttp://localhost:11434/v1 $env:HERMES_LLM_API_KEYollama配置完之后启动 Hermes-Agent如果能在日志里看到类似Connected to LLM provider的信息就说明对接成功了。注意我遇到过一种情况环境变量配了但 Hermes-Agent 没走 Ollama而是去请求官方 API。这是因为 Hermes-Agent 里还支持通过.env文件读取配置如果你项目根目录有一个.env文件里面残留了旧的HERMES_LLM_API_KEY它会被优先读取。排查时先把.env里的配置清掉再用终端里 export 的环境变量。3.2 验证 Hermes-Agent 是否能正确调用本地模型的函数功能对接完成之后别急着跑复杂场景先做一个最简单的函数调用验证。Hermes-Agent 自带了check_time这样的示例函数我一般直接让 agent 问“现在几点了”看它能不能正确触发时间查询函数。如果模型返回的不是函数调用而是一大段自然语言说明说明函数调用链路有问题。我在实际验证时遇到过三种情况第一种模型根本不认识函数。这种情况通常是HERMES_LLM_MODEL配错了模型或者模型本身不支持 tool calling。比如某些纯对话模型你给它函数列表它也只会说“我无法获取当前时间”。第二种模型理解函数了但工具执行环节报错。这往往是函数代码本身的问题需要去 Hermes-Agent 的日志里看具体的报错堆栈。第三种函数执行成功但结果没有回传给模型。这种情况比较隐蔽表现为工具执行结果已经拿到了但模型的下一轮回复还是“我在思考中”。多半是 Ollama 的 context length 设置太小函数返回结果太长被截断了。解决办法是给 Ollama 设置更大的上下文窗口后面我会在性能调优里详细说。3.3 完全离线环境下的启动流程离线机器的启动流程我已经形成一个肌肉记忆了按顺序执行就行# 1. 启动 Ollama 服务 ollama serve # 2. 确认模型已经可见 ollama list # 3. 设置环境变量 export HERMES_LLM_MODELqwen2.5:7b export HERMES_LLM_BASE_URLhttp://localhost:11434/v1 export HERMES_LLM_API_KEYollama # 4. 启动 Hermes-Agent python -m local_server.app这里有一个细节Ollama 的serve默认只监听127.0.0.1这就够了因为 Hermes-Agent 和 Ollama 都在同一台机器上。如果你想让局域网内其他机器也能访问 agent我建议只把 Hermes-Agent 的 API 服务暴露到局域网Ollama 继续保持只监听本机。这样做的好处是别人只能通过 agent 的 API 来交互不能直接访问底层模型服务安全性更好。我实测下来这套流程在两台不同的离线机器上跑过一台是 NVIDIA 3060 12GB一台是纯 CPU 的办公主机。GPU 机器跑 qwen2.5:7b 很流畅CPU 机器跑 qwen2.5:3b 也能用就是单轮响应要等十几秒。如果你要在 CPU 机器上跑建议把上下文长度调小一点响应速度会明显提升。4. 常见问题与排查技巧实录4.1 Ollama 连接失败提示 connection refused这是小白最容易踩的坑。connection refused基本就是 Ollama 服务没起来。执行ollama serve启动之后再用curl http://localhost:11434/api/tags测一下能返回 JSON 就说明服务正常。另一个容易忽略的情况是Hermes-Agent 跑在 Docker 容器里而 Ollama 跑在宿主机上。这种情况localhost:11434指向的是容器内部访问不到宿主机的服务。解决办法是改用host.docker.internal作为宿主机地址或者在启动 Docker 容器时加上--network host。我还遇到过一种情况Ollama 服务看起来是在跑的但端口被其他进程占了。用netstat -ano | findstr 11434Windows或lsof -i :11434Linux/macOS查一下端口占用如果被别的程序占用了改 Ollama 的监听端口即可。4.2 函数调用不生效agent 只会说不会做如果 agent 能正常对话但从来不触发工具函数问题大概率出在模型本身。Ollama 对函数调用的支持是模型级别的不是所有模型都支持。你要确认两件事第一模型是否支持 tool calling。在 Ollama 中运行ollama show qwen2.5:7b看输出里有没有tools相关的能力标注。也可以在对话里用一条消息测试curl http://localhost:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5:7b, messages: [{role: user, content: 查看当前时间}], tools: [{type: function, function: {name: check_time, description: 获取当前时间, parameters: {type: object, properties: {}}}}] }如果返回的finish_reason是tool_calls说明函数调用链路是通的如果返回的是普通文本说明模型压根没走函数调用分支。第二Hermes-Agent 的函数名和描述是否足够清晰。YAML 里定义的函数描述如果太模糊模型就不知道该在什么情况下调用。比如函数描述写“获取时间信息”模型可能会觉得所有问题都沾点边就触发调用反而把对话带偏。实操心得我后来把函数描述写得像“给一个完全不懂技术的人看的功能说明”一样具体调用准确性明显提升。例如不要写“执行计算”要写“当用户需要数学计算时传入表达式并返回计算结果。适用场景加减乘除、百分比、单位换算等”。4.3 内存不足 / 模型加载失败 / 显存溢出模型加载失败分两种情况。第一种是显存不够模型太大。Ollama 日志里会出现类似CUDA out of memory的报错。解决办法有三个换更小的模型比如 7B 换 3B、使用量化模型Ollama 默认拉取的是 Q4_K_M 量化版本已经比较省显存了、调整 Ollama 的并发加载策略。第二种是 CPU 内存不够。这种情况多出现在纯 CPU 机器上跑 7B 以上模型。7B 模型的全精度版本大约占用 14GB 内存即使量化后也要 6GB~8GB。如果机器内存只有 8GB可以考虑把上下文长度调小或者选 3B 模型。关于上下文长度Ollama 默认的 context length 可能是 2048 或 4096这对 agent 场景来说有点紧张。Hermes-Agent 每次请求要带函数定义列表、完整对话历史token 消耗很快。我建议在启动 Ollama 时显式设置OLLAMA_CONTEXT_LENGTH8192 ollama serve或者在模型层面设置num_ctx参数ollama run qwen2.5:7b --num-ctx 8192设置之后agent 能记住的上下文变多了函数调用结果的截断问题也会缓解。4.4 Hermes-Agent 与 Ollama 配合时的性能调优经验性能调优这块我踩过很多坑总结下来就三条主线。第一减少不必要的上下文膨胀。Hermes-Agent 每次对话都会把函数定义列表塞给模型如果你的函数列表很长每个函数描述又很啰嗦模型每轮请求都要处理大量 token响应自然就慢。建议只保留当前 agent 真正会用到的函数用不到的函数直接从functions/目录移除或者通过 YAML 配置过滤掉。第二合理利用 Ollama 的并发请求能力。Ollama 默认支持并发请求但并发过高时显存会快速占满。如果你在跑 agent 的同时还想用同一个 Ollama 实例跑其他任务建议打开 Ollama 的OLLAMA_NUM_PARALLEL环境变量并设置一个较小的值比如 2。数值过大反而会因为显存竞争导致所有请求都变慢。第三在 CPU 机器上启用更积极的量化。如果你的离线机器没有 GPU跑 7B 模型很吃力不妨换用 qwen2.5:3b 或者更小的模型。我在实际项目中把 CPU 机器上的模型从 7B 降到 3B 之后响应时间从 20 多秒降到了 8 秒左右agent 的功能完整性反而提升了不少因为模型不会频繁超时整体体验更顺。注意性能调优是个持续过程不要期望一步到位。建议每次只改一个参数跑一轮真实对话观察响应时间和显存/内存占用再决定下一步调整方向。4.5 常见问题速查表现象可能原因排查方向连接被拒绝Ollama 服务未启动执行ollama serve用 curl 测试端口模型不存在模型未下载或名称错误执行ollama list确认 tagagent 无法触发函数模型不支持 tool calling检查模型能力换带函数调用支持的模型函数执行报错函数代码本身有 Bug查看 Hermes-Agent 日志堆栈响应被截断上下文窗口太小调大num_ctx/OLLAMA_CONTEXT_LENGTH显存溢出模型过大或并发过高换小模型 / 降低并行数 / 使用量化模型配置不生效.env文件覆盖了环境变量检查项目根目录.env5. 实操案例与经验汇总5.1 一个离线的文件管理 agent 示例前面讲了一堆理论和配置我这里用一个真实的离线 agent 示例来收尾方便你理解整个链路是怎么跑通的。假设你想让 agent 帮忙管理一个本地目录比如“帮我把目录下所有超过 100MB 的文件列出来”。我会这么做第一步在functions/目录下新建一个file_tools.py定义两个函数import os from pathlib import Path from typing import List, Dict def list_large_files(directory: str, size_mb: int 100) - List[Dict]: 列出指定目录下超过指定大小(MB)的文件。参数directory 目录路径size_mb 文件大小阈值。 result [] for root, dirs, files in os.walk(directory): for name in files: file_path Path(root) / name size file_path.stat().st_size / (1024 * 1024) if size size_mb: result.append({path: str(file_path), size_mb: round(size, 2)}) return result第二步在 agent 的 YAML 配置文件里把file_tools声明为可用工具并写清楚使用规则。第三步启动 Hermes-Agent在 Web UI 里输入“帮我看看 D 盘 work 目录下有没有超过 100MB 的文件”。正常情况下agent 会先理解用户意图然后调用list_large_files函数把结果以表格或文本形式返回给你。整个过程模型只负责“决定调用什么函数”具体的文件操作由 Python 函数完成。这样即使模型出现幻觉它也没有能力直接操作系统文件只能通过你定义好的函数白名单来间接操作安全性可控。5.2 我在实际使用中的几条经验心得第一先用小模型跑通流程再上大模型。我刚开始用 Hermes-Agent 对接 Ollama 时直接拉了一个 13B 模型结果每次调试函数调用都要等很久迭代效率极低。后来我先用 3B 模型把整个链路跑通确认函数调用、对话、错误处理都没问题再切换到 7B 模型效率高了很多。第二离线环境尽量不升级任何组件。Hermes-Agent、Ollama、Python 依赖这几个东西一旦在离线环境跑通了就固定版本不要轻易升级。我踩过一次坑把 Ollama 升级了一个小版本结果模型文件格式不兼容所有模型都要重新下载在离线环境差点卡死。第三做好日志和监控。Ollama 和 Hermes-Agent 都支持日志输出建议把日志级别调成 DEBUG 并定时清理。如果你在离线环境跑的是生产任务最好给 Hermes-Agent 设置一个定时健康检查脚本每隔几分钟请求一次本地 API如果响应超时就自动重启相关服务。5.3 后续可以扩展的方向Hermes-Agent 对接 Ollama 跑通之后后续的扩展空间其实很大。你可以给 agent 增加更多本地工具比如文件搜索、数据库查询、Shell 命令执行、本地知识库检索等。只要在functions/里定义好函数在 YAML 里声明好规则模型就能自动学会使用这些工具。你还可以把 Hermes-Agent 作为一个后台服务通过它的 API 接口对接其他业务系统。比如做一个定时任务让 agent 每天早上自动读取本地日报文件、调用本地统计函数生成摘要、再输出到指定目录。整个过程完全离线运行不依赖任何外部 API对于数据敏感的办公环境非常友好。如果追求更好的性能还可以把 Ollama 换成 vLLM 或 SGLang 这类高性能推理服务只是配置复杂度会高一些。但如果你只是个人使用或者小团队用Ollama 完全够用了真的没必要为了性能去增加部署复杂度。我自己在这套组合上已经稳定跑了好几个月一直没出过什么大问题最主要的还是模型本身的输出质量在决定体验上限。