Hermes × 本地 Ollama × qwen3.8 效能优化研究实验报告

摘要

本报告记录并分析了一次针对"Hermes Agent + 本地 Ollama + qwen3.8"三元栈的系统性效能优化。

研究起点是一个朴素的问题------"如何让这套组合发挥最大潜力";终点却是一个与起点假设相反的结论。

核心发现 :在这套架构中,决定端到端延迟的主要变量不是被调用的模型,而是调用方发送的提示宽度。

实测表明 Hermes 在该配置下每轮固定发送 36,109 tokens (系统提示 18.7k + 工具 schema 10.1k 等),

在本机 qwen3.8 实测 1,713 tok/s 的预填充速率下,意味着每轮 21.1 秒的纯预填充 ------在任何输出

token 产生之前。而这一固定载荷中,技能索引一项即占系统提示的 60% (56,345 B),

其成本又高度集中在四个"批量迁移"引入的技能包上(443 个技能,占索引 81%),

而使用者自己创建的技能仅占 0.8%。

研究过程中形成了五个递进阶段,每一次都对前一阶段的结论构成修正甚至否定:

  1. 递进一:成本结构的重新定位。 从"调 num_ctx / num_batch / 温度"转向"审计调用方提示宽度"。
    模型参数调优的收益在数量级上小于提示削减。
  2. 递进二:驻留与缓存经济学。 发现 OLLAMA_KEEP_ALIVE=2m 造成 12.7 秒的冷加载税;
    发现 Ollama 桌面版静默覆盖注册表环境变量 ;发现请求级 keep_alive 优先生效(保温触碰仅 0.004 s);
    发现前缀缓存使同会话第二轮延迟从 24.7 s 降至 1.3 s(仅新增 64 tokens)。
  3. 递进三:混合路由体系。 确立"远程大脑 / 本地手"三层路由(含被普遍忽略的 Tier-0"不调模型"层)。
    发现工具集宽度 是本地执行的第一杠杆(32,216 → 11,632 tok,−64%;31.1 → 12.2 s,−61%);
    发现本地为单并发串行队列 (同一请求 12.2 s vs 55.1 s,劣化 4.5 倍且随机);
    反向验证出不应把 delegation.provider 指向本地 (子智能体继承完整工具集);
    成本证据显示远程与本地 token 消耗比为 66 : 1。
  4. 递进四:动态加载与"伪两难"的识别。 拒绝了"剪枝技能"路线(Hermes 源码自身的注释即写明
    "pruning caused silent capability loss" ),转向"降级为目录"。在四份候选降级名单之间发现
    一切权衡都源于粒度错配 (按类别匹配),遂提出第三条路径:按进程定菜单粒度。
  5. 递进五:决策融合。 证明两个原以为独立的选择实为一个伪二维问题,通过"进程级作用域 +
    惰性变更 + 大脑保菜单/手拿目录"的融合设计,同时取得最高收益(省 77% 索引、6.5 s/轮)
    与零能力损失(技能名 100% 保留、skills_list / skill_view 全可用、disabled = 0)。

最终验证 :端到端实测本地执行者提示从 26,087 → 15,907 tokens(−39%) ,

而执行者仍成功调用 skills_list(category=...) 并返回正确结果------能力保留得到实证。

方法论层面的产出 :本报告记录了研究过程中的 7 处自我纠错 ,其中 2 处是对外发布建议的

方向性错误,2 处是数值/单位错误,1 处是自建补丁的逻辑缺陷,1 处是测量口径错误,

1 处是对实验环境稳定性的误判。报告主张:在效能优化类研究中,纠错记录的密度是可靠性的
直接指标
,因为此类研究的结论极易被单一噪声点、单位混淆或非受控并发所污染。

关键词 :提示词经济学;渐进式披露;伪两难;粒度错配;无损劣化;前缀缓存;

串行队列;惰性变更;本地推理;agent 编排

关键发现速览(15 条)

# 发现 数值证据
1 每轮固定载荷是本机最大的单点成本 36,109 tok ≈ 21.1 s 预填充
2 技能索引占系统提示的 60% 56,345 B / 94,254 B
3 索引成本 81% 来自四个迁移包 443 技能 / 10,545 tok / 6.2 s·轮
4 使用者自建技能仅占索引 0.8% ~105 tok
5 64k 上下文是显存硬顶 20,480 MiB 占用 / 余 3,658 MiB
6 128k 上下文会杀死推理进程 RemoteDisconnected + 服务端自我重启
7 KV 成本仅 ~4.0 KB/token 混合注意力红利
8 冷加载 12.4--12.7 s,KEEP_ALIVE=2m 使其反复发生 桌面版覆盖注册表
9 保温触碰成本 0.004 s(暖机) 等效解决 2m 限制
10 前缀缓存使第二轮降至 1.3 s in 11,633 → 11,697(+64 tok)
11 工具集宽度是第一杠杆 32,216 → 11,632 tok(−64%)
12 本地是单并发串行队列 12.2 s vs 55.1 s(同一请求)
13 远程:本地 token 消耗 66:1 13,863,060 vs 208,757
14 关闭 thinking 反而更慢 4.92 s/374 tok vs 3.98 s/266 tok
15 按进程定菜单粒度优于按类别挑选 −39% 提示,零类别误伤,能力 100% 保留

五条深层元规律(报告的核心理论产出)

元规律 一句话表述 证据锚点
M1 成本引力在调用方 被调用方的参数不是主要变量;调用方发送的固定载荷才是 模型参数调优收益 ≪ 提示削减收益
M2 粒度错配制造伪两难 许多"必须权衡"的两难源于实现粒度选错,而非问题固有 类别级降级 → 进程级降级后两难消失
M3 可发现性 / 可加载性 / 可用性三分 "模型不知道"与"模型不能做"是完全不同的失效模式,不能混同 降级保留全部名字但丢描述
M4 无损劣化优于有损优化 能"退回现状"的变更,优于"破坏能力"的优化 惰性补丁;降级≠禁用
M5 口径决定结论 不控制测量口径时,噪声会生成与事实相反的结论 墙钟 17/20/32/61 s vs in= 恒定

第一章 引言与问题陈述

1.1 研究背景

1.1.1 三元栈的构成

本次研究的对象是一个三层协同的本地智能体运行栈:

层 组件 版本 / 规格 角色
编排层 Hermes Agent v0.21.1(2026.9.7,upstream ad03f20d,git 安装) 提供系统提示、工具协议、技能体系、后台系统
推理层 Ollama 0.33.2 提供本地模型服务(OpenAI 兼容 /v1)
模型层 qwen3.8 架构 qwen35,27.3B 参数,Q4_K_M 量化,原生上下文 262,144 执行本地推理

术语校正(重要) :qwen3.8 这一模型标识极易被误读为"Qwen3-8B"(80 亿参数的小模型)。

实测其元数据为:architecture=qwen35、parameters=27.3B、context length=262144、

quantization=Q4_K_M,并具备 completion / vision / tools / thinking 四项能力,

附带 clip 架构的多模态投影器(460.73M 参数)。

它是一个 273 亿参数、带视觉与工具调用能力的 Qwen3.5 系模型 ,而非小型模型。

本报告全文使用其原始标识 qwen3.8,但在容量讨论中一律以其真实参数量 27.3B 为准。

1.1.2 硬件平台

项 规格
GPU NVIDIA GeForce RTX 5090 Laptop,24,463 MiB 显存,WDDM 驱动模式
驱动 / CUDA 616.92 / CUDA 13.4(Ollama 使用 cuda_v13 后端)
系统内存 31.4 GiB 总量,实测空闲约 12.4 GiB
CPU Intel Core Ultra 9 275HX(24 逻辑核)
操作系统 Windows 11(build 10.0.26200)

WDDM 模式的特殊性 在此必须前置说明:Windows 的 WDDM 显示驱动模型下,

显示子系统可与 CUDA 计算共享显存,导致"理论可用显存"与"实际可用显存"出现差异。

本研究的容量实验均以 nvidia-smi 与 Ollama 服务端日志的实测值为准,不采用理论值。

1.1.3 研究起点

研究的原始提问非常朴素:"如何让 Herman(Hermes)+ 本地 ollama + qwen3.8 发挥最大潜力"。

这一提问隐含了三个未经验证的假设:

  • 假设 A:瓶颈在模型的参数配置(上下文长度、批大小、采样温度、GPU 卸载层数等)。
  • 假设 B:"最大潜力"等于"本地模型跑得尽量快"。
  • 假设 C:本地模型应当承担主要工作负载。

本报告的第一项贡献,就是逐条证伪这三个假设 。研究在推进过程中经历了一次根本性的

问题重述:从"如何让本地模型更快"变为"在给定硬件上,如何最小化每轮固定成本并
把能力放在最合适的位置
"。

1.2 问题陈述的演化

研究过程中,问题陈述发生了三次明确的重述。这一演化过程本身是重要的研究材料,

因为它记录了如何识别一个被错误框定的问题。

第一版问题陈述(原始)

如何调优本地 ollama 与 qwen3.8,使其在 Hermes 中跑得最快?

缺陷 :把"调优"默认理解为"调整被调用方的参数"。这会导致研究者把注意力放在

num_ctx、num_batch、num_gpu、采样参数上,而这些参数的可得收益在实测中

远小于提示削减的收益(详见第四章)。

第二版问题陈述(瓶颈识别后)

Hermes 每轮发送的固定载荷有多大?其中哪一部分占比最高?

进展 :从"调参数"转向"量成本"。这一转向立即产出了本报告最重要的单个数字------

36,109 tokens 的固定每轮载荷 ,折合本机 21.1 秒预填充。

新缺陷 :识别出成本后,研究者的第一反应是"削减成本",而削减的方式被误选为

"裁剪能力"(最小化工具集 / 禁用技能包)。这一反应犯了两类错误:

  • 技术错误:裁剪工具集确实快,但会静默移除能力(详见第七章)。
  • 认识错误:把"降级"与"禁用"混为一谈(详见第八章)。

第三版问题陈述(本报告的最终框定)

在保持能力完整的前提下,如何把每轮固定载荷压到最低?能力应当分布在哪个层级

(远程 / 本地 / 无模型)?削减成本的操作应当以何种粒度、何种作用域实施?

这一版本的关键进步 在于把"成本"与"能力"从对立面变为两个独立可控的维度:

低成本 高成本
高能力 ✅ 目标(通过降级而非裁剪达成) 现状(36,109 tok)
低能力 裁剪后的机械执行者(被否定的路线) ---

在第二版问题陈述下,研究者只能在左上到右下的对角线上移动(即所谓"权衡");

在第三版问题陈述下,研究者意识到该对角线并非必然 ------它是由"削减手段的粒度"造成的

人为约束。这一认识直接导向了本报告第七章与第八章的核心成果。

1.3 研究问题

基于最终的问题框定,本报告回答以下六个研究问题(RQ):

编号 研究问题 对应章节
RQ1 本机平台上,本地模型的真实性能边界是什么(吞吐、上下文容量、能力可用性)? 第三章
RQ2 Hermes 每轮固定载荷的成本结构如何?瓶颈在哪一层? 第四章
RQ3 在保持能力完整的前提下,有哪些机制可以降低每轮成本?它们的收益与代价分别是什么? 第五、六章
RQ4 远程模型与本地模型的正确分工是什么?判据是什么?有哪些反直觉的正确结论? 第七章
RQ5 削减提示成本的"粒度"与"作用域"如何选择?是否存在优于"按类别挑选"的路径? 第八、九章
RQ6 这类效能优化研究中,哪些测量纪律是必需的?哪些错误模式是高频的? 第二章、第十章

1.4 研究边界与非目标

为避免读者误读本报告的适用范围,以下明确列出不在本次研究范围内的事项:

非目标 说明
模型微调 / 量化对比 本研究使用既有模型与既有量化(Q4_K_M),未做任何权重层面改动
云端 / 集群扩展 全部实验限于单机单卡
安全加固 未评估提示注入、工具越权等安全议题
商业成本测算 仅给出 token 消耗比(66:1)作为量级证据,未做货币换算(远程 provider 单价未公开)
用户工作流的正确性 未评估"哪些技能对使用者真正有用"------该判断属业务决策,报告只提供成本侧数据
上游代码质量评价 对 Hermes 源码的引用仅为机制说明,不含质量评判

1.5 报告的读者与使用方式

本报告面向三类读者,建议的阅读路径如下:

  • 运维/工程读者 :从第三章(环境与基线)→ 第四、七、八章(瓶颈与优化)→ 第九章(融合方案),
    可直接落地;脚本与补丁见配套交付目录。
  • 方法学读者 :从第二章(方法论与口径纪律)→ 第九章(深层逻辑)→ 第十章(失败与自我纠错),
    关注可迁移的研究纪律。
  • 决策读者:从摘要的"关键发现速览"与"五条深层元规律"入手,再按需查阅具体章节。

报告中的每一项数值断言都可回溯到配套的原始输出文件(见各章末的"数据出处"小节)。

凡属推断而非实测的结论,均以 【推断】 显式标注;凡证据不足者,均列入第十一章"待核清单"。

第二章 方法论与测量口径纪律

2.1 研究方法的总原则:实测优先

本次研究在方法上遵循一条压倒性的原则:任何进入结论的数值,必须有本机实测输出支撑;
任何未实测的推断,必须显式标注为推断;任何证据不足者,不得进入结论。

这条原则在本研究中并非形式主义。研究过程中出现的 7 处错误 (见第十一章),

其中 5 处 如果严格遵循"实测优先"本可避免,另外 2 处 恰恰是被实测发现的。

换言之:实测优先既是最有效的防错机制,也是唯一能暴露既有错误的机制。

为落实这一原则,本研究对所有断言做了三级可信度标注:

级别 定义 标注方式 示例
L1 实测 有本机命令的原始输出可直接复核 直接陈述 + 引用原始文件 "冷加载 12.66 s"(server.log 的 load_duration)
L2 推算 由 L1 数据经明确公式导出,公式与输入均公开 陈述时给出公式与输入 "KV ≈ 4.0 KB/token"(三点线性推算)
L3 推断 由机制推理导出,无直接观测 显式标注 【推断】 上游若改文件则重打可能冲突

2.2 技能编排方法:G-D-C-M-E-O-V

本研究的执行过程采用 G-D-C-M-E-O-V 技能编排法(目标类型 → 领域指纹 → 要素分解 →

匹配矩阵 → 扩展门禁 → 编排 → 校验)。该方法在本任务中的作用并非"选技能",

而是强制在动手前把工作流拆解并做覆盖率审计。

2.2.1 本任务的组合卡(门禁版)

复制代码
目标类型:G8 混合 = 主 G4 构建/执行 + G1 分析/审计 + G5 改进/优化
领域指纹:devops(本地推理运维)· autonomous-ai-agents(Hermes 编排)· 方法学(跨域)
要素分解:
  ① 能力盘点 → ② 机制核验 → ③ 实测标定 → ④ 策略成型 → ⑤ 工程化 → ⑥ 逐项复验
主 skill :ollama-tuning(覆盖 ②③)
支撑 skill:hermes-local-providers(④),hermes-agent(②④)
质量门  :以 agent.log 的 in=/latency= 为唯一延迟口径
工具链  :terminal / python 脚本文件 / Hermes CLI / 源码检索

2.2.2 E 门禁的三项闭合情况

门禁 要求 实际执行 结果
E1 覆盖率审计 每个工作流阶段须有 PRIMARY skill 或脚本兜底 ② 有 ollama-tuning;③ 有实测脚本;④ 有 hermes-local-providers;⑤ 无 skill 覆盖 → 真缺口 触发 E2/E3
E2 外拓检索 必须跑 15 源 registry hermes skills search "model routing hybrid remote local" --source all → 明确返回 No skills found matching your query. (非超时)→ 降级本地图谱(575 skills)→ 仅软命中 automation-workflows 无合适外部技能 → E3
E3 构建/升级 核心缺口必须自建或升级 自建:local_exec.sh、verify_patch.py、reapply_patch.sh、demote_savings.py、hermes_bench.py;升级:ollama-tuning、hermes-local-providers 闭合

人工段:无。

2.2.3 门禁制在本任务中的真实价值

E2 门禁的价值不在于"找到了什么",而在于它排除了"没找到是因为没找"的可能性 。

hermes skills search 明确返回空结果(而非超时、非静默),使"不存在现成技能"

成为一个有证据的结论,而不是"我以为没有"的猜测。

2.3 测量口径纪律(本研究的核心方法学贡献)

2.3.1 问题:墙钟时间在并发环境下不可用

研究早期使用墙钟(wall-clock)作为性能指标,得到了自相矛盾的结果:

实验 配置 墙钟
第 1 次 完整工具集 39 s
第 2 次 -t terminal,file 17 s
第 3 次 -t terminal 16 s
第 4 次 同 -t terminal,file(不同档案) 20 s
第 5 次 同 -t terminal,file(回原档案) 61 s

第 2 次与第 5 次是同一个档案、同一个模型、同一个工具集、同一条工单 ,

墙钟却是 17 s 与 61 s,相差 3.6 倍。若以此为据,任何结论都不可靠。

根因定位 :本地服务以 OLLAMA_NUM_PARALLEL=1 运行,单并发串行队列 。

当同时存在其他本地请求(例如辅助通道的标题生成、视觉调用)时,请求进入队列,

延迟由"服务时间"变为"服务时间 + 排队时间"。排队时间取决于当时系统恰好在做什么,

因此完全不可预测。此外,本研究的主会话本身会持续产生辅助调用,构成持续的干扰源。

2.3.2 解法:使用服务端与 agent 端的确定性计数器

有效的替代口径有两个层次:

(a) Ollama 服务端返回的计数器 (/api/generate 与 /api/chat 的响应体):

字段 含义 用途
prompt_eval_count 本次实际评估的提示 token 数 前缀缓存命中率
prompt_eval_duration 提示评估耗时(纳秒) 计算预填充速率
eval_count / eval_duration 生成 token 数与耗时 计算生成速率
load_duration 模型加载耗时 冷加载代价

(b) Hermes agent 端的每次 API 调用记录 (<profile>/logs/agent.log):

复制代码
API call #1: model=qwen3.8-hermes provider=custom in=11632 out=46 total=11678 latency=55.1s
API call #2: model=qwen3.8-hermes provider=custom in=11694 out=22 total=11716 latency= 1.0s
  • in= 是发送给模型的提示 token 数 ------这是本研究最重要的单一指标,
    因为它直接反映"提示宽度",且不受并发影响(确定性)。
  • latency= 是每次调用的延迟,受并发影响,仅用于同批次横向对比。

结论性纪律 :凡涉及"提示规模/成本结构"的结论,一律以 in= 为口径;
凡涉及"延迟"的结论,必须在同批次、无并发干扰的条件下测量,否则不予采信。

本研究在第七、八、九章的所有优化结论均以 in= 为主口径。

2.3.3 三源交叉验证

对关键结论,本研究采用三个独立数据源交叉验证:

源 提供的信息 独立性
nvidia-smi 显卡占用/剩余显存 独立于 Ollama
Ollama server.log 服务端实际生效环境、启动参数、显存分解、请求日志 服务端视角
Hermes agent.log 实际发送的提示规模、延迟、辅助通道路由 客户端视角

例如"64k 是显存上限"这一结论同时得到三方支持:

nvidia-smi 显示 20,480 MiB 占用 / 余 3,658 MiB;

