Hermes-Agent对接Ollama:完全离线的本地大模型Agent实战
2026/9/20 17:49:33 网站建设 项目流程

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 请求把对话数据发给 Ollama,Ollama 在本地完成推理后把结果返回。

这三层之间全部通过 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\models
  • Linux/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_timesearch_webrun_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 离线部署的完整迁移清单

当你准备把整套系统搬到离线环境时,按照这个清单检查一遍,缺一不可:

  1. Ollama 安装包(目标系统的对应版本)
  2. Ollama 模型存储目录(.ollama/models的完整拷贝)
  3. Hermes-Agent 项目代码(或者一个 Git 打包文件)
  4. Hermes-Agent 所需的 Python 依赖包(在联网机器上执行pip download -r requirements.txt,把.whl文件都下载下来,离线环境再pip install *.whl
  5. 已经配置好的环境变量脚本

我做离线迁移的时候,最常翻车的就是 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_MODEL="qwen2.5:7b" export HERMES_LLM_BASE_URL="http://localhost:11434/v1" export HERMES_LLM_API_KEY="ollama"

逐个解释一下:

  • HERMES_LLM_MODEL就是模型名称,要和ollama list里显示的 tag 完全一致,写成qwen2.5:7b这种带版本号的形式。
  • HERMES_LLM_BASE_URL指向 Ollama 的 OpenAI 兼容接口。注意末尾要带/v1,不带会报路径错误。
  • HERMES_LLM_API_KEY填什么都可以,Ollama 不校验 key,但 Hermes-Agent 要求这个字段非空。填ollamask-no-key-required都行。

如果你用的是 Windows,环境变量设置方式略有不同:

$env:HERMES_LLM_MODEL="qwen2.5:7b" $env:HERMES_LLM_BASE_URL="http://localhost:11434/v1" $env:HERMES_LLM_API_KEY="ollama"

配置完之后,启动 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_MODEL="qwen2.5:7b" export HERMES_LLM_BASE_URL="http://localhost:11434/v1" export HERMES_LLM_API_KEY="ollama" # 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 11434(Windows)或lsof -i :11434(Linux/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_reasontool_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_LENGTH=8192 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确认 tag
agent 无法触发函数模型不支持 tool calling检查模型能力,换带函数调用支持的模型
函数执行报错函数代码本身有 Bug查看 Hermes-Agent 日志堆栈
响应被截断上下文窗口太小调大num_ctx/OLLAMA_CONTEXT_LENGTH
显存溢出模型过大或并发过高换小模型 / 降低并行数 / 使用量化模型
配置不生效.env文件覆盖了环境变量检查项目根目录.env

5. 实操案例与经验汇总

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 完全够用了,真的没必要为了性能去增加部署复杂度。我自己在这套组合上已经稳定跑了好几个月,一直没出过什么大问题,最主要的还是模型本身的输出质量在决定体验上限。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询