Repository navigation
Releases: agentpit-io/huntercode-atomcode
Release list
v0.2.1(预发布)· 性能收尾
v0.2.1(预发布)· 性能收尾
在 v0.2.0 基础上的收尾版。改动很小:
只有人设与项目指令两个文件(distro/personas/hunter-research.md、
distro/workspace-template/.atomcode.md),把 v0.2.0 里因为护栏而回退掉的
「按结构卡控制篇幅」改对之后加了回来。代码、镜像、二进制、MCP 清单、hook
一个都没动。
先把没达到的说清楚:用户给的验收口径是「每道题的墙钟中位数 ≤ 社区版 ×1.05」
做到 5/5、D 维度 ≥ 24/25。实测 1/5、D 22.2,没达到。
逐题还差多少、差在哪、要再快得付什么代价,全部写在
docs/开发文档/I3-性能收尾报告.md §5。
tag 指向哪个提交:
v0.2.1=dbaa80d。它之后还有一个纯文档提交
(06f3778,两台部署的升级记录与真浏览器截图)—— 按红线「禁止 --force」,
tag 不动。代码、镜像、人设、模板在两个提交之间一个字都没有变。
升级
bash deploy/install.sh --upgrade --ref v0.2.1COPY 进镜像的
(正式部署不挂宿主目录),所以仍然要重建。
这一版改了什么
「按结构卡」改对了
v0.2.0 的报告 §2.9.4 里记着一次按护栏回退:那一版结构卡把答案压短了,
但同时砍掉了内容 —— q2 把用户的持仓(2 000 股 / 38.50 元 / 2026-01-20)整段删了、
q4 把末尾那段必须原样附上的「AI 生成标识与风险提示」当成「额外段落」删了。
A 掉 1.6 分,超过护栏(1 分),所以整项退回。
这一版按三条改对:
- 题面明确要求的内容不在可砍范围。 原来写的是「数据表只列题面点名要的指标」
—— 这是包含式白名单,模型把「持仓」读成了不在名单里。
现在写的是「题面点名要的指标一项都不能少(用户报了持仓数量 / 成本价 /
买入日期这类,就是点名要了)」。 - 风险提示段不算多余段落。 卡里单独给它一行「必须原样附上,不算额外段,
也不计入字数上限」,并在「不写额外段」那一行末尾再钉一句「不包括上面那段风险提示」。 - 篇幅控制只作用于铺陈与重复解释。 卡的开头先写清卡什么、不卡什么;
并把原来卡内容条数的规则整个删掉(判断依据「最多 4 条」、风险项「最多 3 条」
改成「每条 ≤ 1 句、条数不限」)。
实测效果(专用评测机,每题 12 遍,与 v0.2.0 同一套题同一套口径)
| 题 | 正文字数 | 出字耗时 | 整轮墙钟 |
|---|---|---|---|
| q1 单股基本面 | 1 578 → 1 360 | 4 273 → 2 832 ms | 15 537 → 15 677 ms |
| q2 持仓论点复核 | 1 564 → 1 489 | 4 158 → 3 170 ms | 19 128 → 18 567 ms |
| q3 因子筛选 | 1 372 → 1 262 | 3 972 → 2 902 ms | 13 328 → 12 064 ms |
| q4 Kronos 预测 | 611 → 546 | 2 028 → 1 300 ms | 7 208 → 6 390 ms |
| q5 情报汇总 | 1 461 → 1 477 | 3 092 → 2 618 ms | 16 322 → 15 828 ms |
(左边是同一天、同一台机器上用 v0.2.0 那版人设重测的对照档,不是 v0.2.0 报告里的数 —— 为什么,见下。)
出字五题全部下降;整轮墙钟四题下降、q1 基本持平。
护栏(全量逐次核,不是抽样):
- q2 那三项持仓数据里,成本价 38.50 元 12/12 次都在(v0.2.0 回退的那版坏卡是 2/4);
- 末尾的 AI 生成标识与风险提示 59/60(对照档 58/60,缺的那一次两档都有,是模型自身波动);
- 人工评分 A 25.0 / C 25.0,与 v0.2.0 持平,一分没掉。
⚠️ 一条比上面所有数字都重要的提醒:性能数字跨天不可比
这一轮为了判断「结构卡是不是把速度弄坏了」,把 v0.2.0 那一版配置在同一台机器上
原样重跑了一遍(另放一份仓库副本,除那两个文件外逐字节相同,md5 当场核过)。
结果:同一份配置,v0.2.0 报告记的是 D 23.2 / 逐题达标 2 的 5,今天重测只有
D 21.8 / 1 的 5。配置一个字没改。而社区版那一侧没有跟着一起慢 ——
也就是漂的不是整个网关,是 HCA 这种大请求在不同时段拿到的服务质量。
所以:
- 请不要把 v0.2.1 的数字和 v0.2.0 报告里的数字相减来判断「变好了还是变差了」;
- 要比就在同一个批次里比两侧(本版所有比较都是这么做的);
- 本版的评测因此改成每档拆两段跑、两档交错,每题 12 遍而不是 6 遍
(6 遍时 q3 一度量到 1.51,12 遍是 1.19 —— 差别全是抽样)。
这条已经写进 docs/对比-opencode版.md、docs/eval/summary.json 与待办池 U-19。
顺带答掉的一个问题:工具 schema 到底吃多少时间(待办池 U-20)
v0.2.0 的报告只能说「请求小了 685 ms」,因为那次把提示正文和工具 schema 一起摘了。
本版单独打了五臂探针(人设一个字不动,只动工具清单;每臂 26 次):
| 挂了多少工具 | schema 字节 | 上游首字中位 |
|---|---|---|
| 上游全量 62 个 | 62 732 | 3 799 ms |
| 本发行版默认 39 个 | 39 642 | 3 576 ms |
| 只留某类场景要的 5 个 | 9 475 | 3 229 ms |
| 全关 | 1 944 | 3 223 ms |
约 10.0 毫秒 / 千字节(R² 0.99)。作为对照,只改提示正文那一格是
6.0 毫秒 / 千字节 —— 同一量级。所以准确的说法是「吃时间的是请求大小本身」,
而不是 v0.2.0 猜的「吃时间的是 schema 不是正文」。
这条对运维的意义:如果你的部署只跑某一类固定场景,把 HCA_TOOLS_ALLOW
收成那几个工具,每轮模型约省 350 毫秒。用法与三条要先知道的警告
(尤其「这一档没做过端到端 A/C 评测」)写在 docs/部署与运维.md
「工具 schema 有多贵」一节。
按会话 / 按技能动态收白名单本发行版做不到,需要改内核 —— 已排进待办池 U-23,
本版没做。
已知问题
- 逐题墙钟没做到 5/5:q3 1.19 / q4 1.35 / q5 1.38 倍(q1 0.51 ✅、
q2 见下)。再快就要砍掉题面要的数据点或合规段落,不做。逐题的代价分析见
I3 报告 §5。 - q2 这道题的比值取决于对照组:社区版在这道题上 23 次里只有 5 次真去读了
论点文件,其余直接回「你没存买入理由」就结束。原样口径 1.98、
只看「两边都真做题」的那些次是 0.59。两套数都在报告 §4.3 里。 - P0-10 仍然开着(
/live/switch_session之后 MCP 工具可能消失而
/mcp/status仍报 connected)。升级之后第一轮如果失败,重发一次即可 ——
处置写在docs/部署与运维.md§4.2。 - 结构卡改对版在 q2 的「买入日期」上有残余压缩(3/12,对照档 7/12)。
不影响评分(成本价 12/12),但确实少写了,记在待办池 P2-22。
两台部署都已升到本版并各验过一次
| 环境 | 状态 | 真浏览器 |
|---|---|---|
测试机 http://34.133.8.3:3200 |
六容器健康、MCP 10/10、binary_hash 2c2653b0… |
5/5(真实对话,评分 78、免责三句齐全) |
香港 http://34.92.73.207:3200 |
自检全过、MCP 10/10 | 5/5(评分 76、免责三句齐全) |
switch-to-fork.sh(如果你在跑 fork 变体):
升级会重建 daemon 基础镜像,fork 那一层是叠在它上面的,就旧了。
up.sh 会警告但不会自动重叠 —— 不补的表现是「代码更新了但模型行为没变」。
顺带修掉一个部署缺陷:新放进去的 key 容器读不到
这一轮在测试机上升级完,第一轮真实对话被网关回 401。
根因是 deploy/up.sh 的 harden_secrets 早退判据只看密钥目录、不看里面的文件:
目录之前 chgrp 过一次就直接返回,于是后来放进去的那把 key(带的是当前用户的组)
永远改不对组,daemon(uid 10001)读不到。
它不报错:up.sh 自检全绿、六个容器全 healthy —— 自检那一跳不需要模型 key。
已修 + 4 条单测。如果你之前换过 key 之后一直报「没有可用模型」或 401,升到本版再跑一次
bash deploy/up.sh 就会被自动纠正(日志里会打出是哪个文件)。
原始记录
docs/eval/i3/:四个评测批次共 240 次运行(每次三份记录:结构化 JSON +
SSE 原始流 + 上游请求追踪),外加 U-20 的五臂 × 每臂 26 次。
docs/eval/summary.json 是给 PPT 取数用的总表,每个数带出处,
并明写哪些数不能放在一起比。
v0.2.0(预发布)· 速度这一轮
v0.2.0(预发布)· 速度这一轮
在 v0.1.2 基础上的性能版。这一版做的是一件事:
把「同一道投研题,HCA 要跑几步、要等多久」压到与 opencode 版(社区版 1.2.0)同一个量级。
默认仍然装 AtomCode v5.1.0 官方二进制(pins.lock 双重 sha256,行为与上游完全一致),
但本版新增了可选的 fork 变体 —— 三个只在 config.toml 里露面的提速参数
(人设整体替换 / 工具挂载白名单 / 按族关工具),已向上游提 PR
(#1106)。
本轮的性能数字是在 fork 变体上测的;跑官方二进制能拿到其中一部分(见下面的对照)。
切换方式见 docs/部署与运维.md §6.3,一条环境变量的事,随时可回滚。
升级
bash deploy/install.sh --upgrade # 数据卷不动,升级前自动存回滚点想用 fork 变体(本轮性能数字对应的配置):
bash deploy/fork-image.sh /path/to/atomcode # 叠一层,自带 sha256 校验
# deploy/.env 里加三行
# HCA_DAEMON_VARIANT=-fork
# HCA_LLM_SYSTEM_PROMPT_FILE=/opt/hca/personas/hunter-research.md
# HCA_TOOLS_DENY=group:codeintel,group:atomgit,group:subagent,code_review,ast_grep,list_sessions,schedule_wakeup,recall,web_fetch,web_search,glob,grep,search_replace,open_file
bash deploy/up.sh --no-build # 用新镜像重建容器(不重新构建镜像)这一版做了什么
1. 组合工具(新 MCP hcapack)—— 步数下降的主因
一道投研题要的往往是「一整包」数据,而底层工具是一项一个。本版加了三个包:
| 问的是 | 调这个 | 一次带走 |
|---|---|---|
| 某只票基本面 | mcp__hcapack__stock_snapshot |
最新价与取数时刻、营收与归母净利同比、毛利率、ROE、资产负债率 |
| 最近有什么消息(可多只票) | mcp__hcapack__stocks_intel |
每只票的公告 + 新闻(都带来源与日期)+ 一手信号简报 |
| 复核我的论点 | mcp__hcapack__thesis_evidence |
论点原文 + 持仓账本 + 行情 + 财务 + 分红 + 近期公告与新闻 |
包里的子请求是并行发的,而且「没有公告」与「取不到公告」在返回里是分开的两种
—— 后者是 {"error": …},前者是 []。这个区分不是洁癖:混成一个,模型看到
「取不到」就会再换个工具找一遍,那正是要消掉的步数。
2. 八个性能开关(默认值就是实测最快的那一组)
HCA_LLM_TOOL_DENY(shim 层摘工具 schema)、ATOMCODE_AI_SESSION_NAMING=0
(上游每轮结束会再发一次模型请求给会话起名,实测 3 817 ms)、HCA_HOOKD=1
(hook 常驻服务:每次工具调用 966 → 51 ms,每条提问 292 → 34 ms)、
HCA_MCP_DISABLE、HCA_CTX_CAPABILITIES=1(把「本部署没配 Kronos key」这件事
直接注入上下文,省掉一次「调一次工具拿到报错才知道拿不到」的整轮模型)等。
逐条说明与「想恢复上游行为改成什么」在 docs/部署与运维.md §6.3。
3. 人设里两条与速度直接相关的纪律
- 篇幅:一般问题 900 字以内、逐条复核类 1 300 字以内。
依据是实测出字速度 2.3 毫秒一个字 —— 多写一千字,用户多等 2.3 秒。
这一条明写了不许用来偷工:结论、每个数字的出处、风险项、取不到的东西、
以及合规要求的那段 AI 生成标识,少一样都是错的。 - 路标:只有这一轮要发 2 次以上工具调用时才发,最多 12 字。
实测收益:不发路标时第一个工具调用提前 0.26~0.62 秒(四道题里三道如此,
q2 反着来 +0.63 秒)。单次取数的问题从此少一行「正在查…」,
换来的是直接出答案 —— 这是一处产品取舍,写在这里。
4. fork 变体:三个 config.toml 参数
| 参数 | 不配置时 |
|---|---|
system_prompt_file |
上游已有这个字段但从来没被读到过;补丁把它接上,整个文件的内容替换内置编码人设 |
[tools] allow / deny |
两个列表都空 = 挂载名单与上游逐字相同 |
「不配置时与上游完全一致」是比出来的:tools/probe/fork_verify.py 用 stub provider
拿官方 5.1.0 与补丁版各跑一遍 headless —— 系统提示 27 397 字符逐字节相同、
工具清单相同;配上参数后 12 067 字符、工具 33 → 20。
实测结果
评测机(8 核专用、只跑这件事)、M2 那 5 道投研题、两边同一套 api 与同一份持仓账本、
A/B 交错且每遍换先手、每题 6 遍(偶数 —— 两边共用同一个 api 的行内缓存,
奇数遍时先手按 2:1 分给两边会白送对照组半秒)。
原始记录:docs/eval/i2/opt3-fork-b/(每次运行的 SSE、上游请求追踪、逐次计时全留)。
| 题 | HCA 调用 | 社区版调用 | HCA 墙钟 | 社区版墙钟 | 墙钟比 |
|---|---|---|---|---|---|
| q1 单股基本面 | 1 | 2 | 16.2 s | 32.9 s | 0.49 |
| q2 持仓论点复核 | 1 | 4.5 | 20.0 s | 27.4 s | 0.73 |
| q3 因子筛选 | 1 | 1 | 12.9 s | 10.0 s | 1.29 |
| q4 Kronos 预测 | 0 | 0 | 5.9 s | 4.7 s | 1.26 |
| q5 情报汇总 | 1 | 3 | 17.1 s | 11.9 s | 1.44 |
| 维度(M2 评分表) | I2 之前 | 现在 |
|---|---|---|
| D 步数与耗时 / 25 | 12.3 | 23.2 |
| A 准确性 / 25 | 24.2 | 25.0 |
| C 输出规范 / 25 | 25.0 | 25.0 |
| 单次 token 中位 | 71 601 | 47 124(社区版 32 939) |
一句话:工具调用次数五道题全部不高于社区版(从 14 / 15 / 1 / 1 / 16 次降到
1 / 1 / 1 / 0 / 1 次);墙钟两快三慢 —— 要一整包数据的题快一倍,
只取一项、答案又短的题还慢 26%~44%。
慢的那三道,差在哪是量出来的:q4 上 HCA 的模型那一段比社区版还快 475 ms,
1.2 秒的差全部来自「HCA 写了 652 字、社区版写了 115 字」(出字实测 2.3 ms/字)。
q3 的差里出字占 71%。逐题的剩余差距与下一步写在报告 §4.6。
没达到的那条也写在这里:用户给这一轮的口径是「每题墙钟 ≤ 社区版 × 1.05 且
D ≥ 24」,实测 D 23.2、逐题达标 2/5。
没做到 / 没测到的
- q3 / q4 / q5 的墙钟仍未达到「≤ 社区版 × 1.05」(1.29 / 1.26 / 1.44 倍),
逐题的剩余差距来源与下一步写在报告 §4.6。 - 有一项优化做了之后按护栏回退了(§2.9.4「按结构卡」):它把字数又压下去 10%~20%,
但把内容也砍掉了 —— q2 丢了「用到真实持仓数据」那个要点(A 掉 1.6 分 > 护栏 1 分)、
q4 把合规要求的 AI 生成标识段当成「额外段落」删了。数据留在
docs/eval/i2/opt4-fork-b/当依据,怎么改对写在报告 §2.9.4。 - 主部署上「优先用组合工具」只跑了一次,而那一次没走组合工具(7 次调用)——
评测机上是 6/6 都走。样本太少,记为待查(待办池 U-22)。这一条直接关系到
上面那些数字对真实用户意味着什么,所以摆在这里。 - fork 二进制只编了 linux-x64;其余平台
pins.lock里照旧是官方值并标verified = false。 [tools] allow(白名单方向)有实现有单测,端到端没用过 —— 本轮只用了deny。- 人工 A/C 评分只打到每题第 1 轮(口径与理由见报告 §4.2)。
升级之后第一轮可能失败,重发一次即可
重建 daemon 容器(不动 web)之后,BFF 那条 /live 长连接还指着旧进程 ——
与重建赛跑的那一轮里模型手里可能一个 MCP 工具都没有,表现是它改用
bash / read_file 在工作区里乱翻、撞满 30 轮上限,最后 HTTP 502、正文 0 字。
下一轮就正常。 想彻底避开:升级后顺手 docker compose -p hca restart web。
根因是已知缺陷 P0-10(/mcp/status 全绿而模型手里是空的),
详情与实测记录在 docs/开发文档/待办池.md。
兼容性与回滚
- 数据卷、账本、会话文件格式都没动;从 v0.1.x 直接升级。
- 八个性能开关全部可以改回上游行为(
docs/部署与运维.md§6.3 每行都写了「恢复上游行为」)。 - fork 变体:
HCA_DAEMON_VARIANT改回空、重起 daemon 就退回官方二进制。
v0.1.2(预发布)· 一个补丁:重启 daemon 后模型看不见数据源
v0.1.2(预发布)· 一个补丁
只比 v0.1.1 多一处修复。底座不变:AtomCode v5.1.0 官方二进制
(sha256 40d86fa3…,pins.lock 双重校验,没有 fork)。
为什么会有这个版本:v0.1.1 的 tag 打得早了一点 —— 下面这个修复是在
打完 tag 之后、做发布前最后一次端到端冒烟时才撞出来并修掉的。
既然 tag 已经推出去了就不动它(不--force),改用一个补丁版发出来。
这是发布流程上的一处失误,记在docs/开发文档/M5-成果与测试报告.md§9。
修了什么
重启过 daemon 之后,模型会"看不见数据源"(P0-10 的第一个可复现触发条件)
这个问题从 M1 追到 M4,一直只能事后从工具序列认(M4 的受控复现明确写着「没能复现」)。
这一版找到并堵上了其中一条可以稳定复现的路:
docker compose restart daemon而不重启 web,之后每一轮
/mcp/status都是 9/9,而模型手里一个mcp__*都没有。
同一个问题(「600519 现在什么价」)连着两轮的实测:
| 用了什么工具 | 墙钟 | 网关配额差值 | |
|---|---|---|---|
| 第 1 次 | read_file, read_file |
567.2 s | 261 926 |
| 第 2 次 | web_search, read_file, read_file |
305.1 s | 953 319 |
restart web 之后 |
watchlist_stock_quickview |
403.6 s | 801 352 |
两次都答出了东西,所以从界面上看不出坏了 —— 只是数据不来自 MCP、
慢了一个量级、而且贵了 3~4 倍。这正是这一族问题最难受的地方。
原因:BFF 维持着一条到 daemon 的 /live 长连接。daemon 换进程之后,
这条连接指向的 runtime 已经不是那个挂好了 9 个 MCP 的了;
而 /mcp/status 查的是新进程的状态 —— 于是状态面板全绿,模型手里却是空的。
修法:daemon 的 GET /health 每个进程返回不同的 instance_id,
BFF 在绑定前比一次,变了就丢掉旧绑定重连(新进程的 runtime 是干净的,不需要重挂 MCP)。
取不到 instance_id 一律按「不知道」处理 —— 不会因为 /health 一次超时就掐掉好好的连接。
故障注入验过两次:重启 daemon 之后下一轮分别用了 1 次与 5 次 MCP 工具、
47.8 s 与 70.2 s 拿到真实数据;BFF 日志里能看到
daemon 换了进程(instance_id 变了)—— 丢掉旧的 /live 绑定重连。
证据:docs/evidence/M5/p0-10-可复现触发条件与修复复验.txt。
这不等于 P0-10 关闭了:4 小时浸泡里那一次发生在任何重启之前,说明还有别的路。
根治仍要上游给「当前 runtime 实际挂载的工具清单」这个可观测量
(已提给上游,见docs/questions-for-atomgit.mdB12)。
升级
bash deploy/install.sh --upgrade --ref v0.1.2会重建 web 镜像(改动在 BFF),2 核机器上大约十几分钟,期间服务不可用。
daemon 镜像没变,数据卷不动。
其余
v0.1.1 的全部内容照旧,见 发布说明-v0.1.1.md。
已知缺陷清单也在那份里,这一版没有减少任何一条(P0-10 只是堵上了一条路)。
v0.1.1(预发布)· 缺陷修复
v0.1.1(预发布)· HunterCode · AtomCode 发行版
在 v0.1.0 基础上的缺陷修复版。底座不变:
AtomCode v5.1.0 官方二进制(sha256 40d86fa3…,pins.lock 双重校验,没有 fork)。
安装 / 升级 / 回滚的用法与 v0.1.0 完全一样。
从零装:
curl -fsSLO https://raw.githubusercontent.com/agentpit-io/huntercode-atomcode/v0.1.1/deploy/install.sh
bash install.sh已经装了 v0.1.0 的:
bash deploy/install.sh --upgrade # 数据卷不动,升级前自动存回滚点
2 核机器上大约要十几分钟,期间服务不可用。
这一版修了什么
1. MCP 返回被砍成半截 JSON(P0-11 · 影响判断质量,最要紧的一条)
AtomCode 内核对超过 16 KB 的工具返回会砍成「头 4096 字节 + 尾 4094 字节」,
中间整段对模型不可见,而且剩下的 JSON 语法是断的
(output_artifact.rs:79/82,两个常量都是 const,全树没有任何配置项能改)。
M2 评测里实测过后果:一次运行 5 次 akshare_call 有 4 次被截断,模型没去调 fetch_output,
写出的财务复核里有三个数在任何一份工具返回里都搜不到,却都标了工具来源。
v0.1.1 在我们自己的 MCP 层先把返回压到阈值以下,关键不只是变小,而是
留一份结构完整的 JSON:
akshare_call加了字节预算(AKSHARE_MAX_BYTES,默认 15000)与列投影
(新参数columns)。只限行数压不住宽表 —— 财务指标接口一行就有八十几列。- 6 个 hunter 系 MCP 走统一的大小闸,超预算时裁成
合法 JSON + 一个 _hca_size_guard 块,明说「共 M 条、这里只给了 N 条、
剩下的是被裁掉的不是不存在」。 truesource与kronos也补上了。这两个跑在另一个 venv 里、
import 不到那份闸,一开始漏掉了 —— 而容器里真实调用
truesource_procurement(days=30)返回 18 084 字节,本来就在被内核砍。
修完同一接口复调 14 099 字节,带明确裁剪说明。akshare_call还补了单元格级裁剪:只限行数压不住长文本
(公告 / 研报正文那类接口一行里某一列就有几万字,容器实测单行 90 168 字节)。- 工作区指令里写死了三种截断各自怎么处理,以及一条硬规矩:
被裁掉那段里的数字不许出现在回答里,更不许标上工具来源。
模型看得懂"少了多少、为什么少、怎么拿全",就不需要拿记忆去补。
内核那一侧的问题没有根治(要上游给配置项),已提给上游。
1b. guard hook 的 bash 判据改成白名单(安全,升级后行为会变)
M4 堵的是内联命令。M5 复核时多问了一句「脚本不写在命令行里呢」,
一轮找出 12 条绕过,形态彼此毫无关系:
python3 reports/x.py sh notes/x.sh cat x.py | python3
echo <b64> | base64 -d | sh echo <b64> | base64 -d | python3
find . -exec python3 {} ; awk 'BEGIN{system(…)}' . reports/x.sh
source reports/x.sh eval "$(cat x.sh)" perl -e 'system(…)'
node reports/x.js ./reports/x.py
而 write_file 本来就允许往 reports/ 与 theses/ 写,所以随便哪一条漏网,
接起来就是完整绕过:先把 import akshare; … 写进 reports/fetch.py,再执行它 ——
取到的数不进 MCP 层,拿不到用户身份、不进审计、富卡片退化成通用卡。
问题不在「这次漏了几条」,而在 denylist 永远只覆盖已经想到的那些。
所以 bash 首词改成白名单(BASH_ALLOW):只收不会写文件、不会联网、
不会执行外部代码的只读工具;解释器只许 -c 内联 / -m 模块 / 问版本。
升级后会变的行为:以前能跑、现在会被拒的命令,报错信息里会写清楚原因和替代办法。
确实需要放开某个命令,改工作区里的 .hooks/guard.py 的 BASH_ALLOW 即可
(改完 docker compose -p hca restart daemon)。
代价是把真实命令重放一遍量出来的:部署中容器 guard.jsonl 里模型发出的 37 次 bash,
该拦的只有 12 条(4 次直接 import akshare、4 次跑 /opt/hca 下的 MCP 源码、
3 次内联发 HTTP、1 次 curl);另外 25 条是正当用途,其中 20 条是
python3 -c 读文件 / 解析 JSON / 算数 —— 白名单本来就放行 -c 内联代码,这些照样能用。
把其中 25 条原样喂给新 guard 重放,与「按意图该不该拦」不符的是 0 条。
换成白名单之后又复核了一轮,发现白名单只管住了"首词是谁"、管不住
"这个命令自己能干什么",于是补了两类(都已在这一版里):
- 自带输出文件参数的:
sort -o FILE、uniq 输入 输出、xxd 输入 输出、
tree -o、yq -i—— 不用>就写盘,写重定向那道闸完全看不见。
部署中的容器里sort与uniq都在,实测sort -o holdings/positions.json …
能把持仓账本整个覆盖。 - 带执行选项的:
rg --pre CMD会把每个输入文件交给CMD跑一遍
(容器里没装 rg,当前不可利用,但白名单随工作区模板走)。ack同类,已移出白名单。
反误伤也钉了用例:uniq -w 3 a.txt、xxd -l 100 a.bin、rg --json 这类照常放行。
1c. 顺手修掉两个一直存在的误伤(升级后原本会被拒的正当命令能用了)
把容器 guard.jsonl 里模型真实发出的 bash 原样重放一遍时撞出来的:
open(路径, 'r')被当成写文件。判据写的是[waxr]\+?,+可选,
于是只读的'r'也算写。python3 -c "with open('x.json','r') as f: ..."
这种正当的读文件算数被拒了 —— 而它正是白名单刻意要放行的用法。
这个误伤从 M2 就在,一直活到 v0.1.0。 现在只有w/a/x(可带b/t/+)
与r带+才算写,16 个模式逐个验过。2>/dev/null被当成写盘。丢弃输出不写任何文件,现在放行
(只限目标恰好是/dev/null;> /dev/nullx、2> reports/err.txt照样拒)。
2. 语言守卫补上了出口那一道(P1-21)
原社区版的语言守卫挂在 opencode 的 text.complete(出口)。AtomCode 的 8 个 hook
事件里没有「助手正文写完」这个点,所以 v0.1.0 只有提示词侧那一道。
v0.1.1 把出口那道补在转发层:回合结束、正文终态已定时逐段送校验,
改写用同 id 重发 part 事件,前端零改动。校验服务挂了一律放行原文
(守卫是保险,不是闸门)。
3. 两个事件的应答体写错了(P1-19)
对着上游的请求结构体逐字核过,查出 v0.1.0 里两处错:
policy_intervention的应答发的是{intervention_id, decision},而上游要的是
{intervention_id, action},action必填且是四选一 —— 少了它会直接 422,
介入永远解不掉。user_input_request的应答没带declined,默认值等于告诉模型
「用户回答了,内容是空的」,模型可能据此往下编。改成明确拒答。
这两个事件在本发行版的配置下发不出来(对应的工具都关着),所以之前没暴露;
现在的代码是防上游换实现的保险。
4. 两处数据质量小修
stock_news的date字段上游返回空串(30 条全空),现在按文章 URL 里的日期串补上,
并标明「从 URL 推断」——推不出来就留空,不编。- 深度分析技能正文里引用的
references/report-template.md原本不存在,模型照着找会扑空,
现在补上了。
5. 安装向导补上了两把数据 key(新装的人直接受益)
install.sh 以前从来不写 KRONOS_API_KEY 与 HUNTER_API_KEY —— 既没有参数也没有提问,
所以从零装出来这两把 key 必然是空的:Kronos 的 K 线预测与回测看板、truesource 类工具
永远出不来数,而安装过程中一句提示都没有。
v0.1.1 补了 --data-key-file / --kronos-key-file(以及不推荐的 --data-key / --kronos-key)
与交互提问。两把都可以直接回车跳过,跳过时明确告诉你会少哪块功能。
它们与模型通道分开计量,所以是两把独立的 key。
bash install.sh --non-interactive --yes \
--api-key-file /root/hca-key \
--data-key-file /root/hca-data-key \
--kronos-key-file /root/hca-kronos-key实测(全新安装、独立 compose 项目):两把 key 进了 0600 的 deploy/.env、容器里读得到、
ps 里没有任何明文;接上之后 kronos_health 从 {"error":"missing_api_key"}
变成 {"ok":true,"upstream":{"status":"ok",…}},网页里的 Kronos 预测报告
(结构标志 6/6、每日预测 6 行)也第一次拿到了真数据。
已经装了 v0.1.0 的:升级不会动你
.env里已有的值。
想补这两把 key,直接改deploy/.env再bash deploy/up.sh --no-build即可。
6. 两条「写了但跑不通」的取证命令
docs/开发者指南.md从 M4 起就写着bash tools/e2e/run.sh,而这个文件根本不存在。
现在它是真的了:一条命令跑完 MCP 冒烟 + 两套 Playwright + SSE 重连,一套失败不挡后面几套。- 浸泡报告生成器把机器写死成「测试服务器 34.133.8.3(2 核 8G)」。
报告换一台机器跑就会在第一行写一句假话,改成必填参数。
7. Ollama 通道在 Linux 上本来就装不上(三处,全修)
安装向导的三条通道里,本地 Ollama 这条从来没在真机上跑通过。v0.1.1 修掉三道门:
- compose 少了
extra_hosts: host.docker.internal:host-gateway——
文档从 M4 起就写着「已配」,而它一直没配。容器解析不出这个名字,
表现是网页能开、发消息没回答。 install.sh对 ollama 通道不再要求 key。以前非交互安装必须编一个假 key
才能过(用法里写着"可以给空文件",代码却拒绝空文件)。- key 校验不再在宿主上 curl
host.docker.internal—— 那个名字只有容器里能解析,
于是校验必然Could not resolve host、安装直接失败。现在校验改用宿主自己的地址
(先127.0.0.1,再退到 docker 网桥网关),并明确提示「容器里仍走 host.docker.internal」。
ollama serve 默认只监听 127.0.0.1,容器走 docker 网桥
(172.17.0.1)连不上。用 OLLAMA_HOST=172.17.0.1 ollama serve(不对公网),
或把 .env 里的 HCA_LLM_BASE_URL 直接填成宿主内网 IP。详见 docs/部署与运维.md §6。
实测(2 核 8G、qwen2.5:1.5b):走网页真发一条消息 203.9 秒 / 172 字。
能用,但 2 核上只够试跑;而且这么小的模型基本不理会「用中文回答」这类约束,
投研场景要挑带工具调用能力的更大模型。
8. 每日探活以前会把「模型通道整个断了」报成成功
tools/e2e/web_turn.py 判成功的条件曾经只有 HTTP == 200。
而 provider_error 这一路 HTTP 恰恰就是 200、终态照常收到、正文 0 字 ——
脚本打出「1 题,成功 1,失败 0」,一行报错都没有。
运维文档推荐用它做每日探活,所以这条判据坏了,那条建议就等于没有。
现在三条都要:HTTP 200 且 stop_reason 不是错误态 且 这一轮真有产出
(正文非空或调过工具)。失败时把 HTTP / stop_reason / 正文字数 / 工具次数 / 终态原文
一起打出来,退出码非零。用故障注入验过:停掉模型服务再跑 → 「成功 0,失败 1」、退出码 1。
新增的工具
-
tools/upstream_diff.sh—— 跟上游升级前先跑它。只比本发行版依赖的
四个外部面(daemon 路由与 SSE 事件 / skill 解析 / hook 事件与格式 / MCP 配置),
不是整仓 diff;有 fork 补丁的话还会在目标版本上试打一遍。
抽不到就报「抽取失败」并让退出码非零 —— 抽漏了报「无变化」是最危险的假阴性。tools/upstream_diff.sh --to 5.2.0 # 与 pins.lock 当前版本比顺带查出一个坑:release tag 上的
latest.json写的是上一版的校验值
(v5.1.0的 tag 里version是v5.0.9),照着 tag 读会锁错 sha256。
工具按文件内容回溯同步 commit,绕开了这个坑。 -
tools/stability/soak.py—— 长时间浸泡测试,采样容器内存 / 会话文件增长 /
错误数 / MCP 连接数 / 网关配额差值。这一版跑了 4 小时,结果与运维建议在
docs/stability-report.md。报告里专门有一节「疑似半截回合」——
浸泡脚本判「成功」的条件是 HTTP 通 + 收到终态 + 正文非空,
这挡不住模型宣告了动作然后就停了(P1-23)。那一节把命中的每一轮连正文开头列出来,
免得「失败 0」被读成全绿。
文档
docs/stability-report.md—— 4 小时浸泡的实测数据与运维建议(新)docs/对比-opencode版.md—— 和社区版怎么选,一页纸,全是实测数(新)docs/questions-for-atomgit.md—— 给上游的问题清单,定稿版(更新)docs/upstream-diff/—— 上游差异报告示例(新)
已知缺陷(仍在)
docs/开发文档/待办池.md 是完整清单。这一版之后仍然存在的:
- P0-10 / P0-12 / P0-13:daemon 的
/live是全局单例。切会话后 MCP 工具可能"消失"而
/mcp/status仍显示 connected;被"孤儿 runtime"占住时整个网页不可用(转发层已加自动恢复)。
不要在网页之外再开/live消费者。 - P0-11 的内核那一侧:我们把 MCP 返回压到了阈值以下,但超过阈值仍然会被砍,
只是现在很难触发了。根治要上游给配置项。 - P0-2:一个 daemon 一个工作区。
- P1-23:
stop_reason=stopped区分不了"做完了"和"做了一半",我们没有做自动续跑
(误判的代价是自动续跑烧钱)。 - P2-14:出口语言守卫的修正不落盘,web 进程重启后历史会显示未修正的原文。
- macOS 未真机测试(Ollama 通道这一版已在 Linux 真机上跑通,见上面第 7 条)。
许可证
与 v0.1.0 相同:Apache-2.0(见 LICENSE),AtomCode 为 MIT,社区版为 Apache-2.0,
版权声明保留在 NOTICE。
HunterCode · AtomCode 发行版 v0.1.0(预发布)
v0.1.0(预发布)· HunterCode · AtomCode 发行版
一台机器上的 A 股投研助手:对话式投研 + 9 个数据源 MCP(28 个工具)+ 6 个投研技能 +
网页终端,全部跑在你自己的机器上。行情、持仓、投资论点、对话记录、审计日志都落在本机磁盘,
唯一出网的是大模型调用(可换成本机 Ollama 做到完全离网)。
底座是 AtomCode v5.1.0 官方二进制(MIT,
版本与两道 sha256 锁在 pins.lock,构建时双重校验,没有 fork);界面与投研能力来自
HunterCode 社区版(Apache-2.0)。
不改 AtomCode 内核 —— 整套发行版只站在它的四个外部面上:daemon HTTP/SSE API、MCP、hook、skill。
装
curl -fsSLO https://raw.githubusercontent.com/agentpit-io/huntercode-atomcode/v0.1.0/deploy/install.sh
bash install.sh交互里只有四个问题:装到哪 → 模型通道三选一(默认 OneAPI · Gemini 3.8)→ 网关地址 → API key。
key 会真的去打一次接口校验;装完自检不过脚本直接失败退出,不会给你一个"起来了但用不了"的栈。
无人值守:
bash install.sh --non-interactive --yes --dir /opt/hca \
--channel oneapi --api-key-file /root/hca-key --web-port 3200要求:Linux + Docker Engine 24+ 且 compose v2;最低 2 核 4G / 20G 磁盘
(构建 web 镜像最吃内存,4G 以下大概率 OOM,可在别处构建好镜像再 --no-build)。
国内网络可换镜像与 npm/pip 源:--image-prefix / --npm-registry / --pip-index-url。
升级 / 回滚(数据卷一律不动,升级前自动存回滚点):
bash deploy/install.sh --upgrade
bash deploy/install.sh --rollback这一版有什么
- 对话式投研 —— 网页终端,问行情、问财务、写投资论点、做假设复核;每次取数都是一次工具调用,
卡片上能看到工具名、参数与返回。 - 9 个 MCP / 28 个工具 —— akshare(全市场)、自选、组合、筛选、龙虎榜与深度分析、
Kronos(K 线预测,需自备 key)、一手信号等。 - 6 个投研技能 —— 深度分析、投资人辩论、龙虎榜、风险画像、杀猪盘检测、UZI 全维扫描。
- 五组 hook(8 条注册):写类工具只放行
reports/与theses/;bash/bash_start
只放行只读与纯计算;取数一律走 MCP(写爬虫、直接import akshare、跑 MCP server 源码都拦);
每轮注入真实日期与交易时段;语言硬约束;每次工具调用落审计(工具名 / 参数摘要 / 耗时 /
结果大小 / 会话 / 用户标识);可选的预算闸(默认关)。 - 一键安装 / 升级 / 回滚,模型通道三选一,多套并存(compose 项目名与镜像 tag 都可配)。
请先读一遍已知缺陷
这是预发布版。功能能完整走通(回归清单见 docs/regression-report.md),
但有几条会影响判断质量的缺陷还在,全部公开摆在 docs/开发文档/待办池.md:
- P0-11:MCP 返回超 16 KB 会被内核砍成"头 4 KB + 尾 4 KB",阈值写死在源码里、无配置项。
模型可能拿记忆补中间那段还标成工具来源。我们在数据源侧压返回体积来规避,但没根治。 - P0-10 / P0-12 / P0-13:daemon 的
/live是全局单例。切会话后 MCP 工具可能"消失"而
/mcp/status仍显示 connected;被一个"孤儿 runtime"占住时整个网页不可用(转发层已加自动恢复)。
不要在网页之外再开/live消费者。 - P0-2:一个 daemon 只有一个工作区。多人共用同一份研究工作区(自选/组合走各自账号),
多用户隔离要多开 daemon。 - P1-21:语言守卫只有提示词侧那一道,出口强校验还没有(AtomCode 没有对应的 hook 事件)。
- Ollama 通道未在真机上验证(测试机磁盘不足,见
docs/regression-report.md)。 - macOS 未真机测试,安装脚本里有分支但只做过脚本审阅。
安全默认值
只有网页那一个端口对外;api / daemon / postgres / redis 都不发布到宿主端口;
单用户免登录强制关闭;注册按邀请码;模型 key 只落 0600 文件并只读挂进容器
(目录会被对齐到容器 uid 10001,不是靠放宽到 0644);容器 no-new-privileges。
默认是明文 HTTP,请自己上反向代理 + HTTPS 再对外(deploy/nginx/ 有现成片段)。
文档
| 看什么 | 去哪 |
|---|---|
| 部署、备份、升级、安全、国内网络、离网、排障 | docs/部署与运维.md |
| 加技能 / 加数据源 / 加约束 / 跟上游升级 | docs/开发者指南.md |
| 五组 hook 的设计与上游契约的 12 个坑 | docs/hooks-design.md |
| 这版都测了什么、结果如何 | docs/regression-report.md |
| 15 分钟演示 | docs/demo-script.md |
| 已知缺陷与待办 | docs/开发文档/待办池.md |
许可证
Apache-2.0(见 LICENSE)。AtomCode 为 MIT,HunterCode 社区版为 Apache-2.0,
两者版权声明保留在 NOTICE。HunterCode / Hunter / AgentPit / 猎鹿人 是 AgentPit 团队的商标,
对外分发或商业发布请去掉这些名称与 Logo,可注明「based on HunterCode」。