server.log 给出显存分解 model 15,339 + context 2,924 + compute 400 ≈ 18,663 MiB;

而 128k 尝试触发了 RemoteDisconnected 与服务端自我重启。

三者互相印证,结论可信度显著高于单一来源。

2.4 变更管理纪律

本研究对生产环境(使用者正在使用的 Hermes 与 Ollama)实施变更,因此建立了四项纪律:

2.4.1 惰性变更(inert change)优先

定义 :新引入的代码路径在未显式启用前,行为必须与变更前逐字节一致。

本研究对 Hermes 源码的唯一补丁即遵循此原则。实测验证:在未设置任何配置键与环境变量时,

compact_skill_categories() 返回 ∅,渲染结果与打补丁前一致。

这使得"补丁已应用"与"功能已启用"成为两个可独立决定的事,任一不启用都不影响使用者。

这一纪律的价值在第十一章有直接体现:补丁本身在验证过程中被发现存在缺陷,

但由于处于惰性状态,缺陷从未对抗使用者产生任何实际影响。

2.4.2 三重保险(备份 + 语法检查 + 异常隔离)

对源码的修改同时施加三重保护:

层 措施 实测结果
1 变更前复制原文件(.bak-20260912)+ 记录上游 HEAD 与文件 sha256 回滚锚点 HEAD 6c3d4a4a;原文件 4921bad3...
2 变更后立即 py_compile 通过
3 新增逻辑包裹在 try/except Exception: pass 中 即使新逻辑失败也不影响原行为

2.4.3 可逆性优先于正确性

对每一项变更预先设计回滚路径,且要求回滚为一条命令。本研究的三级回滚为:

bash 复制代码
hermes config set skills.demote_categories '[]'                    # L1 立即停用(保留补丁)
cp agent/coding_context.py.bak-20260912 agent/coding_context.py     # L2 源码还原
git checkout -- agent/coding_context.py                             # L3 git 原生还原

2.4.4 隔离验证(不触碰实时配置)

验证新功能时,不修改使用者的实时配置。做法是利用函数已支持的显式参数:

python 复制代码
coding_compact_skill_categories(platform="cli", cwd=os.getcwd(),
                                config={"skills": {"demote_categories": ["gaming","media"]}})

这一做法在研究中直接暴露了补丁的一个真实缺陷(详见第十一章第 5 项),

若当时选择"直接改实时配置来测",该缺陷会被掩盖。

2.5 伪优化的剔除机制

本研究对每一项候选优化施加三道检验,任一不通过即剔除:

检验 问题 被剔除的候选项
机制检验 该优化所依赖的机制,在源码层面是否存在? 通过环境变量 OLLAMA_GPU_OVERHEAD 预留显存(0.32+ 已不读取)
因果检验 观测到的改善是否真由该变更引起?有无混杂变量? 早期"17 s vs 61 s"的墙钟对比(实为并发噪声)
成本检验 该优化的代价(能力/风险/维护)是否小于收益? 最小化工具集(省 12.0 s 但静默失去全部技能能力)

经此机制,本研究明确剔除了 6 项诱人但无效(或有害)的"优化" ,

详见第六章末节的"负结果清单"。这一清单与方法学上的正结果同等重要:

它防止使用者重复踩踏同样的坑。

2.6 可复现性

本研究的所有测量脚本、原始输出与配置均随报告交付,目录结构如下:

目录 内容
01_实测报告/ 性能基线与瓶颈实测报告 + raw/ 全部原始输出
03_配置与脚本/ hermes_bench.py(性能基准)、verify.sh(健康自检)、keepwarm.ps1(驻留保温)
06_混合路由策略/ local_exec.sh(本地执行者封装)
07_动态加载优化/ verify_patch.py(补丁验证)、reapply_patch.sh(升级后重打)、demote_savings.py(收益测算)
09_研究报告/ 本报告

复现须知 :本报告的延迟类结论依赖具体硬件(RTX 5090 Laptop 24 GB)与具体模型

(27.3B Q4_K_M)。in= 类结论(提示规模)与硬件无关,可跨平台复现。


第三章 实验环境与性能基线标定

本章回答 RQ1:本机平台上,本地模型的真实性能边界是什么?

所有数据均来自本机实测,原始输出见 01_实测报告/raw/。

3.1 环境指纹

项 实测值 来源命令
GPU NVIDIA GeForce RTX 5090 Laptop,24,463 MiB nvidia-smi
驱动 / CUDA UMD 616.92 / 13.4 nvidia-smi
驱动模式 WDDM nvidia-smi
系统内存 31.4 GiB 总 / 空闲 12.4 GiB server.log 的 system memory
CPU Intel Core Ultra 9 275HX(24 逻辑核) server.log
交换空间 空闲 35.1 GiB server.log
Ollama 0.33.2 GET /api/version
推理后端 libdirs=ollama,cuda_v13,compute=12.0 server.log 的 inference compute
Hermes v0.21.1(2026.9.7)· upstream ad03f20d · git 安装 hermes --version
模型目录 D:\ollama\models(43 个 blob) server.log / ollama list

3.1.1 模型元数据(关键校正)

复制代码
ollama show qwen3.8:latest
  architecture        qwen35
  parameters          27.3B
  context length      262144
  embedding length    5120
  quantization        Q4_K_M
  requires            0.32.12
  Capabilities        completion / vision / tools / thinking
  Projector           architecture=clip, parameters=460.73M, dimensions=5120

三点必须强调:

  1. qwen3.8 不是 8B 级小模型,而是 27.3B (Qwen3.5 家族)。标识中的 "3.8"
    是版本号而非参数量,这一命名极易导致容量规划错误。
  2. 原生上下文 262,144 ,但本机显存只允许其实用上下文 65,536 (见 3.5)。
    模型能力上限 ≠ 部署上限。
  3. 具备 vision(多模态投影器 clip 460.73M)与 tools(工具调用)能力------
    这两项能力在后续章节的路由设计中起决定作用。

3.1.2 服务端实际启动参数(从 server.log 提取)

复制代码
llama-server.exe --model <blob> --port 59949 --host 127.0.0.1 --no-webui --offline
  -c 65536 -np 1 --log-verbosity 4 --no-log-prefix --no-log-timestamps --no-jinja
  --chat-template chatml
  --mmproj <clip blob>
  --spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-backend-sampling
  --load-mode none --cache-type-k q8_0 --cache-type-v q8_0 --flash-attn on
  -b 512 -ub 512 --context-shift --keep 4

这一行包含了本研究需要解释的多个现象的直接证据(详见 3.6 与第八章):

  • -c 65536:上下文由上层的 num_ctx 决定(本次为 65536)。
  • -np 1:单并发槽------本研究后续所有"串行队列"结论的源头。
  • --mmproj <blob>:多模态投影器被加载,占用独立显存(见 3.5)。
  • --spec-type draft-mtp:MTP 投机解码已启用(见 3.6)。
  • --flash-attn on、--cache-type-k/v q8_0:KV 缓存量化与 FlashAttention 生效。
  • --load-mode none 与 disabling mmap for llama-server load by default, reason=windows_cuda:
    Windows CUDA 下禁用内存映射加载。

3.2 吞吐基线

3.2.1 预填充速率与生成速率(qwen3.8:latest,num_ctx=8192)

提示长度 预填充 token 预填充耗时 预填充速率 生成 token 生成速率
~576 576 0.79 s 726 tok/s 16 65.5 tok/s
~2,246 2,246 1.78 s 1,263 tok/s 16 57.5 tok/s
~6,686 6,686 3.90 s 1,713 tok/s 16 68.0 tok/s

观察 1:预填充速率随提示长度上升而非下降。

从 726 → 1,263 → 1,713 tok/s,存在明显的规模效应。原因是每批计算存在固定开销

(kernel 启动、批次调度、显存访问建立),在短提示下该开销无法被摊薄。

到 6,686 token 时仍未看到饱和迹象。

方法论含义 :用短提示测出的预填充速率会低估 长提示的真实速率。

本研究在后续折算中一律采用 1,713 tok/s (实测峰值,对应最大提示),

这一选择对优化结论是保守 的(若真实速率更高,则"每轮固定开销"的绝对耗时更低,

但相对排序不变)。

3.2.2 生成速率(64k 上下文,暖机)

输出预算 生成 token 耗时 生成速率
60 60 0.93 s 64.4 tok/s
275 275 5.07 s 54.2 tok/s

基线取 54--68 tok/s,中位数约 60 tok/s。 500 token 的回答约需 8.3 s。

3.2.3 冷加载代价

场景 实测耗时 来源
冷加载(17 GB 模型从磁盘) 12.36 s load_duration
冷加载 + 首个响应 12.70 s 总墙钟
64k 首次加载(含参数拟合) 13.1 -- 13.6 s load_duration
64k 加载 + 首次响应(含拟合计算) 18.6 -- 20.9 s 总墙钟

观察 2:冷加载 12.4--12.7 秒是一个不可忽略的常数。

在交互式 agent 使用中,会话内思考间隔常超过数分钟。若模型在此期间被卸载,

则每一轮的第一个 token 都要额外等待约 12.7 秒。这一发现直接导出了第六章

的"驻留经济学"分析。

3.3 能力可用性验证

优化必须在"能力可用"的前提下进行,因此在优化前先确认基线能力。

3.3.1 工具调用(OpenAI 兼容端点)

向 /v1/chat/completions 发送带 tools 数组的请求:

json 复制代码
{"model":"qwen3.8-hermes","stream":false,"max_tokens":300,
 "messages":[{"role":"user","content":"What is the weather in Beijing right now? Use the available tool."}],
 "tools":[{"type":"function","function":{"name":"get_weather", ...}}, ...]}

实测返回:

复制代码
finish_reason = tool_calls
tool_calls = [{"id":"call_b1f8dl4e","index":0,"type":"function",
               "function":{"name":"get_weather","arguments":"{\"city\":\"Beijing\"}"}}]
reasoning field: yes, 146 chars
content: ''

结论 :工具调用协议完全可用,finish_reason 正确,参数 JSON 正确。

同时观察到模型返回独立的 reasoning_content 字段(非 OpenAI 标准字段,

Hermes 会忽略,无害)。

延迟 :暖机 4.2 s ;冷机 15.4 s ------差别全部来自模型加载 ,

与工具调用协议本身无关。这一点在后续优化中很关键:

"工具调用慢"是一个假象,真实原因是模型换载。

3.3.2 视觉能力

向模型发送程序生成的 128×128 PNG(白色背景 + 居中红色实心圆 + 左下蓝色色块):

复制代码
VISION -> 'The image contains a large red circle in the center and a smaller
           blue square in the bottom-left corner.'

结论 :视觉能力可用,描述与图像真实内容一致(含位置信息)。

暖机延迟 1.0--1.2 s ;换载模型后 26.7--33.0 s(同样全部是加载代价)。

重要副发现 :早期一次视觉测试返回空字符串 '',一度被误判为"视觉能力缺失"。

深入排查后确认根因是 token 预算耗尽 :在 max_tokens=60 下,

思考型模型先把预算消耗在推理上,导致 finish_reason=length 而 content 为空。

将预算提高到 600 后立即返回正确结果。

方法论含义 :"输出为空"不等于"能力缺失"。 对思考型模型,

必须给足 max_tokens 才能区分"不支持"与"预算不足"。

本研究将此列为 AI 能力测试的标准检查项。

3.3.3 思考模式:一个反直觉的测量结果

设置 思考长度 输出 token 耗时
think: true(默认) 301 字符 266 3.98 s
think: false 0 374 4.92 s

关闭思考后,模型反而输出了更多 token 且更慢。 这一结果违反直觉

(通常认为跳过推理链会更快),但与 3.6 节的发现相吻合:本机启用了 MTP 投机解码,

思考 token 在投机解码下具有高接受率,属于"顺带产出"。

关闭思考后模型改用冗长的直答方式,反而增加了 token 数。

结论 :不要关闭思考。 这是本研究剔除的一项"伪优化"。

3.4 上下文容量实验

3.4.1 实验设计

固定模型(qwen3.8 及其 -opt 派生标签),逐一设定 num_ctx,

测量加载后的显存占用与推理可行性。

3.4.2 结果

num_ctx 权重+KV 驻留 全卡占用 剩余显存 结果
8,192 16.11 GiB 18,080 MiB 6,058 MiB ✅ 可用
32,768 16.20 GiB 19,094 MiB 5,044 MiB ✅ 可用
65,536 16.33 GiB 20,480 MiB 3,658 MiB ✅ 实用上限
131,072 --- --- --- ❌ 推理进程崩溃

3.4.3 KV 缓存成本推算(L2 推算)

以三点线性推算:

复制代码
(16.33 − 16.11) GiB = 0.22 GiB,对应 (65,536 − 8,192) = 57,344 token
0.22 × 1024 × 1024 KB / 57,344 ≈ 4.0 KB/token

KV 成本仅约 4.0 KB/token ,远低于常规稠密注意力模型。

这是 Qwen3.5 采用混合注意力(部分层使用线性注意力)的直接红利。

实践含义 :在本机型上,把上下文从 8k 提到 64k 只需多付 0.22 GiB ,

因此"为了省显存而压小上下文"在本例中是错误的优化方向 ------

真正的约束在 64k 与 128k 之间的悬崖处。

3.4.4 128k 崩溃的根因分析(L1 实测 + L2 推算)

现象 :请求 qwen3.8-hermes(num_ctx=131072)后,

后续请求返回 http.client.RemoteDisconnected: Remote end closed connection without response,

nvidia-smi 显示显存回落至 0 MiB,Ollama 服务端日志出现自我重启记录。

根因 :server.log 的显存分解提供了直接证据:

复制代码
common_memory_breakdown_print:
 | CUDA0 (RTX 5090 Laptop GPU) | 24435 = 22401 + (18663 = 15339 + 2924 + 400) + (-16629)
 | Host                        | 766 = 682 + 0 + 84

即 64k 上下文时:model 15,339 + context 2,924 + compute 400 ≈ 18,663 MiB。

若上下文翻倍至 128k,context 项约需 5.8 GiB (2,924 × 2),

总量约 21.6 GiB ;再叠加日志中记录的多模态投影器最坏情况

[mtmd] estimated worst-case memory usage of mmproj is 1161.02 MiB,

合计约 22.7 GiB ,超出报告可用显存 22.6 GiB。

结论 :64k 是本机型的硬上限,128k 不可用。

这不是模型能力限制(原生支持 262,144),而是显存容量限制。

且由于 WDDM 模式的存在,实际可用显存还会随显示负载浮动,

65,536 已属顶格部署(余量仅 3,658 MiB)。

方法论含义 :扩容前的容量估算必须先于实验。

本次 128k 的尝试把一个正在提供服务的推理进程打挂(服务端需自我重启),

属于"破坏性试错"。正确流程应为:先按 KV/token × 目标上下文 + 权重 + mmproj 估算,

确认余量后再 ollama create。

3.5 模型标签的实例共享现象

实验中观察到一项容易造成误判的行为:

复制代码
请求 qwen3.8:latest + num_ctx=32768 →  wall 0.3 s
ollama ps                          →  RESIDENT qwen3.8:opt  ctx=32768

请求的标签是 qwen3.8:latest,但实际驻留的是 qwen3.8:opt。

原因是两个标签共享同一份权重 blob (sha256-f5f1dd89...),

Ollama 直接复用已加载实例,只调整上下文参数。

推论:

  • 共享权重的不同标签之间切换不会触发重载------前提是权重 blob 相同。
  • 但若标签对应的权重不同(例如不同量化版本),则切换代价为 13--20 秒的完整重载。
  • OLLAMA_MAX_LOADED_MODELS=1 意味着任何真实的权重切换都会卸载前一个模型。

方法论含义 :在多模型工作流中,标签切换的频率直接决定延迟 。

本研究的优化方案(统一使用 qwen3.8-hermes 单一标签,并让辅助通道与执行者

共用同一模型)正是基于这一机制。

3.6 投机解码的发现(对既有认知的修正)

本研究在 server.log 中发现了投机解码的直接证据:

复制代码
--spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-backend-sampling

运行期统计:

复制代码
spec common_specu: statistics draft-mtp: #calls(b,g,a) = 5 186 186
draft acceptance = 0.52163 (217 accepted / 416 generated), mean len = 3.09
acc per pos = (0.827, 0.567, 0.433, 0.260)

draft 接受率 0.52,平均接受长度 3.09,逐位置接受率递减(0.827 → 0.260)。

这一发现修正了先前结论。 本研究使用的 ollama-tuning 技能中原有一行断言:

"投机解码:Ollama 0.32 不支持(PR 被拒),要 draft 模型得换 llama.cpp server / LM Studio"。

实测证明 Ollama 0.33.2 已原生支持 MTP 投机解码 ,且这正是本机生成速率达到

54--68 tok/s 的重要来源。该技能已据此修正。

机制说明 :模型 Modelfile 中的 PARAMETER draft_num_predict 4 触发 Ollama

附加上述投机解码参数,由 llama.cpp 以 MTP(多 token 预测)方式实现。

方法论含义 :"某工具不支持 X"这类否定性断言必须定期重新验证。

工具的迭代会持续推翻旧结论,而旧结论一旦写入知识库就会长期污染后续判断。

3.7 基线小结

指标 基线值 后续章节的用途
预填充速率 1,713 tok/s 折算"每轮固定载荷"的时间成本(第四、七章)
生成速率 54--68 tok/s 折算回答时间(第四章)
冷加载 12.4--12.7 s 驻留经济学(第六章)
上下文上限 65,536 硬约束,所有方案必须在其内(第四、七章)
KV 成本 ~4.0 KB/token 容量规划公式(第八章)
工具调用 ✅ 可用,暖机 4.2 s 混合路由的可行性前提(第七章)
视觉 ✅ 可用,暖机 1.0--1.2 s 辅助通道本地化的可行性前提(第六章)
思考模式 开启更优 剔除"关闭思考"伪优化(第六章)
投机解码 启用,接受率 0.52 解释生成速率;修正既有知识
单并发 已验证(-np 1) 串行队列结论(第七章)

第四章 瓶颈解剖:每轮固定载荷的成本结构

本章回答 RQ2:Hermes 每轮固定载荷的成本结构如何?瓶颈在哪一层?

4.1 两种独立测量方法及其交叉验证

为避免单一测量方法引入的系统偏差,本研究用两条完全独立的路径测量同一对象。

4.1.1 方法 A:Hermes 原生离线统计

复制代码
hermes prompt-size

该方法不发起任何 API 调用 (帮助文本明确说明 "Runs offline (no API call)"),

由 Hermes 在本地构建一份"新会话的系统提示"并统计其组成。实测输出:

复制代码
Prompt-size breakdown (platform=cli, model=DeepSeek-V4-Flash-0731)

  System prompt total :   94,254 B  (92.0 KB, 74,903 chars)
  Major blocks:
    skills index       :   56,345 B  (55.0 KB)
    memory             :    3,618 B  (3.5 KB)
    user profile       :    2,551 B  (2.5 KB)
  Prompt tiers:
    stable (identity/guidance/skills)   :   28,799 B  (28.1 KB)
    context (AGENTS.md/cwd files)       :        0 B  (0.0 KB)
    volatile (memory/profile/timestamp) :   65,455 B  (63.9 KB)
  Tool schemas         :   40,300 B  (39.4 KB, 25 tools)

4.1.2 方法 B:真实请求转储

