1. 从一句“分析甲醇”说起:多角色投研到底解决什么问题
如果你做过期货或者股票的基本面研究,大概率经历过这种状态:打开行情软件看技术面,切到资讯页翻供应新闻,再打开 Excel 拉库存和开工率数据,最后在脑子里把多空逻辑揉成一团,写出一份“综合判断”。问题不在于你不会分析,而在于一个人同时扮演数据员、技术派、多头、空头和风控,视角会互相污染。你刚看完伊朗装置复产的利空,再去看多头逻辑,写出来的多头论据明显就软了。
Hermes 的多角色协作就是冲着这个痛点来的。它把“一个 Agent 切来切去”变成“多个独立 Profile 各跑各的”,每个角色在自己的进程里工作,看不见别人的中间产物,最后通过 Kanban 任务图把产物汇总给一个综合者。这套机制在智能投研场景里特别合适,因为投研本身就是天然的多角色分工:数据采集、技术分析、多头论证、空头论证、风险评估、最终裁决,每个环节需要的能力和心态都不一样。
这篇文章要带你跑通的,是一条完整的多角色投研流水线:用 Profile 划分研究员/风控/交易员角色,用 Skill 封装数据抓取与研报生成,用 Kanban 跟踪任务、Dispatcher 分发调度。我会给出可复制的 Profile 与 Skill 配置骨架、Kanban 看板字段示例,并演示一次从任务下发到研报产出的完整验证流程。目标很明确——你照着做,能跑通自己的多角色投研系统。
适合谁看:用过 Hermes 或者类似 Agent 框架、想从单 Agent 升级到多 Agent 协作的开发者;做量化或投研、想把重复性研究工作自动化的技术人;以及任何对“多角色 Agent 协作”这个模式好奇、想找个真实场景练手的人。不需要你是期货专家,文章里的甲醇只是案例载体,换成股票、可转债、甚至非金融领域的多角色协作,逻辑完全复用。
在开始之前,先把四个核心概念摊开,避免读到一半卡壳。
Hermes Agent:一个 AI Agent 框架,定位类似 Claude Code / Cursor,但有三个独到能力——持久记忆(关机不丢)、技能系统(领域知识沉淀成可复用包)、多 Profile 协作(一个工具跑多个 AI 角色协同)。本文集中在第三个能力上。
Profile:一份独立的 Agent 配置,通俗说就是“一个 AI 角色”。每个 Profile 有自己的模型选择、人设规则(SOUL.md)、记忆、技能集。7 个 Profile 启动后是 7 个独立进程,看不见彼此的中间产物。
Kanban:SQLite 持久化的任务图。所有任务、依赖、状态、事件流都存在~/.hermes/kanban/kanban.db这一个本地数据库文件里。Hermes 内置 dispatcher 调度器——每秒扫一次:哪些任务的依赖都满足了就升为 ready,哪些 Profile 有空闲槽就 spawn 一个 worker 过去 claim 任务。Profile 之间不直接对话,全部通过 Kanban 传递产物。
Skill:可复用的领域包。不是一段 prompt,是一个完整目录,含SKILL.md(描述能力)、scripts/(可执行脚本)、references/(知识库)。Agent 加载技能用渐进披露——先看目录,按需展开内容。
把这四个概念挂住,后面所有内容都是它们的组合。下面进入实操。
2. 前置准备:TaoToken 接入与 Hermes 环境搭建
在跑多角色投研之前,得先把模型接入和环境配好。这一步很多人会卡在 API 配置上,我把自己踩过的坑和最终跑通的配置完整写出来。
2.1 为什么用 TaoToken 做模型接入层
Hermes 的每个 Profile 都要调模型,7 个角色意味着 7 套模型配置。如果每个 Profile 都单独去配官方 API,管理成本很高,而且不同角色的模型切换、额度控制会很麻烦。TaoToken 在这里扮演的是统一接入层的角色——一个 API Key、一个 Base URL,所有 Profile 共用,切换模型只改 Model ID 就行。
它的 API 地址是https://taotoken.net/api,兼容 OpenAI 格式的调用方式,Hermes 的config.yaml里直接填就行。官网在https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,注册和拿 Key 都在控制台里完成。
2.2 拿 API Key 并配置到 Hermes
第一步,登录控制台创建 API Key。地址是https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite,进去之后在 API Keys 页面新建一个 Key,复制出来备用。这个 Key 后面要填到每个 Profile 的config.yaml里,或者统一放到环境变量里让所有 Profile 共享。
第二步,确认 Hermes 已经装好。如果你还没装,先按官方文档把 Hermes CLI 装到本机,能跑hermes --version就行。
第三步,配置模型接入。Hermes 的每个 Profile 目录下都有一个config.yaml,模型相关的字段在这里配。下面是我实际用的配置骨架,路径是~/.hermes/profiles/<profile_name>/config.yaml:
# ~/.hermes/profiles/bull_researcher/config.yaml model: provider: openai-compatible base_url: "https://taotoken.net/api" api_key: "${TAOTOKEN_API_KEY}" model_id: "deepseek-v4-flash" temperature: 0.7 max_tokens: 8192 runtime: max_runtime: 20m max_retries: 2这里有几个关键点。base_url填https://taotoken.net/api,注意不要带多余的路径后缀。api_key我用的是环境变量${TAOTOKEN_API_KEY},这样 7 个 Profile 共用一份 Key,不用每个文件都改。model_id填你要用的模型标识,我这次全用deepseek-v4-flash是为了控本机预算,生产环境可以给 CIO 换更强的推理模型。
环境变量在 shell 里这样设:
export TAOTOKEN_API_KEY="你的_API_Key"想持久化就写进~/.zshrc或~/.bashrc。设完之后echo $TAOTOKEN_API_KEY确认一下能打印出来。
2.3 验证接入是否通
配好之后别急着建 Profile,先验证一下模型能不能调通。Hermes 有个简单的对话入口,或者你直接用 curl 测一下 TaoToken 的接口:
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "回复 OK 两个字"}] }'如果返回里有正常的choices字段和内容,说明 Key 和 Base URL 都没问题。这一步很重要,因为后面 7 个 Profile 都依赖这个接入,如果这里不通,后面所有任务都会卡在模型调用上。
2.4 创建 7 个 Profile 的目录骨架
接入验证通过后,开始建 Profile。Hermes 创建 Profile 的命令是hermes profile create <name>,但为了让你理解每个 Profile 的目录结构,我先把骨架列出来。每个 Profile 落到磁盘上是一个目录,路径在~/.hermes/profiles/<profile_name>/:
~/.hermes/profiles/bull_researcher/ ├── profile.yaml # Profile 元信息(名字、描述、属哪个集合) ├── config.yaml # 模型、温度、token 上限等运行参数 ├── SOUL.md # 这个角色的"灵魂"——人设规则、判断框架、输出约束 ├── memories/ │ └── MEMORY.md # 这个角色的持久记忆(关机不丢) ├── skills/ # 挂到这个角色的技能目录树 ├── sessions/ # 历史会话存档 ├── checkpoints/store/ # 关键操作前的回滚快照 ├── cron/ # 这个角色专属的定时任务 ├── hooks/ # 事件钩子 ├── workspace/ # 角色的工作目录 └── state.db # SQLite,存这个角色的运行时状态最关键的是SOUL.md,它是这个角色的人设和判断规则。我的bull_researcher的SOUL.md核心内容是这样的:
# Bull Researcher Agent Persona You are a biased long-only hedge fund analyst. Mission: Construct the strongest bullish case. Rules: - Focus only on upside catalysts - Ignore bearish arguments unless refuting them - Think in asymmetric upside scenarios Output: Bullish drivers, catalysts, acceleration conditionsbear_researcher是镜像版本,只看空。risk_manager的SOUL.md让它不站队、专做最大回撤情景。chief_investment_officer的SOUL.md让它最后看完所有人的报告再下结论。7 个 Profile 的差异本质是 7 份SOUL.md的差异,其他都是 Hermes 给每个 Profile 标配的基础设施。
建完 7 个 Profile 后,跑hermes profile list应该能看到类似这样的输出:
| 档案 | 状态 | 模型 |
|---|---|---|
| default | 运行中 | deepseek-v4-flash |
| bear_researcher | 停止 | deepseek-v4-flash |
| bull_researcher | 停止 | deepseek-v4-flash |
| chief_investment_officer | 停止 | deepseek-v4-flash |
| market_researcher | 停止 | deepseek-v4-flash |
| memory_reflector | 停止 | deepseek-v4-flash |
| risk_manager | 停止 | deepseek-v4-flash |
| technical_analyst | 停止 | deepseek-v4-flash |
到这里,前置准备就完成了。模型接入通了,7 个角色骨架建好了,接下来进入核心配置环节。
3. 可复制配置:Profile 与 Skill 骨架 + Kanban 字段示例
这一节是全文最核心的部分,我会把 Profile 配置、Skill 目录结构、Kanban 任务字段三样东西的骨架完整给出来,你直接复制改改就能用。
3.1 Profile 配置骨架:以 bull_researcher 为例
每个 Profile 的config.yaml结构基本一致,差异在SOUL.md和挂载的 Skill。下面这份是bull_researcher的完整配置,路径~/.hermes/profiles/bull_researcher/config.yaml:
# ~/.hermes/profiles/bull_researcher/config.yaml profile: name: bull_researcher description: "只看多的研究员,负责把多头逻辑挖到底" collection: investment_research model: provider: openai-compatible base_url: "https://taotoken.net/api" api_key: "${TAOTOKEN_API_KEY}" model_id: "deepseek-v4-flash" temperature: 0.7 max_tokens: 8192 runtime: max_runtime: 20m max_retries: 2 heartbeat_interval: 60s skills: auto_load: - research -># ~/.hermes/profiles/bull_researcher/profile.yaml name: bull_researcher description: "只看多的研究员" collection: investment_research created_at: "2026-06-10"SOUL.md是人设核心,前面已经给过骨架。这里补充一个更完整的版本,包含输出格式约束:
# Bull Researcher Agent Persona You are a biased long-only hedge fund analyst. Mission: Construct the strongest bullish case. Rules: - Focus only on upside catalysts - Ignore bearish arguments unless refuting them - Think in asymmetric upside scenarios - Always quantify: price targets, probability, time horizon Output Format: 1. Bullish Drivers (ranked by importance) 2. Catalysts (with timing) 3. Acceleration Conditions 4. Price Targets (short / mid / long term) 5. Confidence Score (0-100)7 个 Profile 的config.yaml除了name和description不同,模型部分完全一样,都指向 TaoToken 的接入。这样你只需要维护一份 API Key,所有角色共用。
3.2 Skill 目录结构:kanban-orchestrator 与 commodity-supply-chain-intelligence
Skill 是可复用的领域包,目录结构长这样。以kanban-orchestrator为例,路径在~/.hermes/skills/devops/kanban-orchestrator/:
kanban-orchestrator/ ├── SKILL.md # 描述能力、使用场景、调用方式 ├── scripts/ │ └── decompose.py # 把模糊需求拆成任务图的脚本 └── references/ └── task-patterns.md # 常见任务图模式参考SKILL.md的核心内容:
# Kanban Orchestrator ## 能力 把一句模糊需求拆成 Kanban 任务图,自动分配 Profile 和依赖关系。 ## 使用场景 - 用户说"分析某个品种/股票" - 需要多角色协作的复杂任务 ## 调用方式 /kanban-orchestrator ## 输出 任务列表 + 依赖关系图 + 建议的 Profile 分配第二个 Skill 是commodity-supply-chain-intelligence,路径在~/.hermes/skills/data-science/commodity-supply-chain-intelligence/:
commodity-supply-chain-intelligence/ ├── SKILL.md ├── scripts/ │ └── commodity_intel.py # akshare + 搜索数据采集脚本 └── references/ └── methanol-ma-fundamentals.md # 甲醇基本面知识库commodity_intel.py的核心逻辑是拉取 10 维数据:合约报价、主力连续日线、OHLCV 详情、技术指标、仓单数据、库存、开工率、进口、成本、新闻。脚本用 akshare 做数据源,搜索部分补充供应链新闻。
3.3 Kanban 任务字段示例
Kanban 的任务字段是这套系统的协议层。下面是一个完整的任务定义示例,对应 T1 数据采集任务:
{ "task_id": "t_be63214a", "title": "data: 甲醇(MA)全维度数据采集", "body": "运行 commodity_intel.py 获取 10 维数据,参考 references/methanol-ma-fundamentals.md", "assignee": "market_researcher", "skills": ["commodity-supply-chain-intelligence"], "parents": [], "status": "ready", "priority": 1, "max_runtime": "30m", "max_retries": 2, "workspace": "scratch", "created_at": "2026-06-10T17:03:00Z" }关键字段说明:
| 字段 | 含义 | 示例值 |
|---|---|---|
| task_id | 任务唯一标识 | t_be63214a |
| assignee | 绑定的 Profile | market_researcher |
| skills | 显式注入的技能 | commodity-supply-chain-intelligence |
| parents | 依赖的父任务 | [t_be63214a, t_e3fef572] |
| status | 任务状态 | todo / ready / running / done |
| max_runtime | 最大运行时长 | 30m |
| workspace | 工作区类型 | scratch / dir:/abs/path / worktree: |
创建任务的命令形态:
# T1:数据采集(带技能注入) hermes kanban create "data: 甲醇(MA)全维度数据采集" \ --body "运行 commodity_intel.py ... 参考 references/methanol-ma-fundamentals.md" \ --assignee market_researcher \ --skill commodity-supply-chain-intelligence \ --max-runtime 30m \ --priority 1 # T5:风控(依赖 T1/T3/T4) hermes kanban create "risk: 甲醇(MA)风险评估" \ --assignee risk_manager \ --parent t_be63214a \ --parent t_e3fef572 \ --parent t_4d675132 \ --max-runtime 15m --priority 2 # T6:CIO(依赖全部) hermes kanban create "cio: 甲醇(MA)投资结论与操作建议" \ --assignee chief_investment_officer \ --parent t_be63214a --parent t_f0afecfd \ --parent t_e3fef572 --parent t_4d675132 \ --parent t_671e0b13 \ --max-runtime 20m --priority 2注意三件事。--assignee把任务绑到一个 Profile,不是用谁的模型跑,是用这个 Profile 的整套配置——它的SOUL.md、memories/、skills/目录树——去跑这个任务。--skill显式注入技能,T1 加了commodity-supply-chain-intelligence,worker 启动时这个技能在skills_list的 Level 0 目录里直接出现。--parent编码依赖,T5 写了三个 parent,T6 写了五个,Kanban 内部就是个 DAG。
整张任务图编码完,本地~/.hermes/kanban/kanban.db存着所有任务、依赖、状态、事件流。这是 Hermes 多 Agent 真正的核心——任务图是持久化的,跨进程跨平台跨 Profile 共享。
3.4 依赖关系图
这套投研流水线的依赖关系是这样的:
T1 (market_researcher) ──┐ T2 (technical_analyst) ──┤ T3 (bull_researcher) ────┤──▶ T5 (risk_manager) ──▶ T6 (CIO) T4 (bear_researcher) ────┘ ▲ │ T5 的输出也流入 T6T1-T4 完全并行,多头看不见空头,空头看不见多头,技术面看不见基本面。这不是低效,是故意的隔离——只有这样每个人才能挖到底。等他们都挖完,T5 才把数据揉到一起做风控。T5 不依赖 T2,技术面不参与风控决策,只参与 CIO 的最终综合。T6 依赖所有人,CIO 是综合者。
4. 验证请求:从任务下发到研报产出的完整流程
配置都就绪后,跑一次完整流程验证。这一节我会把每一步的命令和实际输出都贴出来,你对照着跑。
4.1 启动调度网关
Dispatcher 现在跟 IM 接入网关(gateway)合并了,旧版本的hermes kanban daemon已经废弃。启动命令:
hermes gateway start启动后 dispatcher 每秒扫一次 Kanban,逻辑是:找 expired claim 的 running 任务 reclaim;找status=todo && all_parents=done的任务升为 ready;找status=ready且对应 Profile 有空闲 worker 槽的 spawn worker;检查 running 任务的 heartbeat,长时间无心跳的 reclaim。
4.2 加载总调度技能并拆解任务
在 Hermes 会话里调用总调度技能:
/kanban-orchestrator技能加载完,它先问我两个问题:你的目标是什么,你有哪些可用的 Profile。第二个它自己跑hermes profile list就知道了。我说“分析甲醇”,它吐出一张方案表:
| 任务 | 负责档案 | 内容 |
|---|---|---|
| T1 数据采集 | market_researcher | 跑 commodity_intel.py 获取 10 维数据 + 搜索补充供应链 |
| T2 技术面 | technical_analyst | MA 均线 / 支撑阻力 / 量价 / 形态 / MACD-RSI |
| T3 多头逻辑 | bull_researcher | MTO 修复 / 伊朗风险 / 季节性 / 政策 / 估值 / 成本 |
| T4 空头逻辑 | bear_researcher | 产能过剩 / 需求疲软 / 煤炭塌陷 / 进口高位 / 宏观弱 |
| T5 风险评估 | risk_manager | 整合 T1+T3+T4,给最大回撤、风险事件、仓位建议 |
| T6 投资结论 | chief_investment_officer | 综合所有人,给方向 / 入场 / 止损 / 时间维度 |
这张图不是模板,是kanban-orchestrator根据“分析一支期货品种”的语义现场拆出来的。换成“分析腾讯股票”,它会给出不同的任务图。
4.3 批量创建任务并观察调度
确认方案后,批量创建 6 个任务(命令见 3.3 节)。创建完跑hermes kanban list:
● t_be63214a running market_researcher data: 甲醇(MA)全维度数据采集 ● t_f0afecfd running technical_analyst tech: 甲醇(MA)技术面分析 ● t_e3fef572 running bull_researcher bull: 甲醇(MA)多头逻辑分析 ▶ t_4d675132 ready bear_researcher bear: 甲醇(MA)空头逻辑分析 ◻ t_671e0b13 todo risk_manager risk: 甲醇(MA)风险评估 ◻ t_369bddb9 todo chief_investment_officer cio: 甲醇(MA)投资结论与操作建议三个 worker 同时在跑。bear 在 ready 队列里排队,因为本机并发 worker 上限是 3。T5/T6 在 todo,它们的 parent 还没全 done。
点开一个看正在干什么:
hermes kanban show t_be63214a输出:
Task t_be63214a: data: 甲醇(MA)全维度数据采集 status: running assignee: market_researcher workspace: scratch @ /Users/xxx/.hermes/kanban/workspaces/t_be63214a skills: commodity-supply-chain-intelligence started: 2026-06-10 17:03 Events (8): [17:03] created {assignee: market_researcher, status: ready, ...} [17:03] [run 1] claimed {lock: bogon:977, expires: 1781083105, run_id: 1} [17:03] tip_scratch_workspace {message: scratch workspaces are ephemeral} [17:03] [run 1] spawned {pid: 7010} [17:03] [run 1] heartbeat [17:04] [run 1] heartbeat [17:05] [run 1] heartbeat [17:06] [run 1] heartbeat每个 worker 在~/.hermes/kanban/workspaces/<task_id>/里有独立的临时工作目录(scratch),互相看不见。每分钟一次 heartbeat 是 worker 给 dispatcher 报“我还活着”的信号。如果连续几个心跳缺席,dispatcher 会认为 worker 挂了,自动 reclaim 锁,让任务重新进入 ready 队列。
4.4 第一份产出:数据采集完成
用hermes kanban tail t_be63214a监听事件流,等了 6 分钟,第一行 completed 出现:
[17:09] completed { result_len: 0, summary: '甲醇(MA)全维度数据采集完成。 通过 akshare 获取 6 个合约报价(BACKWARDATION 结构, MA2609 主力 2972)、 2776 行主力连续日线(2026 年内 +34.18%)、 15 日 OHLCV 详情、 技术指标(MA5/10/20 多头排列, MA60=2992 压力)、 仓单数据(仅 2920 手历史低位)。 通过搜索获取关键新闻: 伊朗 7 套装置复产、 沿海库存 56.55 万吨(同比 -16.96%)、 MTO 开工率 80.1%(环比 -6.6%)。 所有原始数据汇总输出到 ma_comprehensive_data.txt。' }这一行 summary 信息密度极高。拆一下:期限结构 BACKWARDATION(近月升水远月),现货紧张,多头友好;主力价格 MA2609 = 2972 元/吨;年内涨幅 +34.18%,已经在牛市中段;均线系统 MA5/10/20 多头排列,MA60=2992 是压力;仓单 2920 手历史低位,现货不愿交割;供应端伊朗 7 套装置复产,3-4 周后进口冲击;库存沿海 56.55 万吨,同比 -16.96%,显著去库;需求 MTO 开工率 80.1%,环比 -6.6%,主力下游在走弱。
这是一个矛盾的画面:价格强、库存低、仓单低、伊朗要来、MTO 要走弱。多头有现货支撑,空头有进口预期 + 需求转弱。但market_researcher不下结论,它的角色定义就是只采集,不判断。
T1 done 之后,dispatcher 自动检查:T2/T3/T4 不依赖 T1,已经在自己跑;T5 依赖 T1/T3/T4,等 T3/T4 也 done 才能 ready;T6 依赖全部,最远的等待者。
4.5 全部完成:CIO 交出报告
再跑一次hermes kanban list:
✓ t_be63214a done market_researcher data ✓ t_f0afecfd done technical_analyst tech ✓ t_e3fef572 done bull_researcher bull ✓ t_4d675132 done bear_researcher bear ✓ t_671e0b13 done risk_manager risk ✓ t_369bddb9 done chief_investment_officer cio全部 done。整个流水线从点回车到 CIO 出报告,十来分钟——纯 Agent 跑的时间不到 10 分钟,加上确认拆解方案、回看任务状态的交互,凑够 10 分钟出头。下面是这份报告的关键骨架,是 CIO Profile 看完前面 5 个 Profile 的全部产出之后综合的。
基础数据:主力合约 MA2609 最新收盘 2972,2026 年内涨幅 +34.18%,合约结构 BACKWARDATION,港口库存华东 56.55 万吨(同比 -16.96%),注册仓单仅 2920 手(历史低位),MTO 开工率 80.1%(环比 -6.6%),关键供应伊朗 7 套装置复产。
技术面:短期信号偏多,均线 MA5 > MA10 > MA20 多头排列,MACD 金叉红柱放量,持仓持续增加,量价配合。中期风险 MA60 = 2992 压力,3000 整数关口,OBV 量价背离。结论:短期看多但需突破 MA60-3000 阻力区,否则反弹即是做空机会。
多空对决:多头强烈看多到 3200-3500-3800,核心逻辑伊朗地缘(占进口 40%)+ 近月升水 16% + 成本支撑 1800-2200。空头强烈看空到 2700-2750(极端 2450),核心逻辑产能 1.15 亿吨过剩 + 远月深贴 + MTO 检修叠甲醛淡季。两个 Profile 看到的是同一份原始数据,但走出了完全相反的方向。
风险评估:多头评分 19/30,空头评分 23/30,整体风险等级高危。风控核心结论:伊朗地缘是单一主导变量——若霍尔木兹海峡封锁,甲醇暴涨,空头逻辑瞬间作废;若局势正常,偏空格局不变。建议控制仓位:做多 ≤10%,做空 ≤5%,对冲 ≤20%。
CIO 最终裁决:偏空,置信度 60/100。操作策略:逢高做空,入场区间 2980-3020(等反弹入场,不追空),第一目标 2860,第二目标 2790-2800,硬止损 3100,仓位 ≤5%(伊朗尾部风险限制)。时间维度:短期 1-2 周震荡偏空,中期 1-3 月 MTO 检修 + 甲醛淡季累库,长期 6 月+ 金九银十 + 秋检 + 伊朗冬季限气可能反弹。
关键观测清单:伊朗地缘(霍尔木兹海峡 / 制裁新闻,最大单一变量);MTO 开工率(跌破 75% 确认需求塌陷,回升 85%+ 利空减弱);港口库存(华东突破 70 万吨则确认累库);仓单(从 2920 低位回升 = 交割压力增大);煤炭(跌破 700 元/吨则成本支撑进一步削弱)。
这份报告的含金量在三个细节。第一,置信度 60/100 这个数字很难写——CIO 看到空头 23/30 比多头 19/30 占优,优势存在但不悬殊,所以给出 60 分置信度,并明确写仓位 ≤5% 来匹配不确定性。第二,“反弹做空、不追空”这一笔很贵——需要同时持有“中期偏空”和“短期偏多”两个看似矛盾的信号,综合成一个具体动作。第三,关键观测清单是真正可执行的,5 个有具体阈值的指标,每周扫一眼就知道判断要不要更新。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
多角色流水线跑起来之后,最容易出问题的不是业务逻辑,是接入和调度环节。这一节把几个高频报错和排查方法列出来,你遇到时对照着查。
5.1 401 Unauthorized:API Key 没生效
最常见的报错。worker 启动后调模型返回 401,事件流里能看到类似:
[run 1] error { code: 401, message: "Unauthorized" }排查顺序:先确认TAOTOKEN_API_KEY环境变量在当前 shell 里能打印出来。echo $TAOTOKEN_API_KEY如果为空,说明环境变量没设或者没 source。注意 Hermes 的 gateway 进程和你的交互 shell 可能是不同的环境,gateway 启动时如果没继承到环境变量,worker 就拿不到 Key。
解决办法有两个。一是把 Key 直接写进每个 Profile 的config.yaml,不用环境变量:
model: api_key: "sk-你的实际Key"二是确保 gateway 启动前环境变量已经 export,或者用 systemd / launchd 托管时在服务配置里显式声明环境变量。我推荐第一种,虽然每个 Profile 都要填,但排查起来最直接。
还有一种 401 是 Key 本身失效或额度用完。去控制台https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite确认 Key 状态和余额。
5.2 local proxy failed:网络层问题
报错形态:
[run 1] error { message: "local proxy failed: connection refused" }这个报错通常是本机网络配置问题。先确认https://taotoken.net/api能不能直接 curl 通(用 2.3 节的命令测)。如果 curl 通但 Hermes 报 proxy failed,检查 shell 里有没有设置HTTP_PROXY/HTTPS_PROXY环境变量指向一个不存在的本地端口。Hermes 会继承这些变量,如果代理没开就会 connection refused。
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY清掉之后重启 gateway 再试。另外确认本机 DNS 能解析taotoken.net,nslookup taotoken.net看一下。
5.3 reading choices:响应格式解析失败
报错形态:
[run 1] error { message: "error reading choices: unexpected response format" }这个报错说明模型返回的 JSON 结构不符合预期,Hermes 在解析choices字段时失败了。常见原因有三个。一是model_id填错了,TaoToken 那边找不到对应模型,返回了一个错误结构。去控制台确认模型标识拼写正确。二是base_url多写了路径,比如填成了https://taotoken.net/api/v1,而 Hermes 自己会拼/v1/chat/completions,导致最终 URL 变成/api/v1/v1/chat/completions。正确填https://taotoken.net/api就行。三是响应被中间层截断,比如max_tokens设太小导致返回不完整。
排查方法:在 worker 的日志里找原始响应体,hermes kanban log <task_id>能看到。如果原始响应是 HTML 而不是 JSON,说明请求打到了错误的端点。
5.4 OAuth 相关报错:认证流程问题
报错形态:
[run 1] error { message: "OAuth token expired or invalid" }如果你用的是需要 OAuth 的模型提供方,token 过期会报这个。TaoToken 的接入用的是 API Key 模式,正常不会触发 OAuth。如果你在 Profile 里混用了其他提供方的 OAuth 配置,检查config.yaml里有没有残留的oauth字段,清掉。
还有一种情况是 Hermes 本身的会话认证过期。跑hermes auth status看一下,需要重新登录就hermes auth login。
5.5 worker 卡死无心跳:reclaim 机制
如果任务一直 running 但事件流里 heartbeat 停了,说明 worker 卡死了。dispatcher 会在几个心跳周期后自动 reclaim,让任务重新进 ready 队列。你可以手动触发:
hermes kanban reclaim <task_id>然后确认max_runtime设得合理。我建任务时都设了 15-30 分钟,如果某个 worker 卡死,最多浪费 30 分钟,不会无限挂着。这套调度从设计上就预设了 worker 会挂,这是分布式系统该有的姿态。
5.6 依赖不满足导致任务一直 todo
如果 T5 一直 todo,说明它的某个 parent 没 done。跑hermes kanban show <task_id>看parents字段,逐个确认 parent 状态。常见原因是某个 parent 任务失败后没有重试,或者 parent 的task_id写错了。检查创建任务时的--parent参数,确保引用的是真实存在的 task_id。
排查完这些,你的流水线应该能稳定跑通。下面把整套系统用到的三份清单收个尾。
6. 三份清单与后续扩展:把投研流水线跑成常态
这套智能投研落到地上就是三份东西。前面配置部分已经零散给过,这里集中列一遍,方便你对照检查。
6.1 Profile 清单(7 个角色)
| Profile | 模型 | 职责定位 | 在流程中的角色 |
|---|---|---|---|
| default | deepseek-v4-flash | 我自己的对话入口,负责接需求、调度、收报告 | 接“分析甲醇”、跑 kanban-orchestrator、查任务 |
| chief_investment_officer | deepseek-v4-flash | 综合所有专家产出,给方向 / 仓位 / 时间维度 / 观测清单 | T6(最终裁决) |
| market_researcher | deepseek-v4-flash | 只采集,不判断——10 维数据 + 搜索补充 | T1(数据采集) |
| technical_analyst | deepseek-v4-flash | 技术面专精——均线 / 支撑阻力 / 形态 / 量价 / MACD-RSI | T2(技术分析) |
| bull_researcher | deepseek-v4-flash | 只看多——把多头逻辑挖到见底 | T3(多头逻辑) |
| bear_researcher | deepseek-v4-flash | 只看空——镜像版本的 bull_researcher | T4(空头逻辑) |
| risk_manager | deepseek-v4-flash | 不站队——做最大回撤、风险事件、仓位建议 | T5(风险评估) |
| memory_reflector | deepseek-v4-flash | 跨次复盘 / 教训沉淀 | 本次未触发,留作后续跑批用 |
关键设计:market_researcher和risk_manager都是不站队角色,前者只给数据、后者只算风险。多头空头的活留给bull_researcher/bear_researcher在隔离环境下各挖各的。
6.2 Skill 清单(2 个技能)
| Skill | 分类 | 给谁用 | 内容 |
|---|---|---|---|
| kanban-orchestrator | devops | default | 总调度技能。把“分析甲醇”这种模糊指令拆成 Kanban 任务图 + 依赖关系,自动 spawn 到对应 Profile |
| commodity-supply-chain-intelligence | data-science | market_researcher | 商品供应链情报包:含 commodity_intel.py(akshare + 搜索数据采集脚本)+ references/methanol-ma-fundamentals.md(甲醇基本面知识库) |
关键设计:Skill 在创建任务时通过--skill <name>显式注入,worker 启动时这个 Skill 出现在skills_list的 Level 0 目录里,Agent 会主动skill_view进去看。其他几个角色没注入 Skill,它们靠自己 Profile 的SOUL.md和memories/MEMORY.md工作就够了。
6.3 命令清单(10 条)
| 用途 | 命令 |
|---|---|
| 列出所有 Profile 状态 | hermes profile list |
| 启动调度网关(dispatcher 跑这里) | hermes gateway start |
| 加载总调度技能 | /kanban-orchestrator(在 Hermes 会话内) |
| 创建任务 | hermes kanban create "标题" --assignee <profile> [--skill <skill>] [--parent <task_id>] --max-runtime 30m |
| 列出所有任务 | hermes kanban list |
| 查看任务详情 + 事件流 | hermes kanban show <task_id> |
| 实时跟踪事件流 | hermes kanban tail <task_id> |
| 查看 worker 日志 | hermes kanban log <task_id> |
| 看可用 Profile + 任务计数 | hermes kanban assignees |
| Worker 看自己的完整上下文 | hermes kanban context <task_id> |
整套流程跑下来,人工敲命令的次数 = 6 条 create + 几次 list/show 查状态,不到 10 个动作。
6.4 后续扩展方向
这套系统还能继续进化。第一个方向是股票智能投研:7 个 Profile 的角色框架(CIO / 多空 / 技术 / 风控 / 数据 / 反思)几乎不用动,换掉数据采集 Skill(A 股要接 Tushare / 同花顺数据源),重写部分SOUL.md(股票要看财报、估值、行业景气度),整套 pipeline 直接复用。
第二个方向是主动推送:用 Hermes 的 cron 特性定时跑——每天盘前推一份昨日异动品种的快报,每周末推一份持仓品种的全维度更新。AI 自己判断哪些值得提醒,结论直接推到手机的 IM 上。从“我问 AI 投研”变成“AI 自己判断要不要找我”。
第三个方向是多品种泛化验证:目前只在甲醇上跑通了端到端,PTA / 沥青 / 燃料油这些化工品适不适用还要再试。等多跑几个品种,迁移成本和踩坑经验会更有参考价值。
如果你也在用 Hermes,照着 6 个特性 + 三份清单的样子,自己搭一个验证版完全够。剩下的内部填充交给你自己的领域知识就好。模型接入层用 TaoToken 统一管理,7 个 Profile 共用一份 Key,切换模型只改 Model ID,这套配置在扩展新角色时特别省事。