用三个 LLM 进行辩论、由 Hermes 判定的零成本多模型系统,展示了创意 prompt 工程如何在低成本下实现高质量决策。
这是 Hermes Agent Challenge:Build With Hermes Agent 的参赛作品。
TL;DR —— 提出任何需要判断的问题,三个不同的 AI 模型会各抒己见、相互辩论,最后由 Hermes 给出唯一裁决、置信度评分,以及它们产生分歧的确切原因。每次裁决、异议,以及在辩论中改变立场的记录,都会写入 Hermes 自己的 memory。所以下一个问题开始投票前,系统就能重新调整各位陪审员的权重。裁决过程是基于这些 memory 的纯函数:没有 memory,就没有权重,也没有裁决。三个模型,一个裁决,成本为 0 美元。
有一次,某个 LLM 以十足的信心说服我选错了数据库。它给出的回答流畅、权威。我把它上线了。结果搭进去一个周末,还做了一次直到今天都让我耿耿于怀的数据迁移。
这里真正的反派,是单一模型的过度自信:你得到的是一份精心润色的回答,而本应向你发出警告的分歧却被隐藏了。你永远看不到其他意见,因为你只问了一个模型。
所以,我不再信任单一模型,而是召集了一个陪审团。
Council 可以接收任何需要判断的问题,例如“Postgres 还是 Mongo?”、“这个 PR 可以安全合并吗?”、“这个条款有风险吗?”。它会询问三个不同的模型,让它们表达分歧,再由 Hermes 给出一个最终裁决、一个置信度评分,以及它们产生分歧的确切原因。三个模型,一个裁决,成本为 0 美元。
你提出一个问题,Council 会将它分发给三位陪审员:两个来自不同模型家族的免费 OpenRouter 模型,以及一个通过 Ollama 运行的本地模型。每位陪审员都会给出立场和理由。如果它们意见不一致,系统就会进行第二轮审议:每位陪审员都能看到其他人的回答,并决定坚持立场还是改变想法。这样,Council 进行的是真正的辩论,而不只是一次投票。随后,Hermes 会基于审议后的意见作出判断:给出唯一裁决、一个置信度评分——意见一致时较高,2 比 1 分裂时较低——以及一个“它们为什么产生分歧”的面板。每次裁决都会被记住;一个 Council skill 会学习针对不同类型的问题应该信任哪位陪审员;Agent 甚至可以主动提出信任权重调整建议,交由你批准。
整个产品只有一个问题输入框。所有有趣的事情都发生在它背后,而本文剩余的大部分内容,都是用图片展示这个“背后”究竟发生了什么。
Repo:https://github.com/ArqamWaheed/council
在线演示:https://council-jet-kappa.vercel.app/
Hermes 编排只能在本地运行——serverless 环境中没有 Hermes binary;托管演示通过 OpenRouter/mock 运行相同的 UI。要体验真正的 hermes -z 路径,请在本地运行。
试着输入:“一家只有 3 个人的创业公司应该使用微服务吗?”,然后打开异议面板。
本地只需一条命令即可运行。离线 mock 模式的成本为 0 美元,也不需要 key:
git clone https://github.com/ArqamWaheed/council && cd council && ./setup_hermes.sh && python server.py
我认为直接看图最容易理解这个设计,所以下面会用一组连续的图片展示整个系统。每张图片的说明文字就是相应的解释。
核心循环:一个问题被并行分发给三个相互独立的 Hermes subagent——两个托管模型和一个本地模型——然后再进行第四次 Hermes 调用,由 foreman 综合生成唯一裁决。每条箭头使用的都是同一个 hermes -z 接口;没有任何组件直接与模型通信。
核心押注:托管模型和端侧模型可以坐在同一个陪审团里,只需通过一个 --provider/--model flag 就能替换,完全不需要修改代码。整个项目都建立在 Hermes 的这一项特性之上:模型无关性。
UX 界面:陪审员意见一致时,置信度较高;出现 2 比 1 的分裂时,置信度就会下降。异议面板默认折叠,而当置信度数字让你感到不安时,你可以展开它查看详情。
真正的产品:一个自信满满的单一回答会把分歧藏起来;Council 则让分歧成为主角。要在这里正确完成意见聚类并不简单,具体可参阅下文的“我学到了什么”。
重头功能:一个会审议,而不只是投票的 Council。第一轮结束后,如果陪审员存在分歧,它们会进行第二次 Hermes 调用。在这一轮中,它们会阅读彼此的论点,并决定坚持还是改变自己的投票。改变立场的陪审员会显示“⇄ changed”徽章;当原本 2 比 1 的分裂通过讨论转为一致时,置信度仪表盘也会真正上升。
Agentic learning 闭环,由人参与决策:Hermes 提出建议,由你批准或忽略。获批的规则会持久保存在客户端,并随下一次 convene 请求一同发送。
裁判可以验证的持久化机制:裁决会同步写入 Hermes 自己的 memory,因此 recall 是由 Hermes 真正完成的;相关证明位于 docs/hermes-proof/04-memory-recall.txt。
Repo:https://github.com/ArqamWaheed/council
hermes_run.py:所有陪审员和裁判调用都会经过的 Hermes CLI driver。
run_council.py:负责 orchestration、确定性 judge、Hermes foreman,以及 --reflect 闭环。
skills/council/SKILL.md:Hermes 会编辑的陪审员权重大脑。
server.py:提供 /api/reflect 和 /api/learn endpoints。
index.html:设计完成的裁决 UI,包括 foreman TTS 朗读和 localStorage 持久化。
Hermes 确实参与了整个流程的证据,包括 subagent transcript、skill diff 和 memory recall,都位于 docs/hermes-proof/。
# hermes_run.py: every juror/judge call is a real Hermes run
def ask(prompt, provider, model, skills=None, timeout=120):
cmd = [binary(), "--provider", provider, "--model", model]
if skills: cmd += ["--skills", skills]
cmd += ["-z", prompt] # -z = one-shot, final answer on stdout
return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout).stdout
# jurors.py: fan out one Hermes subagent per juror, in parallel
with ThreadPoolExecutor(max_workers=len(roster())) as pool:
opinions = list(pool.map(lambda c: ask_juror(*c), enumerate(roster())))
为什么一定要用 Hermes:因为它具有模型无关的核心能力。Hermes 允许你指向任意 provider,只需修改一个 flag 就能切换模型,无须改动代码。Council 正是建立在这一特性之上的:陪审员由不同模型组成,而 Hermes 是唯一能让“使用不同模型”这件事变得低成本的组件。
最清楚的证明就是第三位陪审员:它通过 Ollama 在本地运行,而另外两位陪审员托管在 OpenRouter 上,但三者都通过完全相同的 hermes -z 接口回答问题,也就是上方模型无关性示意图所展示的内容。一个托管模型和一个端侧模型坐在同一个陪审团里,却不需要修改任何代码——这就是肉眼可见的模型无关性。说实话,我没有看到这次挑战中的其他参赛作品利用这一点;大家都是选定一个模型,然后继续往下做。而这正是整个项目最核心的押注。
Subagent:每位陪审员都对应一次真正的 Hermes 运行。每位陪审员都是一次真实且隔离的 Hermes invocation,分别使用不同的 provider 与 model。两个托管陪审员使用 hermes -z --provider openrouter --model …,端侧陪审员则使用 --provider ollama-local …。它们会被并行分发,因此不会有某个模型的推理先入为主地影响另一个模型,也就是上方 convene-flow 图中所示的流程。
推理工作由 Hermes 完成;我的 Python 代码——从 jurors.py 到 hermes_run.py——只是负责 fan-out 的管道。在输出 JSON 中,每位陪审员都会被标记为 "via": "hermes"。
这里有一个值得特别提醒的坑:Hermes 强制要求至少 64K context。对于本地模型,这意味着既要设置 ollama_num_ctx,也要添加一个命名的 custom_providers 配置项。如果不使用命名 provider,--provider ollama 会悄无声息地将请求路由到错误的 base URL。setup_hermes.sh 已经写入了可正常工作的配置,因此评委只需一条命令就能复现。
真正的辩论,而不只是投票——第二轮是真实的 Hermes 工作。这是我最引以为傲的功能。第一轮结束后,如果陪审员之间存在分歧,每位陪审员都会再次运行 Hermes。这一次,系统会向它展示其他人的立场和主要理由,并要求它决定坚持还是改变想法。
真正的陪审员会通过与第一轮相同的 hermes -z 路径重新考虑;mock 陪审员则以确定性方式重新评估,从而保证离线演示可以复现。因此,这场辩论是真正额外执行的 agentic work,而不是 UI 上的装饰。
随后,judge 会根据审议后的意见综合生成裁决。因此,如果某位陪审员被其他人的论点说服,它确实会改变最终结果,也就是上方 deliberation 图中展示的流程。只有出现分歧时才会启动第二轮;如果第一轮意见一致,系统就会跳过。你也可以通过 COUNCIL_DEBATE=0 关闭它。
为什么使用 skill,而不是用 prompt 进行判断。Foreman 的裁决本身也是一次 Hermes 运行,即 hermes -z --skills council,并以 skills/council/SKILL.md 为依据。这个 skill 会安装到 Hermes 中,可以通过 hermes skills list 查看。权重逻辑存放在一个机器可读的 weights block 中。
判断大脑是数据,而不是藏在某个角落里的 prompt。--learn 和 --reflect 都会编辑这个 block,并同步更新已经安装到 Hermes 中的副本。
在连续处理了一系列安全问题后,--learn 添加了一条规则:针对安全主题提高本地模型的权重,并同步更新已经安装到 Hermes 中的副本。这是因为本地模型发现了一些被托管模型漏掉的问题:
python run_council.py --learn "Local Juror | security | 1.5"
下一次再遇到安全问题时,该陪审员的投票权重会变成 1.5 倍,由 judge 直接读回。反事实对比是:静态的综合 prompt 不会变得更好,但这个系统可以。修改前后的 skill diff 位于 docs/hermes-proof/03-skill-learning.txt。
让 Agent 主动提出学习建议:现在它已经可以在 Web 上运行,并且有真实证据作为依据。python run_council.py --reflect,以及 UI 中的“Should the council reweight itself?”按钮,会把 Hermes 自己保存的历史裁决 memory 交给它,并要求它提出一项权重调整建议。例如:“本地陪审员在三次数据库决策中都提出了异议;提高它的权重。”
这一轮最关键的修复,是让建议以证据为基础。Hermes 会收到真实的异议统计;任何没有至少两次真实异议支撑的规则都会被拒绝。因此,它不能只是复述 skill 中预先写好的示例。随后,你可以选择 Approve 或 Dismiss,也就是上方 reflect-flow 图中所示的过程。
这才是诚实完成的 agentic 闭环:单次裁决并不存在 ground truth,因此 Agent 负责呈现一种模式,再由人类确认它代表的是真实信号,而不是过拟合。这也正是本文最后要讨论的矛盾。离线运行时,系统会退回到一个确定性 heuristic,因此永远不会因此中断。
让学习结果在 stateless deploy 中继续存在。托管演示环境中的文件系统是只读的,因此获批规则无法写回 SKILL.md。Council 对此采用了诚实的处理方式:获批规则会存储在浏览器的 localStorage 中,并随每次 /api/convene 调用重新发送。服务器会针对当前请求,把这些规则合并到 judge 的 weights 中。
在本地运行时,你会得到持久化的 SKILL.md;在 Web 上,你会得到按浏览器持久化的数据。无论使用哪种方式,学习结果都能保留下来。
为什么使用 memory。每次裁决都会追加到日志中,并同步写入 Hermes 自己的 MEMORY.md。因此,我可以询问 hermes -z "what did the council decide about auth?",Hermes 会从自己的 memory 中回忆相关内容,而不是由我的代码代为查找,正如上方 memory-recall 图片所示。证明位于 docs/hermes-proof/04-memory-recall.txt。
Foreman 会大声宣读裁决。裁决卡片上有一个“the foreman reads the verdict”按钮,使用浏览器 SpeechSynthesis 实现,成本为 0 美元。Hermes 也通过 hermes setup tts 提供原生 TTS。这个功能很契合主题,也很有记忆点:由陪审团 foreman 宣布最终决定。
构建过程本身也是由 Agent 驱动的。我维护了一个 memory.md,coding agent 会在每个任务开始前读取,并在完成后更新,从而以较低成本保留上下文。每个增量都会按照 Conventional Commits 规范提交。我还使用 frontend-design skill 构建了裁决 UI,所以置信度仪表盘和按颜色编码的陪审员标签看起来是经过设计的,而不是默认模板式的 AI 垃圾。仓库中的 AGENTS.md 和 commit history 展示了整个过程,而不仅仅是最终结果。
为什么选择这些模型,以及必须承认的代价。系统使用两个来自不同模型家族的免费 OpenRouter 模型——它们的 context 至少为 64K,因为 Hermes 会在启动时拒绝更小的模型——再加上一个本地 Ollama 陪审员。
这里需要坦诚承认两个问题:
对于一种“每次需要做决定时才使用”的工具,我愿意接受这些代价。成本:0 美元。
许可证:MIT。欢迎 fork,并加入你自己的陪审员。
分歧本身就是产品。2 比 1 的分裂比一个自信满满的单一回答更有价值,因此,用来判断“究竟谁真的持有不同意见”的聚类必须准确。
有一次,一个小型本地模型写下了一个含糊的立场:“to facilitate efficient integration…”,但它给出的理由明显支持 Postgres。第一个版本却错误地把它归类成了异议方。
修复方式是:当陪审员明确表达的立场含糊不清时,改为读取它给出的理由;同时忽略那些只是在比较中被提到的选项——“better than Mongo”并不代表它投票支持 Mongo。现在,意见一致的陪审员会被正确聚类到一起,分裂数量也能如实反映情况。
有依据,胜过说得漂亮。只有当 Agent 提出的权重调整建议与真实证据相关联时,这项能力才真正有效。没有依据的“reflect”,只会复述 skill 中原本就存在的示例。
Hermes 的 64K context 下限,帮我发现了一个原本会悄无声息地表现不佳的模型。
Council 应该进行审议,而不只是投票。上面介绍的第二轮辩论是整个项目的转折点:让陪审员阅读彼此的论点并重新考虑,意味着真正被说服的陪审员会改变裁决结果。你还能亲眼看到,随着 2 比 1 的分裂转变为全体一致,置信度仪表盘也随之上升。一次性的投票无法做到这一点。
部分评论可能只有登录用户才能看到。请登录以查看全部评论。
如果需要采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。