Hermes 在遇到不可重试的客户端错误时会把完整请求体写入

sessions/request_dump_*.json。本研究解析了一份实际的历史转储:

复制代码
dump: request_dump_20260902_163255_41e6bb_20260902_165402_314468.json
request.url  = https://ark.cn-beijing.volces.com/api/v3/chat/completions
error.type   = Unauthorized (401) "The API key format is incorrect"
body keys    = [model, messages, tools, max_tokens, reasoning_effort]

messages          : 2
system messages   : 1  -> 78,008 chars  (~19,502 tok)
tools             : 38 -> 66,431 chars  (~16,607 tok)
ALL messages      : 78,855 chars        (~19,713 tok)
FIXED PER-TURN    : ~36,109 tok   (system + tools, resent every turn)

4.1.3 交叉验证的结论

量 方法 A 方法 B 一致性
系统提示规模 74,903 chars 78,008 chars 同量级(不同会话,技能集略有差异)
工具 schema 40,300 B / 25 tools 66,431 chars / 38 tools 不同! 见下
固定载荷折合 token ≈ 33,600 36,109 同量级

工具数量的差异(25 vs 38)需要解释,且这一差异本身极具信息量:

  • 方法 A 统计的是当前 平台(platform=cli)在新配置下的工具集,此时
    tools.tool_search.enabled: auto 已生效,部分工具被"延迟加载" ,
    因此进入 schema 的只有 25 个。
  • 方法 B 是 2026-09-02 的历史转储,当时 tool_search 的延迟阈值与工具集
    配置不同,因此有 38 个工具全量进入。

方法论含义 :"固定载荷"并非恒定,它随配置漂移。

因此任何"提示成本"的结论都必须绑定其测量时的配置状态。

本研究后续一律以方法 A 的 prompt-size 作为当前状态的权威口径,

以方法 B 作为"未优化状态下可以达到多高"的参照。

4.2 系统提示的组成解剖

4.2.1 按块划分(方法 A,当前配置)

块 体积 占系统提示 折合 token(÷4) 作用
技能索引 56,345 B 60% ~14,086 列出所有可用技能及其描述
记忆 3,618 B 4% ~905 跨会话持久事实
用户画像 2,551 B 3% ~638 使用者身份与偏好
其余(身份/指令/工具指引) 31,740 B 33% ~7,935 角色定义与行为规范

4.2.2 技能索引为什么是最大块

本研究进一步解剖了技能索引的内部结构,来源为

.skills_prompt_snapshot.json(348 KB,566 个技能条目)与

hermes prompt-size --json 的 skills_breakdown 数组。

每个技能在索引中占一行,格式为:

复制代码
    - <skill-name>: <description 截断至 57 字符>

实测平均每行约 85 字节 (4 字节缩进 + 名称 + ": " + 至多 57 字节描述 + 换行)。

566 行合计 51,999 字节;差额 4,176 字节为分类标题行与样板文字。

关键推论 :描述占据了索引的约 68% 。

若只保留技能名(去掉描述),每行约 27 字节。这一事实是第七章"降级为目录"

方案的量化基础。

4.2.3 技能索引的类别分布:一个意外发现

按类别统计索引成本(实测 prompt-size --json):

类别 技能数 索引成本 折合 占索引
scientific-skills/skills 157 12,705 B 3,176 tok 24%
scienceclaw-migrated 133 10,747 B 2,687 tok 21%
bmad-migrated 54 4,796 B 1,199 tok 9%
research/workbuddy-migrated 33 4,662 B 1,166 tok 9%
autonomous-ai-agents/workbuddy-migrated 25 3,524 B 881 tok 7%
productivity/workbuddy-migrated 20 3,075 B 769 tok 6%
creative/workbuddy-migrated 13 1,795 B 449 tok 3%
productivity 23 1,729 B 432 tok 3%
software-development 19 1,664 B 416 tok 3%
creative 20 1,485 B 371 tok 3%
research 14 1,175 B 294 tok 2%
...(其余 33 个类别) 105 ~2,600 B ~650 tok 5%
合计 566 51,999 B ~13,000 tok 100%

四个"批量迁移"引入的技能包合计 443 个技能、10,545 tok、占索引 81%。

而使用者亲手创建 的技能(intellectual-property、rd-management、

patents-search、regulatory-affairs-head 等)合计约 105 tok,占索引 0.8%。

这是本研究报告最重要的单项发现之一 :

索引的 81% 消耗在批量迁移产物上,而使用者自己的知识仅占 0.8%。

这一比例关系直接决定了后续所有优化的着力点------问题不在"技能太多",

而在"这个档案为什么要装 443 个迁移技能"。

4.2.4 "迁移产物"的性质辨析

在优化讨论中,"迁移"(migrated)这一来源标记极易被误读为"无用"。

本研究明确反对这一推论,并给出证据:

含有关键能力的迁移包 其中的关键技能 对该档案的价值
scientific-skills uspto-database 专利检索------IP 档案的立身之本
scientific-skills openalex-database、literature-review、peer-review、scientific-critical-thinking、scholar-evaluation、citation-management 学术检索与审稿
scientific-skills docx、pdf、xlsx、pptx、markitdown 交付格式
scientific-skills rdkit、chembl-database、pubchem-database 化学/配方
scientific-skills iso-13485-certification、fda-database、market-research-reports 法规与研报
scienceclaw-migrated crossref-search、semantic-scholar 文献核验
scienceclaw-migrated legal-analysis、regulatory-drafting 法务与法规撰写
scienceclaw-migrated nano-banana-pro、scientific-diagram-generation、data-visualization-expert 顶刊级配图
scienceclaw-migrated pdf-processing、pdf-processing-pro 文档处理

结论 :"来源是迁移" ≠ "内容无用"。 真正的无用部分是同一批迁移里

与档案主题无关的消费级/外设/远缘学科技能,它们只是混在同一批迁移中 。

正确的判据是内容相关性 ,不是来源 。这一认识在第五章与第七章

的路线选择中起了决定性作用。

4.3 工具 schema 的成本结构

prompt-size 提供按工具集(toolset)的成本分解:

工具集 工具数 schema 体积
file 4 5,404 B
browser 5 4,359 B
delegation 1 4,032 B
skills 3 3,650 B
browser-use 1 3,498 B
terminal 1 3,371 B
(unknown) 3 3,328 B
memory 1 3,296 B
code_execution 1 3,009 B
tts 1 1,912 B
web 2 1,910 B
clarify 1 1,636 B
vision 1 845 B
合计 25 40,300 B

观察 3:单个工具的平均 schema 成本约 1,600 字节。

其中 delegation(1 个工具 / 4,032 B)、memory(1 个 / 3,296 B)、

browser-use(1 个 / 3,498 B)是单个工具最昂贵 的三项,

因为它们的参数说明与文档字符串很长。

机制说明 :Hermes 的 tools.tool_search.enabled: auto 提供工具延迟加载:

日志显示 tool_search activated (tier 1): 22 core/visible tools kept, 5 deferred (~4452 tokens)。

在收窄工具集后,该机制的效果更显著:

tool_search activated (tier 1): 5 core/visible tools kept, 1 deferred (~380 tokens)。

推论 :工具 schema 的成本可以通过两条途径降低------

(a)减少启用的工具集;(b)依靠 tool_search 把非核心工具转为延迟加载。

本研究在第七章的实验中同时利用了这两条途径。

4.4 固定载荷的时间折算

以第三章测得的 1,713 tok/s 预填充速率为准:

组成 token 预填充耗时 占比
技能索引 ~14,086 8.2 s 39%
工具 schema ~10,075 5.9 s 28%
身份/指令(含 SOUL.md 人格) ~4,664 2.7 s 13%
记忆 + 用户画像 ~1,542 0.9 s 4%
(按 36,109 tok 口径的其余部分) ~5,742 3.4 s 16%
合计 36,109 21.1 s 100%

再加上一次 500 token 的回答(8.3 s 生成):

一次"全新轮次"(前缀未命中缓存)约需 29 秒纯计算,不含工具执行 I/O。

这是本研究的核心量化结论。 它意味着:在本地模型上,

使用者感知到的"卡顿"主要不是模型在思考,而是在重复读取一份每轮都不变的文本。

4.5 前缀缓存:救赎及其严格条件

4.5.1 实测证据

复制代码
API call #1: model=qwen3.8-hermes in=11632 out=46 total=11678 latency=55.1s
API call #2: model=qwen3.8-hermes in=11694 out=22 total=11716 latency= 1.0s

第二轮 in= 仅比第一轮多 62 tokens ,而延迟从 55.1 s 降至 1.0 s。

另一次独立验证(重复同一 6,686 token 提示):

复制代码
prompt_eval_count = 23     ← 提示共 6,686 token,仅重算 23 个

结论 :Ollama 在第 2 轮及之后复用 KV 前缀缓存,只计算新增部分。

4.5.2 严格条件

前缀缓存的生效需要满足两个条件的联合:

  1. 模型保持驻留------模型一旦卸载,KV 缓存随之销毁(见第六章)。
  2. 提示前缀字节级不变------系统提示中任何字符变化都会使缓存失效。

推论(本报告的关键实践结论):

会话中的操作 对本地模型的影响
加载一个技能(skill_view) 若技能内容进入系统提示 → 缓存失效
写入记忆(memory) 记忆块变化 → 缓存失效
切换工具集 工具 schema 变化 → 缓存失效
切换模型标签(不同权重) 模型重载 + 缓存失效
纯粹继续对话 ✅ 缓存命中,仅付增量

因此,本地模型上的"提示缓存纪律"价值 21 秒/轮。

这也解释了 Hermes 硬性不变量"绝不在会话中破坏提示缓存"在本地场景下的极高价值------

在远程模型上,破坏缓存只影响成本;在本地模型上,它直接影响使用者的等待时间。

4.6 本章小结

结论 数值 可信度
每轮固定载荷 33,600--36,109 tok L1 实测(两法交叉验证)
折合预填充时间 21.1 s L2 推算(1,713 tok/s)
技能索引占系统提示 60% L1 实测
索引中描述占比 ~68% L2 推算(行结构分析)
四个迁移包占索引 81%(443 技能 / 10,545 tok) L1 实测
使用者自建技能占索引 0.8%(~105 tok) L1 实测
工具 schema 成本 40,300 B / 25 工具,均 1,600 B/工具 L1 实测
前缀缓存收益 第二轮延迟 ÷55(55.1 s → 1.0 s) L1 实测
缓存失效的触发条件 系统提示字节变化 / 模型卸载 L2 推算(机制)

瓶颈定位 :瓶颈不在模型,在于"每轮都要重发的固定文本",其中技能索引是最大单项。

第五章 递进一:从"模型参数调优"到"提示词经济学"

本章记录优化的第一次范式转变 ,以及伴随而来的 6 项被实测剔除的伪优化。

5.1 起点假设及其来源

研究开始时的默认假设是:"发挥最大潜力"等于"把模型参数调对"。

这一假设并非凭空产生,它有三个看似合理的来源:

  1. 领域惯例 :本地推理社区的常规讨论集中于 num_ctx、num_batch、
    num_gpu、KV cache 类型、量化等级等参数。
  2. 工具提供的显式旋钮 :Ollama 提供约 10 个环境变量与 8 个请求级参数,
    这些"可见的旋钮"天然吸引注意力。
  3. 可解释性:参数与性能之间的因果关系直观(更大的批 → 更快的预填充)。

因此,研究的第一阶段系统性地检视了这些旋钮的实际可得收益。

5.2 参数旋钮的实测可得性

5.2.1 环境变量

变量 实测状态 结论
OLLAMA_KV_CACHE_TYPE=q8_0 已设,server.log 确认 --cache-type-k/v q8_0 有效,但已是最优
OLLAMA_FLASH_ATTENTION=1 已设,确认 --flash-attn on 有效,但已是最优
OLLAMA_NUM_PARALLEL=1 已设,确认 -np 1 有效但性质是约束------它造成了串行队列(第七章)
OLLAMA_MAX_LOADED_MODELS=1 已设 有效,防止显存抖动
OLLAMA_CONTEXT_LENGTH=8192 已设 数值偏低,是隐患(见 5.3.3)
OLLAMA_KEEP_ALIVE=2m 被桌面版覆盖为 2m 关键问题(第六章)
OLLAMA_NUM_THREAD=24 已设,实际 n_threads = 12 / 24 有效,但内核自选 12
OLLAMA_GPU_OVERHEAD --- 已废弃,0.30+ 不读取
OLLAMA_MAX_VRAM --- 已从代码移除

观察 :环境变量层面的"优化空间"几乎为零------现有设置已接近本机最优 。

唯一有实质影响的两项(KEEP_ALIVE、CONTEXT_LENGTH)都属于配置正确性问题

而非性能调优问题,且其中一个还被上层软件覆盖。

5.2.2 请求级参数

参数 实验 结论
num_batch 512 → 2048 无增益(默认 512 已饱和:865 token 预填充 1,389 tok/s 持平)
num_ctx 8,192 → 65,536 大上下文不降低预填充速率(反而因摊薄固定开销而略升)
num_gpu 默认(999 = 全量) 8/10 个测试模型可全量入显存,无需手工降层
temperature 1.0 → 0.3 不影响速度;影响工具调用的确定性(已采纳 0.3)
think true / false 关闭反而更慢(3.98 s → 4.92 s),见 3.3.3

观察 4:请求级参数的可得收益同样趋近于零。

其中 num_batch 的"无增益"结论尤为重要------它是社区中被最广泛推荐的调优手段之一,

但在本机实测中完全无效。

5.2.3 一个被误设为"参数"的正确性问题

OLLAMA_CONTEXT_LENGTH=8192 这一设置初看是"保守的参数选择",

但结合第四、七章的发现,它是一个隐患:

  • Hermes 的固定载荷为 36,109 tokens;
  • 若某个模型未在 Modelfile 中声明 num_ctx,Ollama 会回退到全局默认值;
  • 则该模型的可用上下文(8,192)小于固定载荷,系统提示根本无法装入。

这一隐患的实际触发条件 是"使用未声明 num_ctx 的模型作为主模型"。

本研究据此把该变量调整为 32,768 (与本机自动推断值一致,见 5.4.2),

并明确记录:Hermes 主模型必须使用在 Modelfile 中声明 num_ctx ≥ 65,536 的模型。

5.3 剔除清单(负结果)

本研究明确剔除以下 6 项候选优化。负结果与方法学上的正结果同等重要 ,

因为它们防止使用者重复投入。

# 被剔除的候选 剔除依据 证据来源
N1 调 num_batch 至 1024/2048 以提速预填充 实测无增益,默认 512 已饱和 865 token 预填充 1,389 tok/s,两档持平
N2 关闭思考模式以减少输出 token 实测更慢(4.92 s vs 3.98 s),且 token 数更多(374 vs 266) 隔离测试
N3 通过 OLLAMA_GPU_OVERHEAD 预留显存给桌面 该变量在 0.30+ 已不被读取 源码审计 + 实测设置无效
N4 通过 OLLAMA_MAX_VRAM 限制显存占用 该变量已从代码移除 源码审计
N5 建 131,072 上下文模型以获得"更大能力" 直接导致推理进程崩溃 RemoteDisconnected + 服务端自我重启
N6 关闭 HAGS / 调整页面文件以"释放显存" HAGS 不影响 CUDA/VRAM(且关掉会断 DLSS);页面文件只影响系统内存交换 机制分析与既有实测

方法论提炼 :这 6 项的共同特征是它们都是"看起来最像优化"的操作 。

N1 是社区共识、N2 是直觉推断、N3/N4 是"文档里写着的变量"、N5 是"越大越好"、

N6 是"操作系统层面的大动作"。它们全部失败于同一个原因:没有先测量。

5.4 范式转变:成本方程

在参数旋钮的收益被判定为趋近于零之后,研究转向提示侧,并建立了三条成本方程。

5.4.1 方程一:轮次成本分解

复制代码
T_turn = T_prefill(固定载荷) + T_prefill(对话增量) + T_generate(输出) + T_tool + T_queue

其中:

项 本机基线 是否可控 控制手段
T_prefill(固定载荷) 21.1 s ✅ 可压缩 削减提示宽度(第七、八章)
T_prefill(对话增量) 每轮 60--300 token ✅ 可压缩 上下文压缩、控制历史长度
T_generate 500 token ≈ 8.3 s ⚠️ 受模型能力限制 控制输出长度
T_tool 由工具本身决定 ⚠️ 有限 减少工具往返次数
T_queue 0--43 s 且随机 ✅ 可消除 串行化调用(第七章)

关键认识 :T_prefill(固定载荷) 与 T_queue 是两个可被工程手段消除的量级项 ,

而其余三项受物理或模型能力约束。因此优化的正确着力点在前两项。

5.4.2 方程二:固定载荷的构成方程

复制代码
L_fixed = L_persona + L_skills_index + L_tools + L_memory + L_profile
         = 4,664 + 14,086 + 10,075 + 905 + 638  (token)
         ≈ 33,600--36,109

该方程的偏导决定优化优先级 :

∂L/∂L_skills_index 最大(14,086 tok),其次是 ∂L/∂L_tools(10,075 tok)。

因此技能索引与工具 schema 是仅有的两个值得削减的项。

5.4.3 方程三:索引的宽度-信息量权衡

设索引中第 i 个技能行的成本为:

复制代码
c_i = 4 + len(name_i) + 2 + min(len(desc_i), 57) + 1

则索引总成本 C = Σ c_i。若把描述全部去掉:

复制代码
c_i' = 4 + len(name_i) + 1
C' / C ≈ 27 / 85 ≈ 32%

即去掉描述可把索引压到约三分之一 ,理论节省约 9,000--11,000 token 。

这一方程是第七章"降级为目录"方案的数学基础。

但方程三只回答了"能省多少",没有回答"省了会失去什么" ------

后者是能力层的问题,正是第七章的核心议题。

5.5 范式转变的表述

优化前范式 优化后范式
关注对象 被调用的模型 调用方发送的内容
主要变量 num_ctx / num_batch / 量化 / 卸载层数 提示宽度、工具集宽度、索引粒度、作用域
优化手段 调整参数 重构信息架构
收益量级 ~0(实测趋近于零) 21.1 s → 可压缩至数秒
风险 低(参数可回退) 中(可能触及能力,需谨慎)
验证方式 吞吐对比 提示规模(in=)+ 能力回归测试

转变的本质 :从"让引擎转得更快 "转向"少运一点货 "。

在本地推理场景中,货物(每轮重发的固定文本)的重量远大于引擎的效率差异。

5.6 本章小结

结论 内容
参数旋钮的可得收益 趋近于零(6 项候选全部剔除)
真正的主导变量 每轮固定载荷的宽度
最大单项 技能索引(14,086 tok,占系统提示 60%)
第二单项 工具 schema(10,075 tok)
可被工程消除的两个量级项 T_prefill(固定载荷) 与 T_queue
三条成本方程 轮次分解 / 载荷构成 / 宽度-信息量权衡
由此确立的优化顺序 削减提示 → 保住缓存/驻留 → 路由分工 → 粒度设计

下一章 将处理一个与"削减"同等重要的变量:

即使提示再短,若模型被反复卸载,每轮仍要付 12.7 秒。

第六章 递进二:驻留经济学与缓存经济学

本章处理两个与"削减提示"正交、但同等重要的变量:模型是否驻留 与前缀是否命中缓存 。

