
上周有个朋友问我能不能在他那台 32G 内存的笔记本上跑一个能自己动手干活的智能体不要云端接口不要数据出本机断网也能转。我第一反应是这事儿不难真动手的时候才发现从零把爱马仕Hermes Agent跑起来坑主要集中三个地方Python 依赖、模型服务对接、还有权限边界。这篇就把我这边从零安装并配置爱马仕Hermes Agent的全过程摊开讲包括那些文档里不写、但你不处理就一定卡住的细节。先说清楚这东西是什么。爱马仕Hermes Agent本质上是一个跑在本地电脑上的智能体运行时它自己不做推理而是把「想一步、做一步、看结果、再想一步」这个循环管起来把大模型的输出翻译成具体的工具调用再把工具的执行结果喂回模型。解决的是「模型只会聊天不会干活」这个问题。适合谁来参考一类是想把重复性电脑操作交给程序的人比如批量整理文件、定时抓数据、自动改代码另一类是手里已经有本地模型、想给它加手脚的人。零基础也能跟着走我会把每一步为什么这么做讲清楚你照着抄作业就行但抄之前建议先看一遍第 1 节理解骨架再动手后面排查问题会快很多。1. 先把爱马仕Hermes Agent的骨架看懂再动手装1.1 它其实就四块东西不要想复杂我见过不少人一上来就pip install装完了不知道配置文件里那堆字段是干嘛的出问题只能瞎猜。其实这个运行时掰开来看就四块Agent Loop循环、Tool Registry工具注册表、Memory记忆、Policy策略与权限。打个比方你招了个实习生。给他一张工位那是 workspace所有文件操作都限定在这个目录里给他一个工具箱那是 tools里面有读文件、跑命令、发请求这些具体本事给他一个笔记本那是 memory记着之前干过什么、你说过什么要求最后给他一本员工手册那是 policy规定哪些事能干、哪些事必须问你、哪些事碰都不能碰。模型是实习生的脑子这四块是公司的基础设施。脑子再好没有工位工具手册他也干不了活。所以安装配置的重心根本不在「装包」而在这四块的参数怎么调。1.2 为什么值得放在个人电脑上跑而不是用现成服务数据不出本机是最直接的理由。智能体干活的时候要读文件、看代码、执行命令这些东西一旦上传你就失去了控制权。本地跑意味着所有中间过程都在你自己的磁盘上日志、缓存、工具输出你想删就删。第二个理由是可调试。云端服务出问题你只能看它给你的报错本地跑你能直接翻日志、断点、改源码。我调工具参数那阵子一天要重启十几次本地环境救了我不少时间。第三个理由是成本可控。本地推理的电费是固定的跑一百次和跑一万次差别不大但按次计费的模式下智能体那种一步拆成七八步的跑法账单会很吓人。反过来说什么场景不适合本地跑需要超大参数量才能做对的复杂推理任务、需要极低首字延迟的交互场景、以及机器本身内存小于 16G 的情况。这几种老老实实用远程接口更省心。我一般的做法是双轨日常小任务走本地遇到硬骨头再切换配置文件里改一行provider的事。1.3 影响范围它会动到你电脑上的哪些东西装之前你得知道它会往哪儿写东西不然清理的时候会漏。位置内容是否可清理项目目录./workspace智能体读写的工作区文件需手动确认后清理项目目录./logs每次运行的完整轨迹日志可定期清理~/.hermes/全局配置、缓存、会话历史保留配置历史可清虚拟环境目录Python 依赖随项目删除系统临时目录工具执行产生的中间文件可清理关键点是workspace 目录。智能体的所有文件操作都应该被限制在这个目录里这是 Policy 层的核心职责。我在第一次配置的时候忘了改默认路径结果它把日志写到了我的文档目录下虽然没造成什么损失但那种「有个程序在你不知道的地方动文件」的感觉很不好。所以第 3 节的配置文件里workspace.root这个字段一定要第一时间改掉。2. 装之前的机器体检别急着敲安装命令2.1 三个硬指标内存、显存、磁盘本地智能体的性能瓶颈几乎都在内存上因为模型权重得常驻。显存决定你能不能上 GPU 加速磁盘决定你能存几个模型。先给个我实测出来的对照表按 4bit 量化估算这是目前个人电脑上性价比最高的档位模型规模4bit 量化后显存占用最低可用内存我的体验评价3B 级别约 2.5 GB16 GB能跑但工具调用格式经常出错7B 级别约 5 GB16 GB日常任务的甜点区推荐起点14B 级别约 9 GB32 GB复杂任务明显更稳值得升级32B 级别约 20 GB64 GB个人电脑的上限性价比开始下降这个数字怎么来的简单算法参数量 × 每参数字节数 × 1.2 的运行时余量。7B 模型 4bit 量化大约是每参数 0.5 字节7 × 0.5 3.5 GB 权重再乘 1.2 得 4.2 GB加上 KV Cache 和框架开销实际吃到 5 GB 左右。你按这个公式可以自己算任何模型。除了模型本身爱马仕Hermes Agent运行时还要吃 500MB 到 1GB 内存工具执行尤其是跑 Python 脚本还会额外占。所以 16G 内存的机器跑 7B 模型建议把并发设成 1别同时开太多应用。2.2 Python 版本别用最新的用最稳的这一条我踩过坑必须单独说。爱马仕Hermes Agent依赖链里有几个包对 Python 版本比较挑3.12 刚出来那阵子有个序列化库还没有预编译 wheelpip 会去现场编译然后因为本机没装编译工具链直接失败。我的建议很明确Python 3.10 或 3.11二选一别犹豫。3.10 兼容性最好3.11 性能稍好一点两者都没问题。3.9 及以下不建议有些新语法不支持3.12 及以上看运气遇到问题你会浪费半天时间在编译错误上。版本管理工具我用的是uv比conda轻比原生venv快。你要是习惯 conda 也行反正核心要求是「一个项目一个独立环境」别往系统 Python 里装东西。这一点是硬要求全局安装迟早会撞版本冲突。2.3 目录规划代码、配置、工作区三者分离我现在的习惯是三个目录分开这个习惯是被坑出来的。早期我把所有东西塞一个目录结果智能体执行清理类工具的时候差点把配置文件一起删了。~/hermes-stack/ ├── app/ # 代码本体只读不往里写东西 ├── conf/ # 配置文件单独备份 │ ├── hermes.config.yaml │ └── tools/ └── workspace/ # 智能体的手脚能碰到的地方 ├── inbox/ # 待处理文件投放区 ├── outbox/ # 产出物 └── scratch/ # 临时文件随便造这么分的道理是代码目录和配置目录设为只读权限工作区设为可读写。Policy 层配置里把allowed_paths指向 workspace其他路径一律拒绝。这样即使模型抽风让它去删根目录也会被拦下来。多花五分钟做这个分层能省掉后面无数次心惊胆战。3. 从空目录到第一条指令跑通3.1 建环境与拉取代码假设你已经把发布包下载到本地了解压后进目录。下面是我实际执行的步骤一条条来# 1. 创建并激活虚拟环境用 uv 的话 uv venv .venv --python 3.11 source .venv/bin/activate # Windows 用 .venv\Scripts\activate # 2. 确认 Python 版本没跑偏 python -V # 期望输出 Python 3.11.x # 3. 升级基础工具 python -m pip install --upgrade pip setuptools wheel # 4. 安装本体先不带可选依赖 pip install -e . # 5. 装了再验证 hermes --version第 4 步这里有个取舍要说清楚。发布包一般会提供两种安装方式pip install -e .和pip install -e .[all]。前者只装核心依赖后者会把所有可选工具浏览器自动化、文档解析、图像处理之类都装上。我建议先装核心跑通再按需补。原因是可选依赖里经常有体积大、编译难的包一次性全装中间任何一个失败都会让你分不清是核心问题还是可选问题。我第一次就是全装了卡在一个图像库的编译错误上折腾了四十分钟才发现跟我要用的功能根本没关系。3.2 依赖装不上的三类典型报错这部分是纯经验文档里不会写。第一类error: Microsoft Visual C 14.0 or greater is required。这是 Windows 上缺编译工具链。解决办法有两条路优先找预编译 wheel升级 pip 到最新一般就能拿到实在没有再装构建工具。不要一上来就装几 GB 的编译器套件先试pip install --only-binary :all: 包名能装上就说明有 wheel。第二类ResolutionImpossible版本冲突。这通常是核心包和可选包对同一个依赖要求了不同的版本区间。排查方法是先看报错里点名的是哪两个包然后手动pip install 包A版本号固定住再装其余部分。爱马仕Hermes Agent的依赖文件里一般会锁主版本冲突多半来自你环境里残留的旧包新建一个干净虚拟环境往往就好了。第三类装完了hermes命令找不到。八成是虚拟环境没激活或者 PATH 没刷新。先which hermesWindows 用where hermes确认路径在不在.venv/bin下面。不在的话用python -m hermes这个等价写法先跑起来别在 PATH 上浪费太多时间。3.3 配置文件逐字段拆解每个参数为什么这么设这是整篇文章最值得细看的部分。配置文件我按功能块拆开讲你对照着自己的机器改。# conf/hermes.config.yaml agent: name: local-hermes max_steps: 12 # 单次任务最多走几步 step_timeout: 120 # 单步超时秒 task_timeout: 900 # 整个任务超时秒 verbose: true # 开发期开着跑稳了再关 workspace: root: /home/you/hermes-stack/workspace allowed_paths: - /home/you/hermes-stack/workspace max_file_size_mb: 20 # 单文件读写上限 model: provider: openai-compatible base_url: http://127.0.0.1:8080/v1 model_name: local-7b-instruct api_key: not-needed # 本地服务通常不校验 temperature: 0.2 top_p: 0.9 max_tokens: 2048 context_window: 32768 memory: backend: sqlite path: /home/you/.hermes/memory.db max_turns_kept: 20 # 保留多少轮对话 policy: confirm_before: # 这些操作必须先问你 - shell_exec - file_delete deny_patterns: - rm -rf / - sudo sandbox: subprocess逐个说关键项。max_steps: 12。这个数是「循环上限」防止模型陷入死循环一直调工具。设太小复杂任务做不完就被掐断设太大一旦模型卡住你要等很久。12 是我试出来的平衡点覆盖了八成日常任务。简单的文件整理任务一般 3 到 5 步就结束多步信息收集类任务会用到 8 到 10 步。step_timeout: 120和task_timeout: 900。前者管单步后者管全局。为什么单步要给到 120 秒因为工具执行可能很慢比如跑一个依赖安装或者处理一个大文件。但如果某一步超过两分钟还没返回基本可以判定出问题了早点掐掉比干等好。全局 900 秒是给多步任务留的余量12 步 × 平均 60 秒再加点冗余。temperature: 0.2。这个值在智能体场景要比聊天场景低很多。聊天要发散、要有文采可以用 0.7但工具调用要求格式严格、决策稳定温度高了会出现「参数名拼错」「JSON 少个括号」这类问题。我一开始用 0.7工具调用成功率大概只有六成降到 0.2 之后稳定在九成五以上。这个调整的收益比换模型还明显。top_p: 0.9。和温度配合使用控制采样范围。一般不建议两个都往低调会把输出搞得太死板遇到需要灵活变通的步骤会僵住。0.2 0.9 这个组合是我试下来最顺的。max_tokens: 2048。单次生成的上限。工具调用场景里的输出很短但模型有时候会啰嗦地解释一大段再给调用2048 够用。设太大有个隐患万一模型跑飞了你会等它生成完 4096 个 token 才拿到结果白等时间。context_window: 32768。这个必须和你实际用的模型对上。填大了运行时会把超出模型能力的上下文塞进去轻则报错重则输出乱码填小了白白浪费模型能力。7B 级别模型常见的是 32K 或 8K装之前查一下模型说明。max_turns_kept: 20。记忆保留轮数这个和上下文预算直接相关第 4.2 节详细算。policy.confirm_before这个列表是保命的。shell_exec和file_delete我强烈建议永远放在里面。意思不是不能用而是每次用之前会弹出确认你点一下同意就行。多这一次点击能避免掉绝大多数「它自作主张删了不该删的东西」的惨剧。4. 模型服务对接本地推理后端怎么接4.1 起一个兼容接口的本地服务爱马仕Hermes Agent本身不含推理能力它通过 HTTP 调用模型服务。最省事的做法是找一个提供 OpenAI 兼容接口的本地推理框架把模型加载起来监听一个本地端口。流程大致是这样先启动推理服务确认/v1/models能返回模型列表再让爱马仕Hermes Agent去连。验证命令很简单curl http://127.0.0.1:8080/v1/models返回里有模型名就说明服务活了。这一步不通先别管 Agent问题一定在推理服务那边。常见原因是端口被占、模型路径写错、或者显存不够导致加载失败这种一般在推理服务的日志里能看到 OOM 字样。服务起来之后回头改配置文件的model.base_url和model.model_name。注意model_name必须和服务返回的列表里那个名字完全一致多一个字符都不行。我就因为模型名里带了个版本后缀没对上报了个特别含糊的 404查了半小时。4.2 上下文预算怎么分一个必须算清楚的账这是很多人忽略的一环。模型有 32K 上下文不代表你就能塞 32K 进去。里面要分好几份用途建议占用说明系统提示词1000 - 2000 tokens定义角色、输出格式、工具调用规范工具描述1500 - 4000 tokens每个工具一段 JSON Schema工具越多吃越多对话历史8000 - 12000 tokens由max_turns_kept控制工具返回结果6000 - 8000 tokens最容易失控的一块留给模型输出2048 tokens对应max_tokens安全余量2000 tokens防止边界溢出按这个分法32K 总窗口是够用的但前提是你得控制住「工具返回结果」这一项。我吃过亏让智能体读一个 500KB 的日志文件整个文件被塞进上下文直接把窗口撑爆模型开始胡言乱语前面做的所有推理全丢了。对策是给工具输出加截断。配置里通常有类似max_tool_output_chars的字段设成 8000 字符左右如果运行时没有这个配置项就得在工具定义里自己处理——读取文件时只返回前 N 行或者返回摘要加「剩余内容请用分页工具查看」。这个设计比无脑全量返回重要一百倍。4.3 采样参数的取舍稳定压倒一切除了前面说的温度和 top_p还有两个参数值得调。重复惩罚。智能体场景容易出现一种病模型反复调用同一个工具、传入同样的参数。适度提高重复惩罚1.05 到 1.1能缓解但调太高会导致它不敢用工具。我的经验是配合max_steps用——循环两次还没进展就强制换个思路比单纯调参数更有效。停止词。这个容易被忽略。有些模型的输出格式是「先分析、再给 JSON」你得让它在该停的地方停。如果运行时支持配置停止词把工具调用的结束标记加进去能省下不少 token 和时间。参数调优这件事我的态度是先按保守值跑通再逐个试。一次只改一个参数改完跑同一批测试任务对比结果不然你根本不知道是哪个改动起了作用。我一开始一口气调了五个参数结果效果变差了都不知道回退哪个。5. 工具、权限与沙箱决定你敢不敢让它自己跑5.1 工具注册怎么写才不容易出错工具是智能体的手脚写得好不好直接决定任务成功率。核心就一点描述要写到模型能看懂参数要穷举到模型不会瞎猜。举个读文件的工具我实际用的定义大概这个结构{ name: read_file, description: 读取工作区内的文本文件。只能读 workspace 目录下的文件不能读系统文件。如果文件超过 2000 行只返回前 2000 行并提示剩余行数。, parameters: { type: object, properties: { path: { type: string, description: 相对于 workspace 根目录的文件路径例如 inbox/report.txt }, encoding: { type: string, enum: [utf-8, gbk], description: 文件编码不确定时用 utf-8 } }, required: [path] } }这里有三处细节值得说。description里明确写了「只能读 workspace 目录下的文件」这是给模型的约束提示能减少它去尝试读系统路径的次数。别指望模型自己知道边界你得写在它能看见的地方。path的描述里给了示例inbox/report.txt明确说是相对路径。模型对有示例的参数理解准确率高很多这是我测试下来最有效的一个改动。encoding用了枚举而不是自由字符串。枚举能框住取值范围模型不会发明一个utf-8-sig-with-bom这种不存在的编码。凡是取值有限的参数一律用enum。工具数量也要控制。我现在的原则是单次任务相关的工具不超过 8 个。工具描述本身占上下文工具太多还会让模型选择困难。需要更多能力的时候用「工具分组」的思路让主 Agent 只挂载当前任务需要的那一组。5.2 权限白名单把危险操作挡在门外Policy 层是整个配置里最不能省的部分。我的原则是三层防护。第一层路径白名单。所有文件类工具在执行前都检查目标路径是否在allowed_paths里。这里要防的不只是绝对路径还有../这种相对路径穿越。写检查逻辑的时候记得先realpath再比对别直接字符串比较否则workspace/../../../etc这种能绕过。第二层命令黑名单。对于shell_exec这类工具用正则匹配拦截危险模式。黑名单不是万能的但能挡住大部分低级事故。至少要把删除、提权、改系统配置这几类挡住。第三层人工确认。前两层是自动的这一层是兜底。配置里confirm_before列出的操作执行前会在终端弹提示你确认了才跑。开发调试阶段我建议把文件写入、命令执行、网络请求全放进去跑顺了再逐步放开常用的那几个。三层配合下来实际效果是日常任务读文件、写文件、跑脚本几乎不需要你干预只有真正危险的操作才会卡住问你。这个平衡点很关键全放开你不敢用全拦截你不如自己动手。5.3 沙箱选型subprocess 还是容器配置里的sandbox字段有两个常见选项。subprocess就是起个子进程执行轻量、快、零额外依赖但隔离性一般出了事影响范围是整个用户账户。适合单人电脑、只跑自己写的工具、信任度高的场景。容器方式隔离性好能限制 CPU、内存、网络但启动慢每次工具调用都要起容器或者维护一个常驻容器配置也复杂。适合多用户环境或者要跑不确定来源的代码。我个人的选择是开发阶段用 subprocess跑稳定了要让它长时间无人值守的时候再上容器。日常任务都是自己写的工具subprocess 的性能优势很明显一次工具调用几十毫秒就回来了容器方案要几百毫秒起步。6. 实测从单步冒烟到多步任务6.1 单步冒烟测试先确认最基础的能通装完别急着上复杂任务先跑最简单的逐层验证。我习惯按这个顺序第一步只测模型连通性。给一个「回复 OK」这种最简指令确认返回正常。这一步不通问题在推理服务或网络配置。第二步测单个工具。直接调用工具绕过模型传固定参数看返回对不对。这一步能验证工具本身的实现有没有 bug。第三步测模型 单工具。给一个「读取 inbox/test.txt 并告诉我第一行是什么」这样的指令看模型能不能正确调用工具、正确解读结果。这一步是整个链路的关键验证点。第四步测多步。给一个需要两步以上的任务比如「读取这个文件统计行数然后把结果写到 outbox 下的新文件里」。这四步一次跑通的情况不多但每一步的失败原因都很好定位。第一步失败必然是服务问题第二步失败必然是工具代码问题第三步失败是提示词或工具描述问题第四步失败才是编排逻辑问题。分层验证是我最推荐的一个调试习惯。6.2 多步任务的循环控制多步任务里最容易出问题的是循环。模型有时候会在两个状态之间来回跳比如读了文件发现有错改了再读还是觉得有错再改无限循环。max_steps是硬刹车但光靠它不够因为你还是会等它走满 12 步。更聪明的办法是加「进展检测」记录每一步的工具调用和参数如果连续两步调用完全相同的工具和参数直接中断并报错。这个逻辑有些运行时内置了没有的话可以在 policy 层用钩子实现。另一个技巧是给任务加显式的中止条件。比如在系统提示词里写「当你已经完成了用户要求的全部事项调用 finish 工具并说明结果」。有个明确的终点标记比让模型自己判断「我是不是完事了」要可靠得多。我加了 finish 工具之后任务提前结束的比例明显上升平均步数从 9 步降到了 6 步。6.3 日志怎么看它到底在干什么verbose: true的时候每步都会打印思考、工具调用、返回结果。一开始会觉得吵但排查问题没有它根本不行。看日志有个技巧先看工具调用的参数再看模型说了什么。大多数人反过来盯着模型的「思考过程」看半天那玩意儿只是参考真正发生的事情在工具调用里。参数传错了后面再合理的推理也是白搭。日志里我重点关注三个信号。一是工具调用失败率超过两成就得查工具定义。二是平均步数突然从 5 步涨到 10 步说明有东西在空转。三是单步耗时某一步特别慢通常是外部命令卡住了。7. 常见问题速查与踩坑记录7.1 环境类问题现象大概率原因处理方式hermes: command not found虚拟环境未激活source .venv/bin/activate或用python -m hermes安装卡在 building wheel缺编译工具或用了新 Python换 Python 3.10/3.11或找预编译包启动报ImportError依赖装了一半就中断了删虚拟环境重装别在残缺环境上修配置读取失败YAML 缩进用了 Tab全部换空格建议开编辑器自动转换中文路径报错部分库对非 ASCII 路径处理不好路径全用英文这是最省事的办法中文路径这条值得单独说。我在 Windows 上碰到过一次配置文件里 workspace 路径带了中文工具执行时死活找不到目录。查了半天是某个底层库编码处理的问题。从那以后我的原则是项目相关的所有路径一律英文不带空格。这个习惯能避免掉很多莫名其妙的问题。7.2 运行类问题模型一直重复调用同一个工具。原因通常是工具返回的结果让模型误以为失败了或者提示词里没说清楚成功是什么样。对策是让工具返回结构化结果明确带一个success: true/false字段再附上错误原因。模型看到明确的状态就不会反复试。工具调用格式错误JSON 解析失败。降低温度到 0.2 以下检查工具 schema 是不是太复杂。嵌套超过三层的 schema小模型很容易生错。简化参数结构比换大模型更有效。上下文爆炸模型开始胡言乱语。检查工具输出的长度加截断。同时看max_turns_kept是不是设太大。这个症状很明显前几步还好好的到某一步突然开始说完全不相关的东西或者重复上一段话。任务中途卡住不动。先看是不是某个工具在等输入比如某个命令需要交互确认。这类命令一定要加非交互参数否则会一直挂着直到step_timeout超时才返回。这是个隐蔽的坑我遇到过一次一个命令等了两分钟白白浪费掉一次任务。7.3 效果类问题跑通了但干得不好这类问题最难因为没报错就是结果不对。常见表现一模型不会拆任务。给一个稍微复杂的指令它直接一步就想给答案不去调工具。原因是系统提示词没强调「必须先获取信息再回答」。加一句明确的约束情况会好转。常见表现二模型调用工具但忽略返回结果。明明读到了文件内容回答的时候却凭想象编。这个通常是提示词里「以工具返回的事实为准」这条不够强。我一般会在系统提示里加一句「任何事实性结论必须来自工具返回不能来自你的推测」效果立竿见影。常见表现三多步任务的中间结果丢失。走到第五步的时候忘了第一步读到的东西这是上下文预算的问题。对策是把关键中间结果显式写进 memory或者让模型每步用「笔记工具」记录要点。后者更可靠因为它不依赖模型自己记住。8. 一些长期维护的个人习惯跑起来只是开始用久了会发现维护更重要。分享几个我摸索出来的习惯。配置用版本管理。conf/目录我单独做了 git 管理每次改参数都提交一次写清楚为什么改。这个习惯帮我回过好几次头——某个任务突然变差了翻提交记录发现是三天前把一个超时调小了。没有版本管理的话这种问题根本查不出来。模型按任务分级。不是所有任务都需要大模型。文件整理、格式转换这类机械活7B 完全够需要理解复杂意图的再切到 14B。我在配置里做了两套 profile一条命令切换。这样日常任务跑得快硬任务也不将就。日志定期归档。日志文件长得很快一次多步任务就能产生几百 KB。我设了每周清理一次只保留最近两周的。但清理前会先扫一遍错误日志把出现过的报错记到一个小本子上这些是优化配置的原材料。工具库慢慢攒。一开始别想着写全遇到什么需求写什么工具。我现在攒了十来个常用的就那么五六个。工具写得越多你会发现新的工具反而会干扰模型选择所以要定期删掉不用的。这个和写代码不一样工具不是越多越好。定期确认安全边界。每个月我会重新看一遍policy配置确认confirm_before里的项有没有被自己图省事删掉allowed_paths有没有扩得太大。人是有惰性的调试的时候经常临时放开限制然后就忘了改回来。这个小检查花不了五分钟但能防止边界在不知不觉中失守。最后分享一个我觉得挺有用的小设计给智能体加一个「干完活自我复述」的收尾步骤让它用两句话说清楚做了什么、产出物在哪个路径。这个步骤本身不产生任何实际价值但它是你快速确认任务是否按预期完成的最省事办法。翻日志太慢看复述一眼就知道对不对。这个习惯我是从一个做运维的朋友那儿学的用在智能体上意外地合适。