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=qwen35parameters=27.3Bcontext 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_ctxnum_batchnum_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.logload_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.shverify_patch.pyreapply_patch.shdemote_savings.pyhermes_bench.py;升级:ollama-tuninghermes-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.logsystem 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_v13compute=12.0 server.loginference 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-mtpMTP 投机解码已启用(见 3.6)。
  • --flash-attn on--cache-type-k/v q8_0:KV 缓存量化与 FlashAttention 生效。
  • --load-mode nonedisabling mmap for llama-server load by default, reason=windows_cuda
    Windows CUDA 下禁用内存映射加载。

3.2 吞吐基线

3.2.1 预填充速率与生成速率(qwen3.8:latestnum_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=lengthcontent 为空。

将预算提高到 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-hermesnum_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

原因是两个标签共享同一份权重 blobsha256-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 --jsonskills_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-propertyrd-management

patents-searchregulatory-affairs-head 等)合计约 105 tok,占索引 0.8%

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

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

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

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

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

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

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

含有关键能力的迁移包 其中的关键技能 对该档案的价值
scientific-skills uspto-database 专利检索------IP 档案的立身之本
scientific-skills openalex-databaseliterature-reviewpeer-reviewscientific-critical-thinkingscholar-evaluationcitation-management 学术检索与审稿
scientific-skills docxpdfxlsxpptxmarkitdown 交付格式
scientific-skills rdkitchembl-databasepubchem-database 化学/配方
scientific-skills iso-13485-certificationfda-databasemarket-research-reports 法规与研报
scienceclaw-migrated crossref-searchsemantic-scholar 文献核验
scienceclaw-migrated legal-analysisregulatory-drafting 法务与法规撰写
scienceclaw-migrated nano-banana-proscientific-diagram-generationdata-visualization-expert 顶刊级配图
scienceclaw-migrated pdf-processingpdf-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_ctxnum_batch
    num_gpuKV 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_ALIVECONTEXT_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.logserver 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 设为 -130m 改变使用者的既有启动方式
无 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,000latency=12--31 s

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

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

6.5 本章小结

结论 数值 / 内容 可信度
冷加载代价 12.36--12.70 s L1
服务端 KEEP_ALIVE 默认值 2m0s L1
该值的来源 Ollama 桌面版注入(db.sqlitesettings 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.login= 为主(确定性),墙钟为辅。

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 tokensdraft acceptance = 0.52163

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

7.6.3 已知代价(如实标注)

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

同一次视觉调用返回 Connection erroropenai.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-skillsscienceclaw-migrated 4,474 2.6 31% 100%
① + bmad-migratedworkbuddy-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 docxpdfxlsx(使用者的交付格式)
creative baoyu-article-illustratorbaoyu-infographicclaude-design(插图线)
research academic-manuscript-auditgrounded-citations(论文线)
software-development skill-orchestration-strategysubagent-driven-development

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

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

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

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

因此,这个"收益 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=0in=15,914

结论

整表降级方案在保留全部技能职能(skills_listskill_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 updategit 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 同时含 docxairtable

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

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

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

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

成本与后果都不同。

证据链

  • 移除技能工具 → 三层全失(_skills_prompt 返回空)
  • 降级为仅目录 → 仅丢描述,名字、加载、执行全保留
  • 实测 disabled = 0skills_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-skillsscienceclaw-migrated 两个包",理由是它们是"批量迁移来的"。

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

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

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

包内关键技能 价值
uspto-database 专利检索------IP 档案的立身之本
crossref-searchsemantic-scholar 文献核验(使用者的既定习惯)
docxpdfxlsx 交付格式(使用者的硬要求)
nano-banana-pro AI 生图通道
legal-analysisregulatory-draftingiso-13485-certification 法务与法规
rdkitchembl-databasepubchem-database 化学/配方
scientific-diagram-generationdata-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,21611,632 本身就是 in= 字段的 token 值 (已经过换算),

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

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

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

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

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

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

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

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

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

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

在脚本中把变量名包含量纲(如 tokens_fixedbytes_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.login=(确定性)为主口径,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-hermesnum_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.dbmessages 表搜索 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.sqlitesettings 表;

但**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 同时含 docxairtable)→ 必然误伤
作用域 = 档案级 无法让主会话与本地手取不同值

解法(第三条路径)按进程定粒度 ------不挑类别,整表降级;

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/pssize_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_*.jsonrequest.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.logAPI 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.logDeepSeek-V4.1-Flash in=
辅助通道路由证据 7.6.2 server.logPOST /v1/chat/completions + agent.logAuxiliary ... using ollama-launch 时间戳对齐
兜底链配置 7.7 hermes fallback list 输出 直接引用
历史 401 中断 7.7 sessions/request_dump_20260902_*.jsonerror 字段 直接引用
四份名单收益 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.sqlitecontext_length=65536 6.2.2 Ollama db.sqlitesettings 表(只读查询) 直接查询
保温触碰 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.login= 读取。

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-hermesnum_ctx 65536temp 0.3 Ollama ollama rm qwen3.8-hermes
2 providers.ollama-launch.default_model / .modelqwen3.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 知识产权(本档案的主题领域)

相关推荐
甲维斯1 小时前
完蛋了,豆包变这么强?Seed2.1pro小测一下!
前端·人工智能
政企项目老覃1 小时前
边缘 AI 推理部署:安防零售场景下的模型裁剪与端侧落地实践
人工智能·程序人生·算法·性能优化·vllm
sarasuki1 小时前
如何让LLM 能在半夜偷偷打开网易云呢?
人工智能·设计模式·agent
jsl_jsl_jsl1 小时前
《单机 Agent 应用的可观测性:刻意轻量的日志与调用链实现》
人工智能
G***技1 小时前
告别物联网碎片化:杰和LH707+LM2-100-V0联合方案给出标准答案
人工智能·嵌入式硬件
szxinmai主板定制专家1 小时前
【工控实战】RK3568/RK3588 8路隔离CAN/CANFD完整解决方案|多路总线并行通信、车载/工控量产落地
人工智能·fpga开发·zynq·mpsoc·半导体设备
刘马想放假1 小时前
RK3588 使用 rk-llama.cpp + RKNPU2 部署 Qwen3.5:从零开始的 NPU 本地大模型实战
人工智能·开源·llm
商业看点解说1 小时前
哪些 AI 创业公司和生成式 AI 产品适合使用 Amazon Bedrock?
人工智能
智驭未来掌门人1 小时前
大模型网关集成 MCP 与 CLI 的调用指南(自动分配密钥工具)
人工智能