二者都受一条不起眼的环境变量支配,而这条变量又被上层软件静默覆盖。

6.1 问题:一个每次停顿都要重付的常数

6.1.1 现象

在第三章已测得:冷加载一个 17 GB 的 27B 模型需 12.36--12.70 秒。

而本机的 Ollama 服务端环境为:

复制代码
OLLAMA_KEEP_ALIVE: 2m0s

KEEP_ALIVE 的含义是模型在最后一次请求后保持驻留的时长 。

2 分钟意味着:只要使用者思考超过 2 分钟再发下一条消息,模型就会被卸载,

下一条消息要先付出约 12.7 秒的加载代价。

6.1.2 成本模型

复制代码
T_first_token = (模型未驻留 ? T_cold_load : 0) + T_prefill(固定载荷) + T_queue

在本机基线下:12.7 s + 21.1 s + T_queue ≈ 33.8 s + T_queue。

这是一个"设计事故"级别的默认值 :交互式 agent 的使用节奏(思考、查阅、

离开工位)与 2 分钟的窗口严重不匹配。该默认值使"冷加载"从异常路径变成了常规路径。

6.1.3 为什么"改环境变量"没有生效

研究者按常规做法修改了 Windows 用户级环境变量:

powershell 复制代码
[Environment]::SetEnvironmentVariable('OLLAMA_KEEP_ALIVE','30m','User')
[Environment]::SetEnvironmentVariable('OLLAMA_CONTEXT_LENGTH','32768','User')

随即重启 Ollama 并复查注册表:

复制代码
OLLAMA_KEEP_ALIVE        : 30m        ← 注册表已改
OLLAMA_CONTEXT_LENGTH    : 32768      ← 注册表已改

但服务端日志显示的实际生效值为:

复制代码
OLLAMA_KEEP_ALIVE:2m0s
OLLAMA_CONTEXT_LENGTH:65536

注册表被忽略,且服务端的值是注册表中从未出现过的数字(65536)。

6.2 根因定位:上层软件的静默覆盖

6.2.1 排查路径

步 假设 检验 结果
1 环境变量未写入 复查注册表 HKCU\Environment ❌ 假设错误,已写入
2 服务端未重启 强制结束 + 重启,再读日志 ❌ 假设错误,新实例仍为 2m
3 有其他环境源 检查机器级变量、启动器脚本、shell 导出 ❌ 未发现
4 上层软件注入 检查 %LOCALAPPDATA%\Ollama\ 下的数据文件 ✅ 命中

6.2.2 证据链

在 %LOCALAPPDATA%\Ollama\db.sqlite 中发现 settings 表:

sql 复制代码
CREATE TABLE settings (
  id, device_id, has_completed_first_run, expose, survey, browser, models,
  agent, tools, working_dir, context_length, window_width, window_height, ...
);

查得的实际数据:

复制代码
context_length = 65536
selected_model = 'qwen3.8'
think_enabled  = 0

这与服务端日志中的 OLLAMA_CONTEXT_LENGTH:65536 完全吻合。

结论(L1 实测) :Ollama 0.33 的桌面版在启动 ollama serve 时,

会以自己的 SQLite 设置为准 注入环境变量,用户级注册表中的 OLLAMA_* 被静默忽略 。

context_length 明确来自该表;keep_alive 虽无对应列,但服务端固定呈现 2m,

说明该值由桌面版以硬编码或内部默认的方式注入。

6.2.3 这一发现的一般意义

层面 含义
运维 "改了环境变量却没生效"的排查必须包含"上层软件是否覆盖"这一分支,且需直接读取上层的配置存储,而非只看自己写入的位置
方法论 验证配置是否生效,必须读"消费者"的日志,而不是"写入者"的界面 。注册表是写入者视角;server.log 的 server config 行才是消费者视角
工具 本研究据此新增了一条标准自检:grep 'server config' server.log,逐项核对 6 个关键变量的实际生效值

6.2.4 一个附带的稳定性问题

排查过程中研究者多次强制结束 Ollama 进程以应用环境变量,观察到两个副作用:

  1. 桌面版会自我重启 :强制结束后,ollama app.exe 会被重新拉起,
    与被结束的动作形成竞争。多次操作后一度出现
    3 个 llama-server + 2 个 ollama + 2 个 ollama app 并存的污染状态。
  2. 托盘版在非交互上下文中会退出 :从终端以分离方式启动 ollama app.exe 时,
    它在调用返回后即退出(推测与需要交互式桌面会话有关),
    导致本地推理反复不可用。

修正措施:

  • 清理为单一实例,并新增 verify.sh 的第一步即为"进程唯一性检查"。
  • 提供脱离式启动脚本(使用
    DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_BREAKAWAY_FROM_JOB
    三个标志组合以逃出父 shell 的 job object)。
  • 明确纪律:诊断完成后不再反复结束该服务。

方法论含义 :排查过程中的"反复重启"本身就是一种破坏性操作。

它把一个确定的状态变为不确定的状态,且可能掩盖原始问题。

本研究将此列为负面教训(见第十一章第 7 项)。

6.3 解法:请求级保温

6.3.1 机制

既然服务端默认值难以持久提高,改从请求级 入手。

Ollama 的 /api/generate 接受 keep_alive 参数,且请求级优先于服务端默认值。

验证实验:

bash 复制代码
curl --noproxy "*" -s -o /dev/null http://127.0.0.1:11434/api/generate \
  -d '{"model":"qwen3.8-hermes","prompt":"","stream":false,
       "keep_alive":"45m","options":{"num_predict":1}}'

随即查询驻留状态:

复制代码
RESIDENT qwen3.8-hermes  ctx=65536  UNTIL=2026-09-12T00:48:06
(当时时间为 00:03:07 ------ UNTIL 被推后了 45 分钟)

请求级 keep_alive 确实优先生效。

6.3.2 成本实测

场景 单次触碰耗时
模型已驻留(暖机) 0.0057 s / 0.0035 s
模型已卸载(冷机) 27.4 s(此时触碰本身就包含了加载)

暖机状态下,一次"保温触碰"的成本是毫秒级------因为它只评估 1 个 token。

等效性论证 :以每 60 秒触碰一次计算,

若因此避免了每小时 5 次冷加载,则节省 5 × 12.7 = 63.5 s,

而触碰成本 60 × 0.0057 ≈ 0.34 s。投入产出比约 190:1。

6.3.3 交付形态

keepwarm.ps1:支持 -Model / -IntervalSeconds / -Minutes / -Once,

每次触碰后输出当前上下文长度、显存占用与到期时间,便于持续观测。

亦可交由 Hermes 的定时任务执行,无需常驻窗口。

6.3.4 一条被否定的替代路径

研究者曾考虑"直接改用 headless ollama serve 以完全掌握环境变量"。

该路径技术上可行(已交付 start_ollama_serve.py),但未被采纳为默认方案 ,

理由:

优点 缺点
环境变量完全可控(可把 KEEP_ALIVE 设为 -1 或 30m) 改变使用者的既有启动方式
无 GUI 依赖,稳定性更好 若托盘版后续启动会争抢端口
便于脚本化 会话结束后进程可能随父进程退出

折中 :把"保温触碰"作为默认方案(零侵入),

把 headless 启动脚本作为使用者自主选择的备选。

6.4 缓存经济学:前缀缓存的严格条件

6.4.1 收益已知,条件需明确

第四章已实测前缀缓存的收益:第二轮延迟从 55.1 s 降至 1.0 s ,

in= 仅增加 62 token。但缓存不是无条件生效的。

6.4.2 失效条件矩阵

操作 是否使前缀缓存失效 机制
继续对话(追加消息) ❌ 不失效 前缀未变,仅增量计算
系统提示中任何字符变化 ✅ 失效 前缀字节不匹配
加载技能(内容进入系统提示) ✅ 失效 技能索引块变化
写入记忆 / 用户画像 ✅ 失效 记忆块变化
切换工具集 ✅ 失效 工具 schema 变化
切换模型标签(不同权重) ✅ 失效 + 重载 KV 缓存随模型销毁
模型被卸载(超时) ✅ 失效 KV 缓存随模型销毁
切换上下文长度参数 ✅ 失效 KV 形状改变

6.4.3 推论:纪律即性能

上表把"使用习惯"变成了可量化的性能参数:

习惯 代价
在一个会话内连续完成多步工作 ✅ 每轮仅付增量(约 1--3 s)
每步都新开一个进程 ❌ 每步重付 21.1 s
在会话中途加载技能/写记忆 ❌ 该轮重付 21.1 s
长时间停顿导致模型卸载 ❌ 额外 12.7 s(除非保温)

这解释了一个此前只被视为"设计洁癖"的构架约束 :

Hermes 的硬性不变量"绝不在会话中破坏提示缓存 (不改变历史上下文、工具集或系统提示)",

在远程模型上只影响成本,在本地模型上直接影响使用者的等待时间 ------

它值 21 秒/轮。

6.4.4 多步任务的最优形态

由上述两条经济学合并得出:

多步任务应交给同一个本地会话连续执行,而不是每步新起进程。

实测支持:同一会话内第 2 次 API 调用 in=11694(仅 +62 tok)、latency=1.0 s;

而新起进程的首次调用恒为 in≈11,600--32,000、latency=12--31 s。

这一结论在第七章被进一步细化 :当任务是"批量独立小任务"时,

单会话串行 vs 多进程并行的取舍需考虑本地串行队列的存在(第七章)。

6.5 本章小结

结论 数值 / 内容 可信度
冷加载代价 12.36--12.70 s L1
服务端 KEEP_ALIVE 默认值 2m0s L1
该值的来源 Ollama 桌面版注入(db.sqlite 的 settings) L1
注册表环境变量是否生效 否(被静默覆盖) L1
请求级 keep_alive 是否优先 是(UNTIL 推后 45 分钟) L1
保温触碰成本(暖机) 0.004--0.006 s L1
保温的投入产出比 约 190:1 L2 推算
前缀缓存收益 第二轮延迟 ÷55 L1
缓存失效的触发条件 9 类操作,其中 6 类属于"使用习惯" L2
由缓存导出的纪律 单会话连续执行 + 不改系统提示 + 保持驻留 L2

本章确立的第二条优化主线 :提示削减之外,还有"驻留与缓存"这条被低估的战线。

两条主线的收益量级相当(各约 12--21 秒/轮)。

第七章 递进三:混合路由体系与工具集宽度的发现

本章回答 RQ4:远程模型与本地模型的正确分工是什么?判据是什么?

并记录一次重要的方向性自我纠错(工具集宽度)。

7.1 三层路由:被普遍忽略的 Tier-0

7.1.1 初始框定及其不完整

使用者给出的初始需求是两层结构:

远程 API 模型负责设计、规划、推理;本地模型只做任务执行。

这一框定正确且有价值,但它遗漏了成本最低的一层。

7.1.2 补全后的三层模型

层 执行者 适用任务 实测成本
Tier 0 无模型 远程大脑直接写脚本 / 命令执行 能被完全指定的确定性任务 0 token,毫秒级
Tier 1 本地手 qwen3.8-hermes(单并发串行) 需语言理解、不需权衡、量大/私密/重复 11.6k--16k 提示,9--12 s
Tier 2 远程大脑 远程主模型 规划、设计、歧义消解、高风险判断、验收 in=218k--294k/轮

Tier-0 的存在是一个常被忽略的盲点。

"把 200 个 CSV 合并并报告行数"不需要任何模型------

远程大脑自己调用 terminal 即可完成。只有当任务无法用确定性命令表达时,
才值得动用模型(无论远程还是本地)。

7.1.3 路由判据(可执行的决策清单)

按顺序提问,命中即停:

  1. 能写成一条确定性的命令或脚本吗? → Tier 0(不调模型)
  2. 需要权衡、歧义消解、多步设计或高风险判断吗? → Tier 2 远程
  3. 需要语言理解但答案唯一,且量大 / 涉隐私 / 高度重复吗? → Tier 1 本地
  4. 要一次处理很多项、彼此独立吗? → Tier 2 并行 (delegate_task,远程)
    ⚠️ 绝不要扇出到本地(原因见 7.3)

7.1.4 典型分派表

任务 层 机制
批量重命名 / 格式转换 / grep / 合并文件 0 远程大脑 → terminal
专利权利要求布局设计、创造性判断 2 主循环
并行调研多篇文献做方案对比 2 delegate_task(远程)
把 200 个 PDF 抽成结构化 JSON 1 本地执行者
长文压缩、标题生成、视觉识图 1 auxiliary.* 辅助通道
每日定时抓取并清洗数据 1 定时任务(本地模型)
远程 API 断线时继续工作 1 兜底链

7.2 工具集宽度:本阶段最重要的发现(含一次方向性纠错)

7.2.1 实验设计

控制变量 :同一模型(qwen3.8-hermes)、同一档案、同一工单

("运行 echo hello 并只回报输出")、同一时间窗口。

唯一自变量 :-t 指定的工具集。

测量口径 :以 agent.log 的 in= 为主(确定性),墙钟为辅。

7.2.2 结果

工具集 真实提示 in= 墙钟 tool_search 状态
完整(25 工具) 32,216 tok 31.1 s 22 core + 5 deferred(~4,452 tok)
-t terminal,file 11,632 tok 12.2 s 5 core + 1 deferred(~380 tok)
-t terminal 10,375 tok 11.2 s ---

净效果:提示 −64%(32,216 → 11,632 tok),延迟 −61%(31.1 → 12.2 s)。

7.2.3 机制分析:为什么降幅远超工具 schema 本身

工具 schema 从约 10,075 tok 降至约 380 tok,只能解释约 9,700 tok 的降幅;

而实际降幅为 20,584 tok。缺口约 10,900 tok,来源是:

源码级机制 (agent/system_prompt.py):

python 复制代码
def _skills_prompt(agent: Any) -> str:
    """Skills index (empty without skills tools).  Focus mode demotes non-coding
    categories to names-only --- never hidden, every name stays visible."""
    if not any(name in agent.valid_tool_names
               for name in ['skills_list', 'skill_view', 'skill_manage']):
        return ""

当工具集里不存在技能工具时,整个技能索引块返回空字符串。

本档案的技能索引为 14,086 tok,正是缺口的主体。

叠加机制 :tool_search 在工具集收窄后把工具块压到 380 tok

(日志:5 core/visible tools kept, 1 deferred (~380 tokens))。

合计 :14,086(技能索引)+ 9,700(工具 schema)≈ 23,800,

与实测 20,584 tok 同量级(差异来自分类标题与样板文字的连带消失)。

7.2.4 方向性纠错(本研究第 2 项错误)

研究者最初的结论 是:"给手最小工具集是本地执行优化的第一杠杆" ,

并据此建议本地执行者使用 -t terminal,file。

该结论被使用者当场质疑,并被源码证实为方向性错误:

被 -t terminal,file 移除的能力 后果
skills_list / skill_view / skill_manage 完全无法使用任何技能(含 SOP、模板、references)
web_search / web_extract 无法联网查证(如 DOI/OA 核验)
vision_analyze 无法识图(专利附图、扫描件)
patch / search_files 只能整文件覆盖,不能精确修改
memory / session_search 不持久化、不留检索痕迹
todo / delegate_task 无任务规划、无自我分派
cronjob / skill_manage 不能定时、不能固化经验

使用者的表述准确地指出了问题:

"手不是要做机械手,而是具有职能的手。"

研究者的自我批评 :该建议把"速度 "当成了唯一目标函数,

而忽略了优化对象的角色定义 。一个没有技能能力、没有联网能力、没有识图能力的执行者,

在本研究的使用场景中不是"更快的执行者",而是"不能完成工作的执行者"。

该结论已被下调并修正 (见第九章的融合方案)。

此错误的完整记录见第十一章第 2 项。

7.3 串行队列:一个被结构性忽略的约束

7.3.1 现象

在测量工具集宽度时,研究者遭遇了自相矛盾的墙钟数据(详见第二章 2.3.1)。

深挖后发现完全相同的一个请求呈现出极端的时间差异:

场景 该请求的延迟
无并发干扰 12.2 s
有其它本地请求在跑 55.1 s

劣化 4.5 倍,且随机不可预测。

7.3.2 根因

服务端启动参数中明确标注:

复制代码
-np 1

对应环境变量 OLLAMA_NUM_PARALLEL=1------单并发槽 。

任何并发请求都会进入队列,其延迟变为"服务时间 + 排队时间"。

7.3.3 实验证据(补强)

研究者安排了两个并发任务(A 与 B)以验证队列行为:

复制代码
[lock] 本地执行者忙,排队中(NUM_PARALLEL=1,串行执行)...
A: WALL = 11 s
B: WALL = 9 s(等待 A 完成后执行)

日志中出现了预期的排队提示,且 B 在 A 之后才执行。

7.3.4 推论与工程设计

推论 工程措施
不要并发扇出到本地(扇出 = 排队,不会加速) 并行任务留在远程(delegate_task)
本地调用必须串行化 local_exec.sh 内建 mkdir 原子锁 + 死锁回收 + 排队提示
本地辅助通道会与本地执行者抢槽 大批本地执行前可临时把辅助通道收回远程
延迟类结论必须在无并发条件下测量 以 in= 为主口径

实测到的抢槽证据 :辅助通道的标题生成出现

Auxiliary title_generation: transient transport error (attempt 1/2); retrying same provider after 1.0s before fallback: Request timed out。

7.4 反向验证:一个"看起来应该做"但不该做的配置

7.4.1 假设

既然本地模型可用,且子智能体(delegate_task)适合做执行------

那么把 delegation.provider 指向本地模型,岂不就实现了"远程规划 + 本地执行"?

7.4.2 验证与否定

源码 tools/delegate_tool.py:557 明确说明:

"Children inherit the parent model unless pinned via delegation.provider / delegation.model in config.yaml."

即该配置确实能把子智能体路由到本地。但进一步的源码检查发现关键限制:

python 复制代码
child_toolsets, child_disabled_toolsets = _resolve_child_toolsets(parent_agent, toolsets, effective_role)

_resolve_child_toolsets() 不接受按调用方指定工具集的参数 ------子智能体继承父级的完整工具集。

因此 :一个本地子智能体携带的是完整 25 工具 的提示,

实测为 32,216 tok / 约 31 s,且因单并发而排队。

结论:不要将 delegation.provider 指向本地模型。

  • 保留 delegation.* 指向远程强模型,用于并行研究类任务;
  • 本地执行 改由"生成独立进程 + 指定最小职能工具集"的路径承担
    (即 local_exec.sh,它通过 -t 绕过了"子智能体无法指定工具集"的限制)。

方法论含义 :"配置项存在"不等于"该配置是最优解"。

该配置项在功能上可用,但在成本结构上劣于替代方案。

7.5 成本证据:为什么这套分工值得做

hermes insights --days 1(官方 CLI 口径):

模型 会话数 token 数
远程(DeepSeek-V4.1-Flash) 1 13,863,060
本地(qwen3.8-hermes / qwen3.8-opt-64k) 5 208,757

比例约 66 : 1。

远程单轮的输入规模亦被记录:

复制代码
API call #21: model=DeepSeek-V4.1-Flash in=283723 out=1719 total=285442 latency=10.3s cache=283
API call #1:  model=DeepSeek-V4.1-Flash in=218355 out=1995 ... cache=217344/218355 (100%)

观察 5 :远程模型的 in= 达到 20 万--29 万 token/轮 ,

且缓存命中率 100%(cache=217344/218355)。

缓存显著降低了成本 ,但上下文占用 依然存在------

每一轮都要在 20 万 token 的上下文中定位。

这是一条对"是否值得把负载移到本地"的强证据 :

把机械性、高体积的任务移到本地,可同时降低远程费用与远程上下文压力。

7.6 辅助通道的本地化(11 项)

7.6.1 决策依据

依据"能力---频次---判断强度"三维打分,把 13 个辅助通道分类:

通道 判断强度 频次 决策
vision 低 中 ✅ 本地
compression 低 高 ✅ 本地
skills_hub 低 中 ✅ 本地
mcp 低 中 ✅ 本地
title_generation 极低 高 ✅ 本地
tts_audio_tags 极低 低 ✅ 本地
triage_specifier 低 中 ✅ 本地
profile_describer 极低 低 ✅ 本地
curator 低 低 ✅ 本地
monitor 低 中 ✅ 本地
web_extract 低 中 ✅ 本地
approval 高(安全相关) 低 ❌ 保留远程
kanban_decomposer 高(分解质量) 低 ❌ 保留远程

7.6.2 端到端验证(活体探针)

调用视觉工具分析本机生成的测试图,并以服务端日志确证路由:

证据 内容
功能返回 "A red circle and a blue square are shown on a white background." ✅ 与图像一致
服务端日志 `[GIN] 2026/09/12 - 00:06:37
推理统计 total time = 6471.75 ms / 381 tokens,draft acceptance = 0.52163

确证:该次视觉调用确实由本地模型完成,而非远程。

7.6.3 已知代价(如实标注)

本地辅助通道依赖 Ollama 存活。测试期间 Ollama 曾意外退出,

同一次视觉调用返回 Connection error(openai.APIConnectionError,见 logs/agent.log),

服务恢复后即成功。

该事件最初被误判为"配置错误",属于本研究第 7 项错误(见第十一章)。

缓解措施:为关键辅助通道配置远程兜底链:

yaml 复制代码
auxiliary:
  vision:
    provider: ollama-launch
    model: qwen3.8-hermes
    base_url: http://127.0.0.1:11434/v1
    fallback_chain:
      - provider: blsc
        model: Qwen3.8-Flash
        base_url: https://llmapi.blsc.cn

值得注意的是:hermes config set 会对 fallback_chain 报

"not a recognized config key"(CLI 白名单陈旧),但实测已正确落盘为 YAML 列表 ,

且源码 if isinstance(chain, list) 的校验通过。

7.7 兜底链:把本地作为保险

bash 复制代码
hermes config set fallback_model '{"provider":"ollama-launch","model":"qwen3.8-hermes"}'

hermes fallback list 实测输出:

复制代码
Primary:   DeepSeek-V4-Flash-0731  (via blsc)
Fallback chain (1 entry):
  1. qwen3.8-hermes  (via ollama-launch)
Tried in order when the primary fails (rate-limit, 5xx, connection errors).

为什么需要它 :历史请求转储显示,该档案的会话确实曾因远程 401 中断:

复制代码
request_dump_20260902_163255_41e6bb_*.json
error.type = Unauthorized (401)
message = "The API key format is incorrect"

配置兜底链后,此类中断不再导致会话终止,而是退回本地继续工作。

7.8 工程化:本地执行者封装

local_exec.sh 的核心设计(各要素均来自本章的实测结论):

要素 依据
工具集默认 terminal,file,skills 保留执行 + 技能职能(第 7.2.4 节纠错后)
HERMES_SKILLS_DEMOTE_ALL=1 默认 第八章的整表降级方案
mkdir 原子锁 + 排队提示 第 7.3 节的串行队列约束
自动回贴 in= / latency= 第 2.3 节的口径纪律
--dry 干跑 降低误发工单的风险
超时与退出码分级 0 成功 / 1 参数错 / 2 锁超时 / 3 调用失败

工单协议(因手在"仅目录"模式下没有技能描述):

复制代码
目标:<一句话,可验证>
输入:<绝对路径 / 具体数据>
约束:<编码、格式、不能碰什么>
输出:<精确格式,便于父会话直接消费>
验收:<如何自检>
完成即止:不要探索、不要额外优化、不要询问

验收实测:

复制代码
$ bash local_exec.sh "运行 echo router-ok 并只回报输出"
  | router-ok
  WALL = 32 s   exit=0
  API call #1: in=11633 out=47 latency=24.7s
  API call #2: in=11697 out=25 latency= 1.3s

7.9 本章小结

结论 内容
路由层数 三层(含被忽略的 Tier-0"不调模型")
工具集宽度的收益 提示 −64%,延迟 −61%(但也曾因此犯方向性错误)
本地并发性质 单并发串行队列,扇出只是排队
delegation 指向本地 ❌ 不应做(子智能体继承完整工具集)
成本证据 远程:本地 token = 66:1
辅助通道 11 项本地化,2 项保留远程;已端到端验证
兜底链 已配置并验证;有历史 401 中断作为必要性证据
工程化产出 local_exec.sh(串行锁 + 审计 + 工单协议)

回到"提示削减"这条主线,处理一个更深的问题:

当削减触碰到能力边界时,应当选何种粒度。

第八章 递进四:动态加载、粒度错配与伪两难的消解

本章回答 RQ5:削减提示成本的"粒度"与"作用域"如何选择?

这是本报告在方法学上最有价值的章节。

8.1 问题的提出:当削减触碰能力边界

第七章确立了一个事实:收窄工具集可省 20,584 token,但会静默移除能力。

使用者明确否定了这条路线,并提出替代方向:

"不要通过剪枝技能来优化,而是通过优化 skills 的动态加载调用来达到

最小投入最大效果的目的。"

这一指示把问题重新定位于:如何在"模型不知道有某技能"与"模型不能做某事"之间做出区分?

8.2 能力的三分:可发现性 / 可加载性 / 可用性

本研究首先建立了一个三分模型,用以精确描述"能力损失"的不同形态:

层次 含义 失效表现
可发现性(discoverability) 模型在系统提示中看到该能力的存在 模型不会主动想到使用它
可加载性(loadability) 模型可以按名称取得该能力的完整内容 即使知道名字也无法调用
可用性(usability) 该能力所依赖的工具/环境确实存在 加载成功但执行失败

这一三分模型的价值在于 :它把"削减"这件事从二元(保留 / 移除)

变为可选择在哪个层次上削减:

削减手段 可发现性 可加载性 可用性
保留完整描述(现状) ✅ ✅ ✅
降级为仅目录(本章方案) ✅(名字保留) ✅ ✅
移除技能工具(第七章的剪枝) ❌ ❌ ❌
禁用技能(skills.disabled) ❌ ❌(skill_view 直接报错) ❌
移除某工具集 视情况 视情况 ❌

关键发现 :"降级为仅目录"是唯一能在保持可加载性与可用性的同时降低成本的层级。

这一发现并非本研究原创------Hermes 自身已实现该机制,且其源码注释即为此写的。

8.3 Hermes 既有的渐进式披露机制

8.3.1 三处源码证据

证据一 :技能工具的自我定义(tools/skills_tool.py:2)

python 复制代码
"""Skills Tool --- list and view skill documents (progressive disclosure)."""

证据二 :skills_list 支持类别过滤(skills_tool.py:600)

python 复制代码
SKILLS_LIST_SCHEMA = {
    "name": "skills_list",
    "description": "List available skills (name + description). Use skill_view(name) to load full content.",
    "parameters": {"properties": {"category": {"type": "string",
        "description": "Optional category filter to narrow results"}}}}

证据三 :索引行截断至 57 字符描述(agent/curator.py:275 的说明)

复制代码
"are truncated to 57 chars in the system prompt skill index --- keep the "

结论 :Hermes 的系统提示索引是一份"菜单" ,而不是能力本身。

真正的能力在 skill_view(name) 与 skills_list(category=...) 中按需加载。

"动态加载"并非需要新建的机制,而是既有的设计。

8.3.2 Hermes 作者已经踩过同一个坑

agent/coding_context.py 中有一段注释,直接确认了本研究的结论方向:

python 复制代码
    def compact_skill_categories(self) -> frozenset[str]:
        """Skill categories to demote to names-only in the skill index. Gated on ``focus``
        like the toolset collapse (index changes under ``auto`` proved too surprising).
        Demoted, never hidden: pruning caused silent capability loss."""

以及 _skills_prompt 的文档字符串:

复制代码
"Focus mode demotes non-coding categories to names-only --- never hidden,
 every name stays visible."

"Demoted, never hidden: pruning caused silent capability loss."

这句话是本研究最重要的外部印证:Hermes 的维护者选择"降级而非裁剪",
并且明确记录了裁剪的代价是"静默的能力损失"
------与使用者提出的关切完全一致。

8.4 降级机制的工作原理与实测

8.4.1 渲染分支

agent/prompt_builder.py 中的渲染逻辑:

python 复制代码
    # Demoted categories collapse to one names-only line. NEVER drop entries ---
    # agent-created skills are the model's project memory and it won't rediscover
    # them via skills_list. Nested categories follow their parent.
    demoted = frozenset(cat for cat in skills_by_category
                        if cat.split("/", 1)[0] in (compact_categories or frozenset()))
    ...
    for category in sorted(skills_by_category):
        entries = skills_by_category[category]
        if category in demoted:
            index_lines.append(
                f"  {category} [names only]: {', '.join(sorted({n for n, _ in entries}))}")
            continue

三个要点:

  1. 降级类别的全部技能名 被拼成一行列出------没有任何条目被丢弃。
  2. 匹配是前缀式 的:cat.split("/", 1)[0],因此写 scientific-skills
    即可覆盖 scientific-skills/skills。
  3. 匹配单位是类别------这是本章后续问题的根源。

8.4.2 内置白名单及其"打偏"

内置的降级白名单为:

python 复制代码
_NON_CODING_SKILL_CATEGORIES = (
    "apple", "communication", "cooking", "creative", "email", "finance", "gaming",
    "gifs", "health", "media", "music", "note-taking", "productivity", "shopping",
    "smart-home", "social-media", "travel", "yuanbao",
)

该名单按"是否与编程相关"分类 (因为它服务于 coding 姿态)。

在本档案上实测其效果:

项 数值
命中技能数 54
索引成本变化 1,003 → 221 tok
节省 782 tok ≈ 0.5 s/轮

结论:内置机制打偏了。 本档案索引成本的两个最大来源

(scientific-skills 3,176 tok、scienceclaw-migrated 2,687 tok)

不在白名单内,因此内置机制只值 0.5 s/轮,占可得收益的 8%。

8.4.3 四份候选名单的实测收益

研究者据此提出四份候选降级名单(实测于隔离渲染环境):

方案 内容 省 tok 省 s/轮 省% 名字保留
① scientific-skills、scienceclaw-migrated 4,474 2.6 31% 100%
② ① + bmad-migrated、workbuddy-migrated 5,376 3.1 37% 100%
③ ② + creative/media/email/productivity/gaming/... 7,406 4.3 52% 100%
④ 除 IP 核心外全部(含 research/software-development/mlops) 10,797 6.3 75% 100%

所有四份方案的名字保留率均为 100% ------这是降级机制的性质保证。

skills_list 可见技能数与 disabled 计数均未改变(实测 disabled = 0)。

8.5 伪两难的识别

8.5.1 表面的权衡

四份名单呈现出一个清晰的权衡曲线:

复制代码
省得越多  ←──────────────────────────────→  误伤越大
   ①2.6s        ②3.1s        ③4.3s        ④6.3s
   无           无           有           严重

而"有误伤"的具体内容经实测为:

类别 其中被误伤的关键能力
productivity docx、pdf、xlsx(使用者的交付格式)
creative baoyu-article-illustrator、baoyu-infographic、claude-design(插图线)
research academic-manuscript-audit、grounded-citations(论文线)
software-development skill-orchestration-strategy、subagent-driven-development

即:用户无法既拿到高收益又避免误伤。 这看起来是一个必须做出的取舍。

8.5.2 关键洞察:该权衡源于粒度错配

研究者对上述权衡做了归因分析,发现它并非问题固有,而是"匹配粒度"造成的:

环节 现状 后果
匹配单位 类别 (scientific-skills 是原子的) 无法在类别内部区分"关键技能"与"无关技能"
作用域 档案级(配置写在 profile 的 config.yaml) 无法让"主会话"与"本地手"取不同值
类别内部同质性 不成立 (productivity 同时含 docx 与 airtable) 任何类别级决策都会误伤

因此,这个"收益 vs 误伤"的权衡是一个伪两难(false dilemma) :

它不是由"成本与能力的内在矛盾"产生,而是由实现粒度的选择产生。

8.6 第三条路径:把粒度从"按类别"改为"按进程"

8.6.1 设计

既然问题出在粒度,就在粒度上求解。研究者提出的替代方案是:

不挑类别。整表降级为仅目录,用"作用域"决定谁生效。

8.6.2 实现

对既有补丁(8.4.3 节的配置驱动能力)扩展两个作用域开关:

python 复制代码
            # Whole-index demotion (names-only for EVERY category). Two scopes:
            #   skills.demote_all: true          -> this profile always
            #   HERMES_SKILLS_DEMOTE_ALL=1       -> this PROCESS only
            _all = _skills_cfg.get("demote_all") or os.getenv("HERMES_SKILLS_DEMOTE_ALL")
            if str(_all or "").strip().lower() in {"1", "true", "yes", "all"}:
                from agent.skill_utils import get_skills_dir
                base = base | frozenset(p.name for p in get_skills_dir().iterdir() if p.is_dir())

关键点是"进程级作用域" :同一个档案下,主会话(无该环境变量)

保持完整描述,而由 local_exec.sh 生成的本地执行者(带该环境变量)

得到仅目录的菜单。

这不需要:新建档案、挑选类别、禁用任何技能、删除任何文件。

8.6.3 实测收益

方案 bytes tok 省 tok 省 s/轮 省% 名字保留
② 按类别挑 35,970 8,992 5,360 3.1 37% 100%
③ 按类别挑 27,849 6,962 7,390 4.3 51% 100%
④ 按类别挑(最激进) --- --- 10,797 6.3 75% 100%
⑤ 整表降级 13,122 3,280 11,072 6.5 77% 100%

整表降级比最激进的 ④ 还多省(6.5 vs 6.3 s/轮),且零类别误伤。

8.6.4 机制验证

检验 结果
py_compile ✅ 通过
惰性(无配置、无 env) ✅ 返回 ∅,渲染与打补丁前一致
skills.demote_all: true ✅ 返回 47 个类别
HERMES_SKILLS_DEMOTE_ALL=1 ✅ 返回 47 个类别(进程级作用域可用)
整表降级后的名字保留 563 个名字 vs 基线 560,丢失 0
[names only] 行数 53
skills_list 可见数 560(未减少)
disabled 计数 0

8.6.5 端到端实测(决定性证据)

实验设计:同一档案、同一模型、同一工单,仅改变执行者的菜单模式。

配置 skills 工具 菜单 in=
A. 现状 ✓ 完整描述 26,087
B. 整表降级 ✓ 仅目录(env) 15,907(−39%)
C. 剪枝参照 ✗ 无 11,632

并从 agent.log 抽取执行者的实际调用记录:

复制代码
API call #1: in=15907 out=53 latency=31.2s
API call #2: in=15969 out=30 latency=31.6s

能力保留的实证 :以 local_exec.sh 派发工单

"用 skills_list 列出 intellectual-property 类别的技能名,只回报数量",

执行者在仅目录模式 下成功调用 skills_list 并返回 2(该类别技能数的正确值),

exit=0,in=15,914。

结论:

整表降级方案在保留全部技能职能(skills_list 与 skill_view 均可用、
disabled = 0、名字 100% 保留)的前提下,把执行者的提示从 26,087 降至 15,907 tok(−39%),
相当于拿到了"剪枝路线"收益(A→C 的 14,455 tok)的 70%。
而"保留职能"的价格仅为 4,275 tok ≈ 2.5 s。

8.7 "伪两难"的消解结果

回顾本章开头的权衡曲线,融合方案消解了它:

方案 收益 误伤 是否需要挑类别
按类别挑(①--④) 2.6--6.3 s 有 / 无(取决于档位) 需要
按进程定(⑤) 6.5 s 零 不需要

即:收益最高的方案,也是误伤为零的方案,且决策成本最低。

这直接证明了前述权衡是人为的。

8.8 实践配置建议

角色 菜单模式 理由
主会话(大脑) 完整描述 规划者需要描述来做技能路由
本地执行者(手) 仅目录(local_exec.sh 默认开启) 执行者只需知道名字 + 按需加载
需要描述的特殊工单 --full-menu 临时关闭降级 保留逃逸舱口

设计律:

大脑拿菜单,手拿目录。

8.9 本章小结

结论 内容
能力三分模型 可发现性 / 可加载性 / 可用性,三者可独立削减
最优削减层级 仅降级描述(唯一保持后两层的层级)
外部印证 Hermes 源码注释:"pruning caused silent capability loss"
内置白名单 有效但打偏,只值 0.5 s/轮(占可得收益 8%)
四份类别名单 2.6 / 3.1 / 4.3 / 6.3 s,均 100% 保留名字
伪两难的成因 粒度错配(按类别匹配 + 档案级作用域)
第三条路径 按进程定菜单粒度,6.5 s/轮,零误伤
端到端效果 26,087 → 15,907 tok(−39%),能力 100% 保留
设计律 大脑拿菜单,手拿目录

第九章 递进五:决策融合与深层逻辑提炼

本章回答两个问题的合并形式:两个原本独立的选择能否被融合?其背后的深层逻辑是什么?

9.1 原初的两个独立选择

在第八章之后,使用者面临两个看似独立的决定:

选择 选项
选择一:补丁去留 留下补丁 / 回滚补丁
选择二:降级名单 ① / ② / ③ / ④ / 不启用

表面上这是一个 2 × 5 = 10 种组合的决策空间。

9.2 选择一的优劣分析

留下补丁 回滚补丁
优势 ① 获得"按进程/按档案定菜单宽度"的能力 ② 惰性------不设配置/不设 env 时行为与打补丁前逐字节一致 ③ 三级回滚,随时可撤 ④ diff 与重打脚本已固化 ① 零源码改动 ② 零 hermes update 风险 ③ 不触碰上游文件
劣势 ① hermes update 会 git stash 掉它 → 优化静默停止生效 ② 上游修改该文件时重打可能冲突 ① 失去第三条路径 → 只能回到①②③④的误伤两难 ② 无法让"主会话与手共用档案却各取粒度"

关键认识 :补丁本身不省时间,它只是一个"能力开关"。

因此"忘记重新打补丁"的代价不是"系统变坏",而是"优化暂时不生效"。

这是一种无损劣化 (lossless degradation),与"有损优化"(先有效果、后失能力)

在风险性质上完全不同。

裁定:留下补丁。

9.3 选择二的优劣分析

选项 收益 误伤 决策成本
① 两个大包 2.6 s(38%) 无 低
② 4 个迁移包 3.1 s(49%) 无 低
③ +无关生活类 4.3 s(51%) ⚠️ 有 中(须逐类核对)
④ 除核心外全部 6.3 s(75%) ❌ 严重 高(须逐类核对)
不启用 0 无 零

关键认识 :这五个选项全部处在同一条权衡曲线 上------

"省多少"与"误伤哪个类别"成反比。而第八章已证明该曲线由实现粒度造成,不是问题固有。

9.4 融合设计

9.4.1 融合矩阵

维度 融合做法 消掉了什么劣势
补丁 留下,但只当能力开关,不指望它省时间 消掉选择一的劣势①:忘重打 = 退回现状(无损),而非系统变坏
菜单宽度 按进程定(env),不按类别挑 消掉①②③④的"收益 vs 误伤"权衡
主会话 完整描述(不动) 保住大脑做技能路由所需的描述信息
本地手 仅目录 + 保留 skills 工具 省 39% 提示,手仍能按需加载技能
类别白名单 留空 消掉"选哪份名单"这个决定本身
升级维护 升级后执行 reapply_patch.sh --check 把"静默失效"变为"一条命令自检"

9.4.2 融合后的决策空间坍缩

融合把 2 × 5 = 10 种组合坍缩为一个二值问题:

要不要让"本地手"使用仅目录模式?

(local_exec.sh 已默认开启,--full-menu 可临时关闭)

选择 后果
要 手的提示 −39%;技能职能全保留;零类别误伤;零剪枝
不要 一切照旧;补丁保持惰性;无任何副作用
主会话 始终 保持完整描述,不受该选择影响

9.4.3 消融验证表

原劣势 是否被消融 消融机制
选择一①:update 会 stash ✅ 降级为无损 惰性补丁 + 固化 diff + 重打脚本
选择一②:上游冲突 ⚠️ 部分(预检 + 手工 11 行) git apply --check
选择二:误伤关键类别 ✅ 消除 不挑类别,整表降级
选择二:决策成本高 ✅ 消除 无需选类别
选择二:收益上限 ✅ 反而提高 6.5 s > ④ 的 6.3 s
选择二:能力损失 ✅ 无 名字 100% 保留、disabled=0、工具全可用

结论 :融合方案不仅叠加了两者的优势,而且收益高于原有任何单一选项 。

这在决策分析中是一个强信号:当"融合"严格优于所有"择一"选项时,
通常说明原始选项集合本身建立在错误的维度的上。

9.5 深层逻辑提炼(本报告的理论产出)

本节把上述五个递进中所隐含的规律抽象为五条可迁移的元规律。

M1 成本引力在调用方

表述 :在"编排器 + 推理服务 + 模型"这类三层架构中,

决定端到端成本的主要变量不是被调用方的参数,而是调用方每轮发送的固定载荷。

证据链:

  • 参数旋钮的可得收益趋近于零(6 项候选全部剔除)
  • 固定载荷 36,109 tok ≈ 21.1 s/轮,占单轮成本的主体
  • 收窄工具集(调用方侧变更)使提示降低 64%,远大于任何参数调优

可迁移形式 :面对"某组件很慢"的报障,先问

"每一轮有多少字节是固定重发的?"而不是"该组件的参数是否最优?"

M2 粒度错配制造伪两难

表述 :当决策者面对"收益与代价必须权衡"的两难时,

应首先检验该权衡是否由实现粒度的选择造成 。

若粒度可选,则两难可能是人为的。

证据链:

  • 类别级降级 → 四份名单构成"收益 vs 误伤"曲线
  • 进程级降级 → 曲线消失,且取得更高收益
  • 误伤的根源:类别内部不同质 (productivity 同时含 docx 与 airtable)

可迁移形式 :遇到"鱼与熊掌"式取舍时,追问

"这个取舍的单位是什么?能否换一个单位重新表述?"

M3 可发现性 / 可加载性 / 可用性三分

表述 :"能力损失"不是单一维度。"模型不知道"与"模型不能做"是两种不同的失效 ,

成本与后果都不同。

证据链:

  • 移除技能工具 → 三层全失(_skills_prompt 返回空)
  • 降级为仅目录 → 仅丢描述,名字、加载、执行全保留
  • 实测 disabled = 0、skills_list 可见数不变、skill_view 可用

可迁移形式 :设计削减方案时,先问

"我要削掉的是'它被想起的概率',还是'它被调用的能力'?"

M4 无损劣化优于有损优化

表述 :在变更管理中,"最坏情况是退回现状"的变更 ,

在风险性质上优于"最坏情况是失去能力"的优化------即使后者的期望收益更高。

证据链:

  • 惰性补丁:未启用时行为与变更前一致(实测返回 ∅)
  • 补丁在验证阶段被发现存在缺陷,但因处于惰性状态从未对使用者产生实际影响
  • 三级回滚均为一命令

可迁移形式 :设计变更时强制回答

"如果这个变更失效(被覆盖、忘记维护、上游冲突),系统会怎样?

是退回现状,还是带着半启用状态运行?"

M5 口径决定结论

表述 :在效能研究中,若测量口径未受控,噪声会生成与事实相反的结论 ,

且这类错误不会自我暴露。

证据链:

  • 同一配置的墙钟序列:17 / 20 / 32 / 61 s(3.6 倍差异)
  • 若据此下结论,会得出"配置 B 优于配置 A"的错误判断
  • 改用 in= 后,同日同配置的数值完全确定

可迁移形式 :在任何对比实验前,先定义

"哪个量是被测对象本身决定的(确定性),哪个量会被环境调制(随机性)? "

后者不得作为结论依据。

9.6 五条元规律之间的关系

这五条并非并列,而存在依赖结构:

复制代码
M5 口径决定结论
      ↓(前提:只有可信的口径才能暴露真实成本结构)
M1 成本引力在调用方
      ↓(发现成本在提示而非模型)
M3 三层次三分
      ↓(区分"削减成本"与"损失能力")
M2 粒度错配制造伪两难
      ↓(识别权衡是人为的)
M4 无损劣化优于有损优化
      (在可行的最优方案上施加风险管理)

解释 :M5 是前提 (没有可信口径,后续全部失效);

M1 是发现 (把注意力引到正确的对象);

M3 是分辨 (区分削减的不同后果);

M2 是重构 (找到更优的决策空间);

M4 是落地(在新方案上管理风险)。

9.7 本章小结

结论 内容
选择一的裁定 留下补丁(它是能力开关,不是省时手段)
选择二的本质 五个选项同处一条人为的权衡曲线
融合结果 决策空间由 2×5 坍缩为 1 个二值问题
融合的异常性质 严格优于所有单一选项(收益更高、代价为零)
该异常的含义 原始选项集合建立在错误的维度上
五条元规律 成本引力在调用方 / 粒度错配制造伪两难 / 三层次三分 / 无损劣化优于有损优化 / 口径决定结论
元规律的依赖结构 M5 → M1 → M3 → M2 → M4

第十章 失败与自我纠错记录

本章记录研究过程中的 9 处错误 。本报告主张:

在效能优化类研究中,纠错记录的密度是可靠性的直接指标。

理由是结构性的:这类研究的结论由测量驱动,

而测量极易被单位混淆 、非受控并发 、平台默认值 与工具版本漂移 污染。

一名研究者的结论若从未被推翻过,通常不是因为他正确,

而是因为他没有做足以暴露错误的检验。

10.1 错误清单总览

# 错误 性质 发现机制 是否影响过使用者
1 把两个迁移包当作"纯负担" 判断错误(来源≠价值) 逐技能清单核对 否(未实施)
2 推荐"最小工具集"为第一杠杆 方向性错误 使用者质疑 + 源码核实 否(未实施)
3 降级收益报 3.1 s(实为 3.4 s) 数值错误(早期快照) 全量 prompt-size --json 重算 否(低估,偏保守)
4 demote_savings.py 单位错误 计算错误 人工复核折算公式 否(已修正重算)
5 自建补丁的 config 未透传 代码缺陷 隔离验证脚本报 FAIL 否(惰性状态)
6 用墙钟对比性能 口径错误 同配置出现 3.6 倍自相矛盾 否(结论被推翻)
7 把"服务已挂"误判为"配置错误" 归因错误 直接探测端口连通性 否(已澄清)
8 把"输出为空"误判为"视觉缺失" 归因错误 提高 max_tokens 后复测 否(已修正)
9 未估算容量即试 128k,打挂服务 破坏性试错 现象本身即证据 是(服务短暂中断)

关于"是否影响过使用者"这一列 :9 项中有 8 项未对使用者产生实际影响 ,

其中 3 项是因为变更处于惰性状态 (错误被隔离在未启用的代码路径中),

5 项是因为错误被在实施前发现。第 9 项是唯一造成实际影响的错误。

这一统计本身是本报告方法论的成果 :

惰性变更(M4)与隔离验证(2.4.4 节)两项纪律,直接阻断了 3 项错误的影响路径。

10.2 逐项详述

错误 1:把两个迁移包当作"纯负担"

内容 :在识别出技能索引占系统提示 60% 之后,研究者的第一反应是

"砍掉 scientific-skills 与 scienceclaw-migrated 两个包",理由是它们是"批量迁移来的"。

错误性质 :把来源属性 误当作价值属性。

发现机制 :使用者要求"详细分析解释原因,说清楚目的、作用、理由、根据、影响后再决定",

迫使研究者逐项核对两个包内的技能清单。核对结果推翻了原判断:

包内关键技能 价值
uspto-database 专利检索------IP 档案的立身之本
crossref-search、semantic-scholar 文献核验(使用者的既定习惯)
docx、pdf、xlsx 交付格式(使用者的硬要求)
nano-banana-pro AI 生图通道
legal-analysis、regulatory-drafting、iso-13485-certification 法务与法规
rdkit、chembl-database、pubchem-database 化学/配方
scientific-diagram-generation、data-visualization-expert 顶刊级配图

修正 :确立判据------按内容相关性切,不按来源切 。

(该判据后被写入 04_瓶颈解剖 的 4.2.4 节与组合卡。)

教训 :"这是导入的/生成的/遗留的"是溯源信息,不是价值判断。

在削减决策中,必须逐项核对内容,而不是依据来源标签批量处理。

错误 2:推荐"最小工具集"为本地执行的第一杠杆(方向性错误)

内容 :研究者测得 -t terminal,file 使提示从 32,216 降至 11,632 tok(−64%)、

延迟从 31.1 s 降至 12.2 s(−61%)后,把它确定为"本地执行优化的第一杠杆",

并写入交付方案与技能文档。

错误性质 :方向性错误------把"速度"当作唯一目标函数,忽略了优化对象的角色定义。

发现机制 :使用者直接质疑:

"手不是要做机械手,而是具有职能的手,不要通过剪枝技能来优化。"

研究者随即做源码核实,确认该建议的后果:

python 复制代码
def _skills_prompt(agent: Any) -> str:
    """Skills index (empty without skills tools)."""
    if not any(name in agent.valid_tool_names
               for name in ['skills_list', 'skill_view', 'skill_manage']):
        return ""

移除技能工具 = 整个技能索引返回空 = 执行者无法看到或加载任何技能。

此外还同时失去了 web、vision、patch、memory、todo、delegate 等能力。

修正:

  1. 把该建议从"第一杠杆"下调为不推荐;
  2. 在 06_混合路由策略 文档顶部加勘误块;
  3. 把执行者的默认工具集从 terminal,file 改回 terminal,file,skills;
  4. 在技能文档中自我纠正(该技能先前已被研究者写入错误建议);
  5. 建立替代方案(第八章的降级路线)。

教训 :优化前必须先确定目标函数,而不是先找最大的数字。

"提示减少 64%" 是一个数字;"执行者能否完成工作"才是一个目标。

本例中,前者与后者冲突,而研究者选择了前者。

这是本研究中最严重的一处错误 ,因为它是唯一一处与外发交付物绑定 的错误------

它会通过技能文档影响未来的会话。所幸使用者在实施前拦截。

错误 3:降级收益报 3.1 s(实际 3.4 s)

内容 :早期基于 .skills_prompt_snapshot.json 的估算给出"整砍两个包省 3.1 s/轮"。

错误性质 :数值错误------源自估算口径与实测口径不一致 (快照推算 vs prompt-size --json 实测)。

发现机制 :改用 hermes prompt-size --json 获取逐技能精确成本后重算,

得到两个包合计 5,863 tok(而非 5,340 tok),实测值 3.4 s/轮。

修正:报告统一采用实测口径,并在文档中显式标注"更正:我上次说 3.1 s 是早期快照估算(偏低)"。

教训 :估算与实测必须显式区分 。本报告为此建立 L1/L2/L3 三级可信度标注(2.1 节),

其中"快照推算"属 L2,"实测"属 L1。

错误 4:demote_savings.py 的单位错误

内容:在对比"剪枝路线"与"降级路线"的收益时,脚本中写了:

python 复制代码
print(f"裁剪工具集省 {(32216-11632)/CPT/PRE:.1f} s/轮")

其中 CPT = 4.0(设计为"字节/字符 → token"的换算系数),

但 32,216 与 11,632 本身就是 in= 字段的 token 值 (已经过换算),

再次除以 4 导致结果被低估为 3.0 s ,而正确值为 12.0 s。

错误性质 :单位/量纲错误------对"已是目标量纲的数值"重复套用了换算。

发现机制 :人工复核折算公式时发现量纲不一致;

随后在报告中显式记录并修正:

复制代码
对照:-t terminal,file 省 12.0 s/轮(单位已是 tok,不再 /4)

影响分析 :该错误使"降级路线"看起来更有吸引力(因为把对照组的收益算小了),

属于有利于自己结论的方向性偏差。若未发现,会导致方案选择被误导。

修正:修正脚本、重算、并在交付文档中说明该 bug。

教训 :单位错误是本领域最高频、最隐蔽、且最可能与研究者动机一致的一类错误。

必须对每一个除法/换算标注量纲。本报告建议:

在脚本中把变量名包含量纲(如 tokens_fixed、bytes_index),并在打印时标注单位。

错误 5:自建补丁的 config 参数未透传

内容:研究者为 Hermes 编写的补丁初版如下:

python 复制代码
    def compact_skill_categories(self) -> frozenset[str]:
        ...
        try:
            from hermes_cli.config import load_config_readonly
            _extra = (load_config_readonly().get("skills") or {}).get("demote_categories") or []

它忽略了调用方传入的 config 参数 ,总是读取全局配置。

而调用链为:

python 复制代码
def coding_compact_skill_categories(*, platform=None, cwd=None, config=None) -> frozenset[str]:
    return resolve_runtime_mode(platform=platform, cwd=cwd, config=config).compact_skill_categories()

即:签名声明支持传入配置,但实现忽略它。

错误性质 :代码缺陷------"签名与行为不一致"。

发现机制 :隔离验证脚本报 FAIL。验证脚本以显式配置调用:

python 复制代码
got = coding_compact_skill_categories(platform="cli", cwd=os.getcwd(),
                                      config={"skills": {"demote_categories": ["gaming", "media"]}})
# 期望 ['gaming','media'],实际返回 []

影响分析 :生产路径当时"恰好"能工作(因为 system_prompt.py 调用时不传 config,

总是走全局读取),所以这是一个不会在日常使用中暴露的缺陷 ------

它只在被显式传参时(例如测试、多档案场景)才显现。

修正:

python 复制代码
    def compact_skill_categories(self, config: Optional[dict[str, Any]] = None) -> frozenset[str]:
        ...
            _cfg = config if config is not None else load_config_readonly()

并将调用方改为 .compact_skill_categories(config=config)。

教训:

  1. "生产路径能跑"不等于"实现正确"。 一个只在非默认参数下暴露的缺陷,
    会长期潜伏并在未来的重构中突然爆发。
  2. 隔离验证(不碰实时配置、用显式参数)不仅更安全,而且能发现实时验证发现不了的问题。
    若当时选择"改实时配置来测",该缺陷将完全不可见。

错误 6:用墙钟作为性能对比口径

内容:研究早期以墙钟(wall-clock)对比不同配置,得到:

实验 配置 墙钟
第 2 次 -t terminal,file 17 s
第 5 次 同配置(同档案/同模型/同工单) 61 s

同一配置出现 3.6 倍差异。

错误性质 :口径错误------在未控制并发的环境中使用受并发调制的量。

发现机制 :自相矛盾本身被发现 。研究者注意到"同配置两次结果差 3.6 倍",

无法用任何合理解释覆盖,遂转向深挖。

根因 :OLLAMA_NUM_PARALLEL=1 单并发队列。当同时存在其它本地请求

(本会话自身的辅助通道调用构成持续干扰源)时,延迟变为"服务时间 + 排队时间"。

修正 :改用 agent.log 的 in=(确定性)为主口径,latency= 仅在无并发批次内比较。

该纪律成为本报告第二章的核心内容,并沉淀为元规律 M5。

教训 :对比实验前必须定义"哪个量是被测对象决定的"。

本例中,in= 由输入决定(确定),latency 由系统瞬时状态决定(随机)。

用随机量做对比,等于用噪声做证据。

错误 7:把"服务已挂"误判为"配置错误"

内容 :研究者把视觉辅助通道切换到本地模型后,调用 vision_analyze 返回:

复制代码
Error analyzing image: Connection error.
openai.APIConnectionError: Connection error.

研究者当时的第一反应是"我的配置改动破坏了视觉功能",并开始排查配置。

错误性质 :归因错误------把依赖服务不可用 误判为自身配置错误。

发现机制:直接探测服务连通性:

bash 复制代码
curl --noproxy "*" -s http://127.0.0.1:11434/v1/models -o /dev/null -w "http=%{http_code}"
# → http=000
# 报错:URLError [WinError 10061] 由于目标计算机积极拒绝,无法连接

Ollama 服务当时已经退出。 配置本身完全正确------服务恢复后同一次调用立即成功

(并返回了正确的图像描述)。

修正:

  1. 澄清该事件与配置无关;
  2. 为关键辅助通道增加远程兜底链(fallback_chain);
  3. 在技能文档中记录该错误的正确归因 ,以及一条判断规则:
    "症状指向某功能失败时,先探测其依赖服务的连通性,再怀疑自己的配置。"

教训 :在"自己刚改了配置"与"观察到失败"相邻发生时,存在极强的因果误判倾向。

必须用独立探测打破这一倾向。

错误 8:把"输出为空"误判为"视觉能力缺失"

内容 :视觉能力测试在 max_tokens=60 下返回空字符串 content: '',

研究者据此一度认为"-opt 派生模型丢失了视觉能力"。

错误性质 :归因错误------把预算不足 误判为能力缺失。

发现机制:提高预算复测:

模型 max_tokens=60 max_tokens=600
qwen3.8:latest finish=stop,'The shape is red.' 同
qwen3.8-opt-64k finish=length,'' 'The shape is red.'
qwen3.8-hermes finish=stop,'The shape is red.' 同

根因 :思考型模型先消耗 token 预算于推理,finish_reason=length 时

content 尚为空。

修正 :把"给足 max_tokens"写入能力测试的标准流程;

本报告的 3.3.2 节明确记录该发现。

教训 :"输出为空"是一个多义症状 (能力缺失 / 预算不足 / 模板错误 / 停止符误触发)。

诊断为"能力缺失"之前,必须先排除预算与模板因素。

错误 9:未做容量估算即尝试 128k(唯一造成实际影响的错误)

内容 :研究者为获得"更大上下文能力",创建 qwen3.8-hermes(num_ctx 131072)并加载。

错误性质 :破坏性试错------在提供服务的过程中进行未经容量估算的资源扩张。

后果 :推理进程崩溃(RemoteDisconnected),Ollama 服务端自我重启;

期间本地推理不可用,且后续排查叠加了进程污染问题。

发现机制 :现象本身即为证据,但根因需事后从日志恢复:

复制代码
common_memory_breakdown_print:
 | CUDA0 | 24435 = 22401 + (18663 = 15339 + 2924 + 400) + (-16629)

[mtmd] estimated worst-case memory usage of mmproj is 1161.02 MiB

修正:

  1. 重建为 num_ctx 65536(安全上限);
  2. 建立扩容前的容量估算流程 (见 3.4.4 节):
    权重 + KV/token × 目标上下文 + mmproj 最坏值 ≤ 可用显存;
  3. 在报告中把 64k 标注为硬上限,并明确警告"不要建 128k 模型"。

教训 :"先估后试"在单卡推理中不是优化建议,而是安全要求。

一次未估算的扩张尝试可以打挂一个正在提供服务的进程。

10.3 错误的分布规律

对 9 项错误按类型归类:

类型 数量 编号
归因错误 3 7, 8, 9(9 兼为破坏性)
数值 / 单位错误 2 3, 4
判断 / 方向性错误 2 1, 2
口径错误 1 6
代码缺陷 1 5

观察:

  • 归因错误最多(3 项) ,且全部发生在"事件相邻"的场景
    (刚改配置就失败、测试没输出就下结论、扩张后就崩)。
  • 方向性错误最少但最严重 ------一旦与外发交付物绑定,
    会通过技能文档污染未来的会话。

10.4 由错误导出的实用检查清单

本报告建议在任何类似的效能优化研究中,强制回答以下 8 个问题:

# 检查项 对应错误
1 我优化的是数字 还是目标函数?两者是否冲突? 2
2 这个"无用/低价值"的判断,是基于来源 还是基于逐项内容核对? 1
3 这个量是被测对象决定 的,还是环境调制的? 6
4 这个数值的量纲是什么?有没有重复换算? 3, 4
5 "生产路径能跑"是否掩盖了签名与行为的不一致? 5
6 我是否刚改了配置?失败能否用独立的连通性/健康探测复现? 7
7 "输出为空"是能力问题,还是预算/模板问题? 8
8 这个资源扩张的容量估算做了吗?失败会打挂服务吗? 9

10.5 本章小结

结论 内容
记录的错误数 9 项
唯一造成实际影响的错误 错误 9(未估容量即试 128k)
错误被隔离的原因 惰性变更(3 项)、实施前发现(5 项)
最高频错误类型 归因错误(3 项),均源于"事件相邻"的因果误判
最严重错误类型 方向性错误(1 项,与外发交付物绑定)
最有价值的发现路径 使用者的质疑(直接拦截了错误 2)
方法论主张 纠错密度是可靠性的直接指标

第十一章 局限性、未验证项与待核清单

任何实证研究都有边界。本章明确列出本报告的适用边界 、

证据缺口 与待核清单,以便读者正确使用结论,并为后续工作提供起点。

11.1 适用边界

11.1.1 硬件边界

维度 本研究的值 结论的敏感性
GPU RTX 5090 Laptop,24,463 MiB 高------上下文上限(64k)与并发能力均由此决定
驱动模式 WDDM 高------可用显存随显示负载浮动,TCC 模式下边界会不同
系统内存 31.4 GiB 中------影响 CPU 回退与堆碎片行为
CPU Core Ultra 9 275HX(24 核) 低------仅影响纯 CPU 路径

明确说明 :本报告所有"延迟类"与"容量类"结论(如"64k 是硬上限")

不可直接外推到其他显存规格的机器。24 GB 与 48 GB 的结论会不同。

11.1.2 与硬件无关的结论(可跨平台复现)

以下结论不依赖具体硬件,具有更强的可迁移性:

结论 为何与硬件无关
固定载荷为 36,109 tok(本档案配置下) 由提示内容决定,与执行硬件无关
技能索引占系统提示 60% 同上
_skills_prompt 在无技能工具时返回空 源码逻辑,平台无关
"降级保留名字、不保留描述" 源码逻辑,平台无关
移除技能工具的后果清单 源码逻辑,平台无关
远程:本地 token 比 66:1 由任务分工决定,与执行硬件无关
五条元规律(M1--M5) 方法学层面,与实现无关

11.1.3 软件版本边界

组件 本研究版本 版本敏感性
Ollama 0.33.2 高------MTP 投机解码、桌面版覆盖注册表等行为均可能随版本变化
Hermes v0.21.1(upstream ad03f20d) 中------本研究的补丁绑定于特定文件版本
qwen3.8 27.3B Q4_K_M 高------换模型则吞吐与容量结论全部改变

重要提示 :本研究已发现一处版本漂移导致旧结论失效 的实例

("Ollama 不支持投机解码"在 0.32 成立、在 0.33.2 已不成立)。

因此读者在引用本报告结论前,应先核对上述三个版本。

11.2 证据缺口(明确标注)

以下事项本研究未能 取得证据。它们不是"可以不谈"的细节,

而是会影响结论适用范围的空白。

缺口 1:技能的历史使用率

缺口内容:本研究无法给出"这 566 个技能中,哪些在历史上真正被加载过"的统计。

原因:两个数据源均不可得:

尝试 结果
挖掘 state.db 的 messages 表搜索 skill_view( 调用 命令被审批机制拦截(超时未获同意),且提示"不得重试或换命令绕过"
读取 curator 的用量遥测 同类命令同样被拦截

影响 :本报告对"哪些技能可以降级"的建议基于内容相关性判断,不含使用频次证据 。

理论上存在这样的可能:某个被判为"无关"的技能实际高频使用,反之亦然。

缓解 :本研究选择了不依赖使用频次 的方案(整表降级,而非挑类别),

因此该缺口未影响最终方案的成立性 ------这是"选择对证据要求更低的方案"的一个正面案例。

若未来需要"选择性启用"某些技能,则必须先补上该缺口。

后续获取路径 (待核):Hermes 的 curator 提供 hermes curator usage 与

skills/.usage.json(含 use_count / view_count / last_activity_at),

应在获得授权后由使用者自行运行。

缺口 2:远程 provider 的实际计费

缺口内容:本报告只给出 token 消耗比(66:1),未给出货币成本对比。

原因 :远程 provider(blsc)的单价未公开,hermes insights 亦报告

Cost: Unknown --- 5 session(s) (no pricing data)。

影响:无法量化"把负载移到本地"的经济收益,只能给出 token 量级证据。

后续获取路径 (待核):查阅 provider 的计费文档;或在 hermes 的

模型价格表中补充该 provider 的定价条目。

缺口 3:KEEP_ALIVE 值的来源未完全确证

缺口内容 :本研究确认服务端固定呈现 KEEP_ALIVE:2m0s,

并确认 CONTEXT_LENGTH:65536 来自桌面版 db.sqlite 的 settings 表;

但**2m 这一具体数值的来源未在数据库中找到对应列**。

当前认识 :推测由桌面版以硬编码或内部默认方式注入。【推断】

影响:若该值可经界面配置,则"保温脚本"这一缓解措施可被更简单的配置替代。

后续获取路径 (待核):检查 Ollama 桌面版的设置界面是否存在该选项;

或审计其二进制/资源文件。

缺口 4:未验证"技能索引"在超长会话中的压缩行为

缺口内容 :本研究验证了单轮的前缀缓存行为,但未测量 在会话历史增长到

接近上下文上限时,压缩(compression)对技能索引的处置方式。

已有认识 (L1,来自源码):

Hermes 对 <512K 上下文的模型施加上限 75% 的压缩阈值下限:

复制代码
(65,536 − 4,096) × 0.75 = 46,080 tok > 36,109 tok(固定载荷)

因此在 64k 上下文下不会因固定载荷而触发过早压缩。但接近 46k 时的实际行为未实测。

后续获取路径 (待核):构造长会话,观测 compression_count 与压缩后的提示构成。

缺口 5:未做"降级后能力回归测试"的完整矩阵

缺口内容 :本研究验证了降级后技能能力 保留(skills_list 成功调用、

disabled=0、名字 100% 保留),但未逐一验证 每个被降级技能仍可正常 skill_view 加载。

现有证据 :机制上,降级只影响 _render_skills_index 的渲染分支,

不触碰 skills.disabled,因此 skill_view 的禁用闸门(_is_skill_disabled)不会拦截。

该推理属 L2(机制推断),非 L1 实测。

后续获取路径 (待核):抽样若干个被降级技能,逐一执行 skill_view(name) 验证。

缺口 6:单次测量,无重复实验的统计

缺口内容 :本报告的多数性能数值来自单次测量,未做重复实验与方差分析。

影响 :无法给出置信区间。部分数值(如预填充速率)可能随设备温度、

功耗状态(笔记本 TGP 145W 限制)而变化。

缓解 :本研究对关键结论采用了多源交叉验证 (nvidia-smi / server.log / agent.log),

并以两次独立运行的一致性 作为可靠性证据(例如 64k 占用两次测得

20,472 MiB 与 20,480 MiB,差 8 MiB)。

11.3 待核清单(行动项)

# 待核项 方法 优先级
1 技能历史使用率 hermes curator usage(需授权) 中
2 被降级技能仍可 skill_view 抽样 5--10 个被降级技能逐一加载 高
3 远程 provider 单价 查计费文档 + 补模型价格表 低
4 KEEP_ALIVE=2m 的可配置性 检查桌面版设置界面 中
5 长会话下的压缩行为 构造接近阈值的会话并观测 中
6 性能数值的重复性 每个关键指标重复 3 次,报告均值与极差 中
7 补丁在 hermes update 后的实际行为 在下一次升级时观测 git stash 并以 reapply_patch.sh 恢复 高(需等待升级事件)
8 多档案下的降级作用域隔离 在主会话与执行者之间对比 prompt-size 中

11.4 方法学局限

局限 说明 缓解
单案例研究 全部结论来自单一档案(intellectual-property)与单一硬件 明确标注诊断性而非统计性
研究者即实施者 研究者同时承担测量与变更,存在动机性偏差风险 通过"隔离验证 + 使用者复核 + 错误记录"降低;但仍不可完全排除
未做对照实验的随机化 变更按序实施,非同时对照 关键对比均采用"同档案/同模型/同工单"控制变量
依赖源码阅读的部分结论 少数结论基于源码推理而非运行观测 已逐条标注 L2/L3

11.5 一个值得强调的正面局限

本研究的最大方法学优势 在于:存在一位会质疑的使用者。

回顾 9 项错误,错误 2(方向性、已绑定交付物)是被使用者当场拦截的 ,

而它恰恰是危害最大的那一项------其余错误或未实施、或被自身检验发现。

这一事实对 AI 辅助工程实践有直接含义 :

人类复核不是流程的冗余环节,而是特定类型错误的唯一发现通道。

本研究能用源码证明错误 2 的危害,但是在使用者指出方向之后才去证明的。

因此本报告主张:

对本类研究,应把"人类对方向的质疑"设计为流程中的显式关口(gate),
而不是把它当作"如果有空就做"的附加步骤。

具体做法是:任何将被写入交付物或长期知识库的建议,必须先说明
"它优化的是哪个目标函数,以及是否牺牲了其他目标"。

这正是本报告第一章所述"问题陈述三次重述"的价值所在:

每一次重述都由一次质疑触发,而每一次重述都实质性地改善了方案。

11.6 本章小结

类别 内容
与硬件无关的结论 7 项(固定载荷、索引占比、源码机制、成本比、元规律)
证据缺口 6 项(使用率、计费、KEEP_ALIVE 来源、长会话压缩、回归矩阵、重复测量)
高优先级待核 2 项(降级技能仍可加载的抽样验证;升级后补丁行为)
最大方法学优势 有会质疑的使用者;人类复核是特定错误类型的唯一发现通道
核心建议 把"人类对方向的质疑"设计为显式关口;任何写入交付物的建议必须先声明其目标函数

第十二章 结论与后续工作

12.1 六个研究问题的回答

RQ1:本机平台上,本地模型的真实性能边界是什么?

回答:

维度 边界值 约束性质
预填充吞吐 1,713 tok/s(实测峰值,6,686 token 提示) 硬件(GPU 算力)
生成吞吐 54--68 tok/s 硬件 + 模型规模(27.3B Q4_K_M)
上下文上限 65,536(131,072 导致进程崩溃) 显存容量(硬约束)
KV 成本 ~4.0 KB/token 架构(Qwen3.5 混合注意力)
冷加载 12.36--12.70 s 磁盘 I/O + 显存分配
并发 1 (-np 1,串行队列) 配置 + 显存
能力 工具调用 ✅ / 视觉 ✅ / 思考 ✅(开启更优) 模型能力

关键区分 :模型能力 上限(原生 262,144 上下文、视觉、工具)与

部署容量 上限(65,536)相差 4 倍。规划必须以部署容量为准。

RQ2:Hermes 每轮固定载荷的成本结构如何?瓶颈在哪一层?

回答 :固定载荷 33,600--36,109 token (两法交叉验证),折合本机 21.1 秒预填充。

组成 token 占比
技能索引 ~14,086 39%
工具 schema ~10,075 28%
身份/指令(含人格文件) ~4,664 13%
记忆 + 用户画像 ~1,542 4%
其余 ~5,742 16%

瓶颈在"调用方发送的固定文本",其中技能索引是最大单项。

更深一层的发现是:索引的 81% 消耗在四个批量迁移包上(443 技能 / 10,545 tok),

而使用者自建技能仅占 0.8%。

RQ3:在保持能力完整的前提下,有哪些机制可以降低每轮成本?

回答:本研究识别并验证了四条机制:

机制 收益 能力影响 可信度
整表降级为仅目录 −39% 提示(26,087 → 15,907 tok) 无(名字 100%、工具全可用) L1
保持模型驻留 免 12.7 s 冷加载 无 L1
保持前缀缓存 第二轮延迟 ÷55(55.1 → 1.0 s) 无 L1
收窄工具集(不推荐单独使用) −64% 提示 ❌ 技能能力全失 L1

核心结论 :"降级"与"裁剪"在成本上效果相近,在能力后果上截然不同。

降级拿到裁剪收益的 70%,代价为零能力损失。

RQ4:远程与本地模型的正确分工是什么?有哪些反直觉的正确结论?

回答 :三层路由(含被普遍忽略的 Tier-0):

层 适用 判据
Tier-0 无模型 可完全指定的确定性任务 能写成一条命令吗?
Tier-1 本地手 需语言理解、不需权衡、量大/私密 答案唯一且可自检吗?
Tier-2 远程大脑 规划、设计、歧义、高风险判断 需要权衡或多步设计吗?

三条反直觉的正确结论:

# 结论 直觉为何出错
1 不要把 delegation.provider 指向本地 配置项"存在且可用"≠"该配置最优"------子智能体继承完整工具集(32,216 tok)
2 不要关闭 thinking 以提速 关闭后 token 更多、更慢(4.92 s vs 3.98 s),因 MTP 使思考 token 顺带产出
3 不要扇出到本地 NUM_PARALLEL=1 → 扇出只是排队(12.2 → 55.1 s),不产生并行度

成本证据 :远程与本地 token 消耗比 66 : 1 ;远程单轮 in= 达 20 万--29 万。

RQ5:削减提示成本的"粒度"与"作用域"如何选择?

回答:这是本报告最重要的方法学结论。

发现 :在"按类别降级"的粒度下,四份候选名单构成一条

"收益(2.6 / 3.1 / 4.3 / 6.3 s)vs 误伤(无 / 无 / 有 / 严重)"的权衡曲线。

关键洞察 :该权衡源于实现粒度,不是问题固有。

错配的环节 后果
匹配单位 = 类别 类别内部不同质(productivity 同时含 docx 与 airtable)→ 必然误伤
作用域 = 档案级 无法让主会话与本地手取不同值

解法(第三条路径) :按进程定粒度 ------不挑类别,整表降级;

用 HERMES_SKILLS_DEMOTE_ALL=1 限定作用域到本地执行者进程。

结果 数值
收益 6.5 s/轮(高于最激进的类别方案 6.3 s)
误伤 零
能力 名字 100% 保留、skills_list/skill_view 全可用、disabled=0
端到端 26,087 → 15,907 tok(−39%)
决策成本 不需要挑类别

RQ6:这类研究中哪些测量纪律是必需的?哪些错误模式是高频的?

回答:

必需的测量纪律(三条):

  1. 口径分层 :区分"被测对象决定的量"(in=,确定性)与"环境调制的量"(latency,随机)。
    后者不得作为结论依据。
  2. 多源交叉验证 :至少两个独立数据源(本研究用 nvidia-smi + server.log + agent.log)。
  3. 三级可信度标注:L1 实测 / L2 推算 / L3 推断,逐条标注。

高频错误模式(按本研究 9 项错误的分布):

错误类型 占比 典型触发场景
归因错误 3/9 事件相邻(刚改配置就失败、没输出就下结论、扩张后就崩)
数值/单位错误 2/9 重复换算、估算与实测混用
判断/方向性错误 2/9 把数字当目标函数、按来源而非内容判断价值
口径错误 1/9 用随机量做对比
代码缺陷 1/9 签名与行为不一致(仅非默认参数下暴露)

12.2 核心结论(一段话概括)

在这套"编排器 + 本地推理 + 27B 模型"的架构中,决定使用者体验的主要变量不是模型的参数,
而是调用方每轮发送的固定文本宽度(36,109 token ≈ 21.1 秒)。削减它存在两条路线:
裁剪能力(快但静默失去职能)与降级粒度(同样快且能力无损)。
后者的实现关键在于选择正确的"粒度"与"作用域"------把决策单位从"类别"改为"进程",
就同时取得了最高收益与零能力损失。此外,驻留与缓存两条次要战线的收益量级与提示削减相当
(各约 12--21 秒/轮),但它们由环境默认值与使用习惯决定,容易被忽略。

12.3 本研究的可迁移产出

12.3.1 五条元规律

编号 元规律 一句话
M1 成本引力在调用方 先问"每轮有多少字节是固定重发的",而不是"组件参数是否最优"
M2 粒度错配制造伪两难 遇到"鱼与熊掌",先问"这个取舍的单位是什么?能否换单位重述?"
M3 可发现性/可加载性/可用性三分 先问"我要削掉的是'被想起的概率'还是'被调用的能力'?"
M4 无损劣化优于有损优化 先问"这个变更失效时,是退回现状,还是带着半启用状态运行?"
M5 口径决定结论 先定"哪个量是被测对象决定的,哪个是被环境调制的"

依赖结构:M5(前提)→ M1(发现)→ M3(分辨)→ M2(重构)→ M4(落地)

12.3.2 可复用的工程资产

资产 用途
hermes_bench.py 归因"固定载荷 → 预填充成本"的标准测量
verify.sh 本地推理栈健康自检(6 项检查)
keepwarm.ps1 模型驻留保温(0.004 s/次)
local_exec.sh 本地执行者封装(串行锁 + 审计 + 工单协议)
verify_patch.py 补丁的隔离验证(不触碰实时配置)
reapply_patch.sh 升级后重打补丁
demote_savings.py 索引成本的精确测算
skills-demote-categories.patch 固化的源码 diff(可重放)

12.3.3 知识库修正

本研究修正了两处已写入技能库的错误或过时结论:

技能 原结论 修正
ollama-tuning "Ollama 不支持投机解码(0.32)" 0.33.2 原生支持 MTP,实测接受率 0.52
hermes-local-providers (研究者写入的)"最小工具集是本地第一杠杆" 下调并修正为"绝不剪技能工具",并补充降级路线

12.4 后续工作

按优先级排列:

优先级高(应立即执行)

# 工作 理由
1 抽样验证被降级技能仍可 skill_view 加载 填补缺口 5,把 L2 推断升为 L1 实测
2 在下一次 hermes update 时观测并验证 reapply_patch.sh 唯一未经验证的关键运维流程
3 把"整表降级"在本机正式启用(local_exec.sh 已默认) 收益已量化,风险已控制

优先级中(可在有资源时执行)

# 工作 理由
4 获取技能历史使用率(hermes curator usage) 填补缺口 1;为未来的"选择性启用"提供依据
5 关键性能指标做 3 次重复测量并报告极差 填补缺口 6
6 观测长会话下的压缩行为 填补缺口 4
7 检查 KEEP_ALIVE=2m 是否可经界面配置 填补缺口 3;可能简化缓解措施

优先级低(方向性探索)

# 工作 说明
8 探索 context.engine 插件机制 源码显示 context.engine 可选择 plugins/context_engine/<name>/ 插件,可能提供更规范的上下文控制路径
9 探索 register_system_prompt_section() 官方插件 API 可注入系统提示段;当前不能移除内容,但可用于补充精简索引
10 评估把"整表降级"作为上游建议反馈 当前需本地补丁;机制本身与 Hermes 的"never hidden"设计原则一致,具备上游化价值

一项明确不推荐的方向

方向 不推荐理由
建"执行者专用精简档案" 该路径的目的是"少装技能",而 -t 与整表降级已用零维护成本达到同样效果。多维护一个档案反而增加不一致风险。

12.5 结语

本研究从一个朴素的问题出发------"如何让这套组合发挥最大潜力"------

最终得到一个与最初假设相反的答案:瓶颈不在模型,而在调用方发送的内容。

这一结论的取得并非线性推导,而是经过三次问题重述 与九次自我纠错 。

其中最关键的两次转折都源于使用者的质疑:

  1. 第一次质疑("手不应是机械手")拦截了一项已绑定交付物的方向性错误;
  2. 第二次质疑("应通过动态加载而非剪枝")直接导向了本报告的核心成果。

因此在结语中值得再强调一次本研究最实用的方法学建议:

任何将被写入交付物或长期知识库的建议,必须先声明
"它优化的是哪个目标函数,以及它牺牲了什么"。

因为数字的改善与目标的达成是两件不同的事,

而前者极易伪装成后者。


附录:篇幅与文件索引

章 文件
摘要 00_摘要与关键发现.md
一 01_引言与问题陈述.md
二 02_方法论与测量口径纪律.md
三 03_实验环境与性能基线标定.md
四 04_瓶颈解剖_固定载荷成本结构.md
五 05_递进一_从参数调优到提示词经济学.md
六 06_递进二_驻留与缓存经济学.md
七 07_递进三_混合路由体系.md
八 08_递进四_动态加载与伪两难.md
九 09_递进五_决策融合与深层逻辑.md
十 10_失败与自我纠错记录.md
十一 11_局限性与待核清单.md
十二 12_结论与后续工作.md(本章)
全文 研究实验报告_全文.md(各章合并)
字数 _count.py / 字数统计.txt

附录 A 原始数据索引与复现指南

本附录的作用是让报告中的每一个数值断言都可被独立复核 。

凡正文引用的数值,其对应的原始输出文件均列于此。

A.1 数值---原始文件对照表

正文数值 所在章节 原始文件 提取方式
预填充 726 / 1,263 / 1,713 tok/s 3.2.1 01_实测报告/raw/bench_out.txt /api/generate 响应的 prompt_eval_count ÷ prompt_eval_duration
生成 65.5 / 57.5 / 68.0 / 54.2 tok/s 3.2.2 同上 eval_count ÷ eval_duration
冷加载 12.36--12.70 s 3.2.3 bench_out.txt 的 PART 7 响应的 load_duration
16.11 / 16.20 / 16.33 GiB 驻留 3.4.2 bench_out.txt 的 PART 4 /api/ps 的 size_vram
20,480 MiB / 余 3,658 MiB 3.4.2 同上 + nvidia-smi 交叉验证
128k 崩溃 3.4.4 model_setup.txt RemoteDisconnected 异常
显存分解 15,339 + 2,924 + 400 3.4.4 03_配置与脚本/verify.sh 关联的 server.log common_memory_breakdown_print
mmproj 最坏 1,161.02 MiB 3.4.4 server.log [mtmd] estimated worst-case
投机解码接受率 0.52 3.6 server.log spec common_specu: statistics
工具调用返回结构 3.3.1 bench_out.txt 的 PART 5 tool_calls 字段
视觉描述正确性 3.3.2 bench_out.txt 的 PART 6 content 字段
think 对比 3.98 / 4.92 s 3.3.3 _count.py 同类隔离测试输出 单次隔离调用
固定载荷 36,109 tok 4.1.2 01_实测报告/raw/dump_stats.txt 解析 request_dump_*.json 的 request.body
系统提示 94,254 B / 74,903 chars 4.1.1 04_实证核验/verify_output.txt hermes prompt-size
技能索引 56,345 B 4.1.1 同上 同上
工具 schema 40,300 B / 25 工具 4.1.1 同上 同上
逐类索引成本 4.2.3 hermes prompt-size --json(%LOCALAPPDATA%\Temp\psize.json) skills_breakdown[].index_line_total_bytes
迁移包占索引 81% 4.2.3 07_动态加载优化/final_decision_table_output.txt 类别聚合
自建技能占 0.8% 4.2.3 同上 同上
工具集 32,216 / 11,632 / 10,375 tok 7.2.2 <profile>/logs/agent.log 的 API call #1: in= 按会话时间戳切分
同请求 12.2 s vs 55.1 s 7.3.1 同上 latency=
串行排队日志 7.3.3 06_混合路由策略/router_test.txt [lock] 本地执行者忙,排队中
delegation 继承规则 7.4.2 tools/delegate_tool.py:557(源码) 直接引用
成本比 66:1 7.5 hermes insights --days 1 输出 按模型聚合 token
远程单轮 218k / 294k 7.5 agent.log 的 DeepSeek-V4.1-Flash 行 in=
辅助通道路由证据 7.6.2 server.log 的 POST /v1/chat/completions + agent.log 的 Auxiliary ... using ollama-launch 时间戳对齐
兜底链配置 7.7 hermes fallback list 输出 直接引用
历史 401 中断 7.7 sessions/request_dump_20260902_*.json 的 error 字段 直接引用
四份名单收益 2.6 / 3.1 / 4.3 / 6.3 s 8.4.3 07_动态加载优化/demote_savings_output.txt 隔离渲染
整表降级 13,122 B / 6.5 s 8.6.3 07_动态加载优化/patch_verify_output.txt 同上
惰性验证(返回 ∅) 8.6.4 同上 第 2 节 隔离调用
端到端 26,087 → 15,907 tok 8.6.5 e2e_demote_test.txt + agent.log in=
执行者成功调用 skills_list 8.6.5 local_exec_last.log + agent.log 返回值 2
前缀缓存 55.1 s → 1.0 s 4.5.1 / 6.4 agent.log 的连续两行 API call #1/#2 in= 与 latency=
缓存复用 23 / 6,686 4.5.1 bench_out.txt 同类重复请求 prompt_eval_count
KEEP_ALIVE 对照 6.2.2 06_递进二 关联的注册表读取 + server.log 两侧对照
db.sqlite 的 context_length=65536 6.2.2 Ollama db.sqlite 的 settings 表(只读查询) 直接查询
保温触碰 0.0057 / 0.0035 s 6.3.2 model_fix.txt 连续两次触碰的 time_total

A.2 复现步骤

A.2.1 前置条件

bash 复制代码
# 确认栈可用
curl --noproxy "*" -s http://127.0.0.1:11434/api/version      # 期望 {"version":"0.33.2"}
hermes --version                                              # 期望 v0.21.1 或更高
hermes config get skills.demote_categories                    # 期望 "Config key not set"

A.2.2 测量提示规模(与硬件无关,可跨平台复现)

bash 复制代码
hermes prompt-size                 # 人类可读
hermes prompt-size --json > p.json # 机器可读(含逐技能成本)

注意 :hermes prompt-size 没有 --toolsets 参数,

因此它无法 显示"收窄工具集"的效果------

该效果必须从 agent.log 的 in= 读取。

A.2.3 测量本地执行者的提示规模

bash 复制代码
# 记录起点行数
n0=$(wc -l < <profile>/logs/agent.log)
# 派发一条简单工单
hermes -p <profile> chat -q "运行 echo probe 并只回报输出" \
    -m qwen3.8-hermes --provider ollama-launch -t terminal,file,skills -Q --oneshot
# 读取本次的 in=
tail -n +$((n0+1)) <profile>/logs/agent.log | grep "API call #1:"

A.2.4 验证整表降级

bash 复制代码
# 完整菜单
in_full=$(... 不带 env ...)
# 仅目录
HERMES_SKILLS_DEMOTE_ALL=1 hermes -p <profile> chat -q "..." ... -t terminal,file,skills -Q --oneshot
# 对比两次的 in=,期望约 26,087 → 15,907

A.2.5 隔离验证补丁(不触碰实时配置)

bash 复制代码
SRC=<hermes-agent>
HERMES_HOME=<profile> "$SRC/venv/Scripts/python.exe" \
  "07_动态加载优化/verify_patch.py"

关键 :该脚本用显式 config= 参数 测试,因此不会改写使用者的配置。

这一做法是发现补丁 config 透传缺陷的关键(见 10.2 之错误 5)。

A.2.6 健康自检

bash 复制代码
bash 03_配置与脚本/verify.sh

检查 6 项:进程唯一性、服务可达性、服务端生效环境、驻留与显存、

工具调用冒烟、视觉冒烟、Hermes 侧配置(兜底链/载荷/辅助槽位)。

A.3 已应用的配置变更清单

# 变更 位置 回滚命令
1 新建 qwen3.8-hermes(num_ctx 65536,temp 0.3) Ollama ollama rm qwen3.8-hermes
2 providers.ollama-launch.default_model / .model → qwen3.8-hermes profile config hermes config set 回原值
3 11 个辅助通道 → 本地 profile config revert.sh
4 fallback_model → 本地 profile config hermes fallback clear
5 auxiliary.vision.fallback_chain → 远程兜底 profile config 删除该键
6 OLLAMA_CONTEXT_LENGTH 8192 → 32768 Windows 注册表 setx 回原值
7 源码补丁:agent/coding_context.py(2 hunk) hermes-agent cp .bak-20260912 覆盖
8 local_exec.sh 默认整表降级 + skills 工具 交付目录 --full-menu 单次关闭

A.4 交付目录索引

复制代码
Hermes-本地模型最大化/
├── 00_项目总览/README.md            项目索引
├── 01_实测报告/                      性能基线与瓶颈 + raw/(全部原始输出)
├── 02_优化方案/                      组合卡 + 已应用优化与验证证据
├── 03_配置与脚本/                    模型定义 / 基准 / 自检 / 保温 / 回滚 / 启动
├── 04_实证核验/                      端到端验收记录 + verify.sh 输出
├── 05_技能索引决策/                  技能索引瘦身决策书 + 分析脚本
├── 06_混合路由策略/                  三层路由 + 执行器封装(local_exec.sh)
├── 07_动态加载优化/                  降级方案 + 补丁 + 验证 + 重打脚本
├── 08_决策融合/                      两个选择的优劣 + 第三条路径
└── 09_研究报告/                      本报告(13 章 + 全文合并 + 字数统计)

A.5 引用本报告时的注意事项

  1. 区分"能力上限"与"部署上限" :模型原生支持 262,144 上下文,
    本机部署上限 65,536。引用时须说明是哪一者。
  2. 区分实测与推算:正文已用 L1/L2/L3 标注,引用时应保留该区分。
  3. 核对版本 :Ollama / Hermes / 模型三者版本变化可能使结论失效
    (已有先例:投机解码支持性随版本翻转)。
  4. 硬件强相关项:所有延迟与容量结论绑定 RTX 5090 Laptop 24 GB + WDDM。
  5. 不与"使用频次"混淆 :本报告未获得技能使用率数据(缺口 1),
    因此任何"某技能不重要"的推断均为基于内容的判断,非基于使用统计。

附录 B 术语表与缩略语

本附录统一报告中的关键术语,避免读者因同名异义产生误读。

每个术语给出"本报告中的定义"与"为何需要区分"。

B.1 性能与推理类

术语 本报告定义 易混点
预填充(prefill) 模型处理输入提示的过程,逐 token 计算并建立 KV 缓存 与"生成"区分:预填充是并行的、吞吐以千 tok/s 计;生成是串行的、以十 tok/s 计
生成(decode / generate) 模型逐 token 产生输出的过程 同上
固定载荷(fixed payload) 每一轮都原样重发的提示部分:系统提示 + 工具 schema 与"对话历史"区分:历史是增量的,固定载荷是恒定的
in= Hermes agent.log 中每次 API 调用记录里发送给模型的输入 token 数 本报告的主口径;由输入决定,不受并发影响,具确定性
latency= 同一条记录中的调用延迟 不可作为对比依据------受本地单并发队列调制
前缀缓存 服务端复用已计算过的提示前缀 KV,只计算新增部分 条件严格:前缀字节不变 + 模型驻留
KV 缓存 自注意力机制的键值缓存,随上下文长度线性增长 本机实测约 4.0 KB/token(因混合注意力而远低于常规模型)
冷加载 将模型权重从磁盘载入显存的过程 本机 12.36--12.70 s,是"停顿惩罚"的主要来源
驻留 模型在显存中保持加载的状态 由 KEEP_ALIVE 控制,本机默认仅 2 分钟
串行队列 因 NUM_PARALLEL=1,本地服务的请求逐条执行 使并发请求的延迟变为"服务时间 + 排队时间"
投机解码 / MTP 用模型自身的多 token 预测头草拟多个候选 token,再一次性校验 本机实测接受率 0.52,是生成吞吐的重要来源

B.2 架构与硬件类

术语 定义 说明
WDDM Windows 显示驱动模型 显示子系统与 CUDA 共享显存,导致"理论可用"与"实际可用"不一致
混合注意力 部分层使用线性注意力的架构 Qwen3.5 采用;这是 KV 成本极低(~4 KB/token)的原因
mmproj 多模态投影器(本项目为 clip 架构,460.73M 参数) 占用独立显存,容量估算时必须计入(最坏 1,161 MiB)
Tier-0 / 1 / 2 本报告提出的三层路由:无模型 / 本地手 / 远程大脑 Tier-0 是常被忽略的一层:确定性任务不需要任何模型
工单(work order) 远程大脑交给本地执行者的自包含任务说明 必须包含目标/输入/约束/输出格式/自检/终止条件
辅助通道(auxiliary slot) Hermes 中由独立(可不同)模型承担的辅助任务,如视觉、压缩、标题生成 本报告将 11 项本地化、2 项保留远程

B.3 知识与削减类(本报告的核心术语)

术语 定义 为何关键
技能索引(skills index) 系统提示中列出全部可用技能及其描述的区块 本机占系统提示 60%,是本轮最大的固定成本
渐进式披露(progressive disclosure) 只发送"目录",需要时再按需加载完整内容 Hermes 技能系统的既有设计;"动态加载"并非需新建的机制
降级(demote) 把索引中的描述去掉,保留技能名 本报告的中心手段:省成本而不损失可加载性
裁剪(prune) 使技能或工具不可见、不可加载 本报告明确不推荐------"pruning caused silent capability loss"
可发现性 模型在系统提示中"看到"该能力存在 三分模型之一
可加载性 模型能按名字取得该能力的内容 三分模型之二
可用性 该能力所依赖的工具/环境确实存在 三分模型之三
粒度(granularity) 削减决策的匹配单位(本报告的案例:类别 vs 进程) 粒度错配是伪两难的成因
作用域(scope) 削减决策生效的范围(档案级 vs 进程级) 进程级作用域是融合方案的关键机制
惰性变更(inert change) 未显式启用时行为与变更前完全一致的变更 使"已应用"与"已启用"成为两个独立决定
伪两难(false dilemma) 看似必然的权衡,实由实现选择造成 本报告识别并消解的核心对象
无损劣化 变更失效时退回现状,而非留下半启用状态 优于"有损优化"的风险性质

B.4 测量与验证类

术语 定义 说明
可控口径 由被测对象决定、不受环境调制的测量量 如 in=;唯有此类量可作为结论依据
隔离验证 以显式参数测试新功能,不改动使用者实时配置 本报告借此发现补丁的 config 透传缺陷
活体探针 通过一次真实调用 + 服务端日志确证路由 视觉辅助通道的本地化即以此验证
L1 / L2 / L3 实测 / 推算 / 推断三级可信度标注 报告中逐条标注
三道检验 机制检验 / 因果检验 / 成本检验 本研究用以剔除伪优化的流程
负结果 被实测否定的候选优化 与正结果同等重要:防止重复投入

B.5 五条元规律(提法索引)

编号 名称 一句话
M1 成本引力在调用方 先问固定重发的字节数,而非组件参数是否最优
M2 粒度错配制造伪两难 遇到取舍,先问"能否换一个单位重述"
M3 可发现性 / 可加载性 / 可用性三分 先问要削的是"被想起的概率"还是"被调用的能力"
M4 无损劣化优于有损优化 先问失效时是退回现状还是半启用
M5 口径决定结论 先定哪个量由被测对象决定、哪个被环境调制

B.6 缩略语

缩略语 全称 说明
KV Key-Value(缓存) 注意力机制的缓存张量
MTP Multi-Token Prediction 多 token 预测,用于投机解码
FA FlashAttention 注意力计算优化内核
WDDM Windows Display Driver Model Windows 显示驱动模型
CJK Chinese / Japanese / Korean 汉字字符集,本报告字数统计口径之一
SOP Standard Operating Procedure 标准作业程序
IP Intellectual Property 知识产权(本档案的主题领域)

相关推荐
打工仔折腾 AI9 小时前
Docker镜像分层与卷挂载到底怎么工作:一次文件系统层面的实测分析
运维·人工智能·后端·python·docker·容器·性能优化
墨染天姬10 小时前
【人工智能训练师】python语法二
开发语言·人工智能·python
深蓝AI10 小时前
748GB 统一内存装进桌面:英伟达 DGX Station 本地跑万亿参数模型,瓶颈不在算力在插座
人工智能·agent
成旭先生10 小时前
AI 文本审核 API:一段中文文本判风险等级、命中标签与处置建议
java·前端·人工智能·api接口·内容风控·文本审核·ugc审核
草上飞952711 小时前
把前沿能力装进便宜产物,本身是多数模型还不会的能力
人工智能·深度学习·llm
林澈在路上11 小时前
2026生成后可发行的AI音乐工具怎么选
人工智能·版权·ai音乐·音乐发行·melo音乐
LoneEon11 小时前
CentOS7 部署 Nacos3.x 集群实战:从注册中心到 AI 管理中心
linux·人工智能·nacos
RobinDevNotes11 小时前
亲手量化大模型,Mac实测和NVIDIA指南
人工智能·后端
跟我学机器学习11 小时前
Qwen3 Reranking原理与使用:重排模型在 RAG 中的作用
人工智能·深度学习·transformer
袁俪11 小时前
数字孪生驱动大模型
人工智能