ThearchyHelios
|
941723b17c
|
端到端验收修复与指标出具:
- 身份与工具:登录页建第一个管理员(认人接口的 401 说明能不能建);搭建者有只读的人和组名录,选人给候选并核对名字;授权三行带标题;端点请求头名校验(空名、非法名存不进、发不出时说清原因);写入能力在工具页试运行一律演练、不发送,HTTP 状态照实说成败;写记忆不算只读、查询能力只能选同一端点上的只读能力;审批与遮罩的说法和实际规则一致;开登录时不要署名、导入和发布记登录的人;使用者不显示推演等只给搭建者的操作,403 按是否开登录说话;登录页只认一次人
- 流程与实例:图里用到的岗位(派给谁、超时升级给谁、发送确认派给谁)全部派生、没绑人的发布时报错;写外部系统的参数按能力声明的类型收拢后再算哈希和发送,收不成就不发;发起人的实例页只看这一步的状态,处理人才给待办卡;会签进度带登录核实和时间,升级后照实写规则;实例状态写流程的结论(已退回、未确认、等待核实写入结果),核实生效后不再挂失败原因;流程应用首页不派生最近封存运行的结果块,看板没数据时是安静的空态;样例⑩的金额带类型和下限、待办标题带金额,表单上下限前后端一起生效
- 看板与证据:定时任务模板加 ISO 周、上一 ISO 周、本月、上月;出处链穿过原样解析查询结果的整形节点,追不到原始数据的照实说停在哪里,样例⑨改用 cell();应用首页和版本历史都能做成应用;指标块单位不重复;版本列表带退役说明;定时任务页头跟着刷新;删视图要确认、新视图能起名;编辑器属性用中文名、术语带解释
- 指标出具(用户 2026-10-15 拍板):契约只写「指标来自」、上游没有报告撰写节点、成果里没有模型写的话时按指标出具——必需指标齐、指标输入追到原始数据、成果字段里的数回指得上才完整出具;受管级要求每个指标静态地追到原始数据(governed.metric_untraced);出具横幅和应用印章写明按指标
- 受管工作流降为已发布只给管理员(Q8 顺延,服务端同样拦);工作流接口带当前发布版的级别,画布上改过之后也认得出受管工作流
|
2026-10-15 07:15:37 +08:00 |
|
ThearchyHelios
|
c86e58f464
|
README 与部署说明:应用(怎么生成、能做哪几类、视图与印章、流程与待办、写外部系统、入站钩子、按新口径补算、升级安全)、身份与权限(三种登录方式、会话、找回、角色与授权、使用者的问数据、遮罩的边界)、能力登记与端点、助手按需查看;默认不开登录的说法、核心能力表、数据目录与遮罩、节点类型、安全边界、检查项(33 项另加 check-auth)、从旧版本升级;部署配置模板加登录一节
|
2026-10-14 22:12:01 +08:00 |
|
ThearchyHelios
|
fc002bd3b3
|
README:检查数改成 29 项并在分类里列上 catalog-loop;功能概览的数据目录一行补上表助手、审阅队列、导出导入;对话里纠正一行写明理由记为这一项的「确认时的依据」
|
2026-10-14 16:26:59 +08:00 |
|
ThearchyHelios
|
49f00c589a
|
目录修改提案的依据改存成目录项单独的字段 reason(界面上叫「确认时的依据」,最多 500 字,超了截成 499 字加「…」),不再拼进备注:拼进 note 之后,带依据保存的关联关系再剖析时测量的说法换不了新、和覆盖率那一栏对不上;改了值的关联关系旧依据叠在新依据后面、越存越长;值不变、保存即确认的项撤销审阅回到推断后「依据:使用者说……」还挂着,看起来像使用者确认过一条推断项。去留:值改了(关联关系也一样)换成这次的依据,没写就去掉旧的;值不变的确认换成这次的,不叠;单项确认、驳回留着,撤销审阅去掉;整份提交改了值的、状态改回推断的、双盲复算改写的去掉;剖析刷新关联关系的测量只动备注。校验认 reason(文字、最多 500 字),起草、剖析的合并不碰人工确认的项,导出导入时已确认、已驳回的项连依据一起带,推断、有确证的项不带。表助手背景里已有的依据写成「以前确认时的依据:……」,系统提示词和 propose_changes 的说明写清那不是这次对话里使用者说的话、引用时写「以前确认时的依据写着:……」,遮罩列的项不给。表详情里依据和说明分开写:表级的项在值下面另起一行,列的一格、关联关系另一个悬停图标(读屏念「确认时的依据:……」),状态弹层里也写,驳回的项只在弹层里写;check-catalog-loop 的假服务端照服务端记下依据,补依据和说明分开、弹层、驳回项的检查;README 表助手一行写上依据另存
|
2026-10-14 15:38:15 +08:00 |
|
ThearchyHelios
|
5b5b6d8df2
|
起草逐表行列出服务端记下的说明(task.log:没收下的有效记录条件和原因),check-catalog 补一项;README 数据目录一节补上防错事实的提议、审阅队列、表助手、导出与导入,模型起草一行写上逐段落盘、不设总时长上限与按比例止损、块进度、同步起草与任务互斥
|
2026-10-14 10:19:18 +08:00 |
|
ThearchyHelios
|
f74744b29e
|
README:数据目录的模型起草照复核修正补上——超时的两半同时问、拆到每段 10 列仍接连超时就不再拆,每段连同它分开、拆小的各块最多 8 次,没写出来的原因写清第几段、哪几列,留空的列只记目录里还没有中文名和含义的,库注释就是名字本身或标识符写法的整条不记进目录
|
2026-10-13 21:26:07 +08:00 |
|
ThearchyHelios
|
a9170d8728
|
README:数据目录的模型起草补上验收后的修正(列分段均分、按表先后排队、超时拆小、段大小减半、每段 8 次封顶、提醒换模型、重新起草不删模型这次没给的项、留空的列逐表记下、库注释就是名字本身的不当中文名)
|
2026-10-13 20:30:02 +08:00 |
|
ThearchyHelios
|
950b88a15b
|
README:数据目录一节补上模型起草(后台任务、只重试失败的表、中断不自动续跑、保留思考加大额度、按段起草宽表、起草要求与本次补充说明、起草模型设置)
|
2026-10-13 16:57:02 +08:00 |
|
ThearchyHelios
|
265ba0c91d
|
报告导出为自包含 HTML(数字点得开口径、来源、计算方式);可验证报告的数字详情补齐口径卡一节
两件事,一条心:把「网页上点数字看得到的效果」带出系统外。
① 报告导出:新增 GET /api/runs/{run_id}/report.html(app/report_export:build + 模板 + 浏览器端脚本)。
正文由服务端按报告文档的块、句、片段渲染成 HTML——不执行脚本也读得到整份报告(附件预览常常不执行脚本);
执行脚本后,带出处的数字、无证据的数字、可疑的表名字段名都点得开,面板是网页上证据面板同一个拼法的
出处链(api/evidence._chain):指标步骤带口径卡名与版本、原式、代入式、每个输入取自哪次查询的哪一格、
复算、双盲复算;查询步骤带 SQL 和被引用的行;数据源遮罩列照网页上的规矩写「已遮罩」。封存状态逐项标明;
没封存的运行照常导出(和网页上读报告一个道理)。同样的引用共用一条链,长报告不把整份快照抄几十遍。
入口在问数据答案和运行详情成果上的「导出」(带证据的报告给 HTML,Markdown 留一个小的;旧运行照旧只有
Markdown)——api.reportExport + AssistantStream 的 AnswerActions。
② 可验证报告(bundle)的数字详情补齐:点开数字原来只有出处和值,现在多一节口径卡——指标(名 + id)、
单位、原式、代入式、输入(取值 ← 路径、取自哪次查询的哪一行哪一列)、复算;输入指向的查询快照也随文件
附带(遮罩规则同嵌入那一套,build._card_input_queries),④ 引用链按「已核对的口径卡的输入」认它们
(哈希对不上的卡不认,免得替被改过的卡圆)。收件人不连服务也能看到每个数怎么算出来的。
测试:后端 tests/test_report_export.py(真跑运行导出,正文、出处链、遮罩、只读、404/409、共用链);
bundle_samples 的口径卡换成带原式/代入式/输入/复算的真实形状,另加 metric-only 样本页(只引用指标的
报告,快照从口径卡的输入这一条路附带);check-bundle 断言数字详情和这条引用链,加上篡改;新增
scripts/check-report-export.mjs(真导出断网点开、不执行脚本也读得到、成果上的导出按钮、旧答案没有
HTML 按钮、409 提示),挂进 check-all。README 补「导出两份」一节。全量 pytest 通过;check-bundle、
check-report-export、check-stream、check-evidence、check-chat 全部通过(check-runs 5 项失败为基线
上就有的沙箱数据形态问题,与本次无关)。
|
2026-10-10 12:59:21 +08:00 |
|
ThearchyHelios
|
fbc48b4e61
|
README 补上数据目录:核心能力加数据目录、SQL 检查、跨库合并,节点类型加合并查询,新增一节说明数据目录的读法、来源与状态、剖析的约束、版本与提醒,开发与验证更新测试数和检查项
|
2026-10-04 01:33:42 +08:00 |
|
ThearchyHelios
|
e4f8ee5d08
|
Excel 导入改造期 4:证据下钻——报告里引用上传表格的数,点开能看到它来自原表格的哪一格;裁判核对时看得到来源、口径、接受理由和区域外文字
推断的来源(新 engine/direct_select、data/provenance、data/provenance_db;api/evidence 新增推断来源接口)
- 只对直接引用一列的查询下钻:受限文法用和执行时相同的 SQLite 分词读法,别名互换、自连接、表达式、聚合、子查询、集合运算(含藏在注释、字符串、方括号、转义、BOM 之后的)一律只给表级来历;再用 EXPLAIN 字节码和授权回调兜底
- 结果带齐主键、值非空,按主键参数化回查只读快照、类型和值严格一致才给格子;不一致时整份重算库哈希,哈希不符标红
- 从导入清单和溯源找回格子:宽表、交叉表逆透视的长表(日期取自表头格、年份取自统计期、行标签、分段标题)、列表、合计表、按期累积的并集(换算到所属那一期);原文与规范写法不同时一并列出
- 清单读不到、登记哈希与清单不一致、快照已回收、遮罩列,都只给表级来历或不给,写明原因;原件已清除、接受已作废照实显示;未封存的运行照常推断并标明
- 相关核对:这一行、这一期的核对结论与接受理由
裁判摘录(engine/judge)
- 带期 4 标记的报告,上传表格的查询旁加来源行、口径行、接受理由、可见单元格里的区域外文字和人工录入的统计期;限定语写明这些数未经系统核对,长度有上限、截断时写明
- 隐藏行列里的区域外文字不送;设了遮罩的源只写条数
前端证据面板(run/EvidenceProvenance;ManifestBody 从版本页抽出复用)
- 「推断的来源」一节与已封存的证据分开标注:格子坐标、取自哪些格、年份来源、规范写法、回查、相关核对、数据版本与各期;标红与拒绝原因按状态显示
不变的部分
- 文档顶层加 provenance 标记,只有新报告走新路径;期 4 之前的运行、非上传源、手工源的面板、复核、裁判摘录逐字不变,由金样测试钉住
- 执行器给区域外文字记录是否在隐藏行列;不建「导入校验」系统表(D6)
|
2026-10-02 14:38:10 +08:00 |
|
ThearchyHelios
|
2cdbf9a733
|
Excel 导入改造期 3:网格交互、自助修复、按期累积——每月的报表可以累积成一份跨月的表,漂移了点修复按钮就能接着导入,网格上框一块就能写进配方,版本页可以回滚、移除一期、清除原件
按期累积(新 recipe_accumulate;table_versions 扩展)
- 按统计期出的交叉表报表首次导入时默认「按期累积」,由人确认;一期一个构建,两期及以上物化成一份新的 SQLite 快照,不用视图
- 统计期完全相同要勾「替换该期」,部分重叠拒收,中间有空缺要确认;物化前逐期核对库哈希和行号,并集上另加行数守恒、主键唯一、日期落在所属统计期三条核对
- 配方演进分三档:新增列(早期各期为空值)、退役的列和表保留旧值(只在这次才退役时要勾)、不兼容变化只能显式「重新开始累积」
- 快照 id 在累积时含目标配方和模式;同样的输入物化两次库哈希相同,同一文件换名再传直接复用
- 说明按期合并,任何一期没核对过就不写「已核对」;各期维度取值不同、退役列、合计表都有提示,经过数字检查
修复按钮(新 recipe_fixes;执行器给问题带结构化参数)
- 加入标签、移除标签、声明为合计行、分段标题改名、编辑恒等式成员、按锚点忽略行/列/区域外文字、声明占位符、声明隐藏行处理、工作表改名
- 服务端算补丁,先预览新旧配方对照、再应用,可以撤销;补丁封闭,不引入正则、自由文本常量和写死坐标;修复进确认清单
- 只改分段标题、新标题仍含原来选的词时沿用已确认的常量,不算破坏性变更;修复后只查改动过的段的认领,没改的关系交给试运行核对
框选转锚点(新 recipe_select)
- 网格上框选(鼠标、键盘、区域输入),按八种用途换算成按文字认的锚点,立刻干跑比对;配方里不存坐标,泛化不了时列出原因
- 整张表挪位后同一配方照样认得;框进合计行、夹着小计、表下说明都有明确的处理
确认与对照(recipe_confirm、recipe_diff、新 recipe_compare)
- 改配方后确认清单只列有变化的项(同时按本期数据比较),不用每修一次重勾十来项;新旧配方对照界面;按规则重新起草并把名字对齐到现行配方
- 改配方后已体现在配方里的回答保留,矛盾的列出来请人重答
- 「排除的行」写进回执和导入清单:隐藏行、跳过的空行、按配方忽略的行、停止后的文字行、只核对不另存的合计行
版本页(新 source_versions、api/source_versions;前端 VersionsDialog)
- 快照与导入记录列表、启用旧版本(可写理由)、查看清单、移除一期、作废接受、清除原件;写操作带界面看到的当前版本,并发改动回 409,不静默丢期
- 除当前版本和被运行引用的版本外,再保留最近 3 个版本供回滚;遮罩列丢失要明确确认
期 1、期 2 遗留
- 重传撞上被改过的构建文件:能用本次上传恢复就隔离旧文件再恢复,否则回 409,不再是 500
- 跳过空行的列表不再把表下隔一行的说明读成数据;不像说明的单格行要人确认;受影响的配方构建换 id
- 版本存储加进程级文件锁:第二个进程拿不到锁时不清理、不回收,写操作回 503(部署本来就是单进程)
|
2026-10-02 07:38:44 +08:00 |
|
ThearchyHelios
|
78f24dfe3f
|
Docker 镜像内置 microVM:构建时装好运行时、预拉沙箱镜像;deploy.sh 检测到 KVM 先试启动一台,起得来才交给容器;没有 KVM 时服务端不再选 microVM
- microvm_sandbox:Linux 上 available() 要求 /dev/kvm 存在且可读写,不可用时给出具体原因(没装、运行时没装、没有 KVM、没有权限)
- 新增 app.sandbox.selftest:真起一台 VM 执行一行代码,部署脚本用它判断
- Dockerfile:WITH_MICROVM(默认 1)构建期 install 并 pull python:3.12-slim,自带的 msb、libkrunfw 改为链接,镜像约多 150 MB
- deploy.sh:ENABLE_MICROVM=auto|0|1,有 KVM 时用临时容器试启动,成功才加 --device /dev/kvm 和所属组;部署完和 status 打印实际用的沙箱
- package-docker.sh:--no-microvm;部署说明、配置模板、README 同步
|
2026-09-30 11:19:25 +08:00 |
|
ThearchyHelios
|
6af4e396b9
|
生产部署:prod.sh 直接运行,package-docker.sh 打 Docker 离线包(镜像 + 一键部署脚本 + 配置 + 说明)
- 服务端可以托管前端构建产物(AGENTLAB_WEB_DIST):页面路由回退到 index.html,/api 下不存在的路径照旧是 JSON 404,
挡住路径穿越;index.html 不缓存,assets/ 带哈希的文件长缓存;没设时行为完全不变
- scripts/prod.sh:不用 Docker 的生产运行。按需构建前端,单进程、不热重载,默认只听本机,--host 开放到局域网并提示没有登录
- Dockerfile(多阶段构建,Linux 镜像):前端在构建机架构上构建,运行阶段用 python:3.12-slim,依赖装进独立的 venv,
以非 root 用户(uid 10001)运行,数据在 /data,带健康检查;.dockerignore 排除 .env、data/、各种库文件,镜像里实测没有密钥和数据库
- scripts/package-docker.sh:构建指定平台的镜像(默认按本机架构,可选 linux/amd64),打成
release/agentlab-<版本>-linux-<架构>.tar,里面有 image.tar、deploy.sh、agentlab.env、README.md、SHA256SUMS
- deploy/deploy.sh:目标机上只依赖 Docker,离线可用。install / start / stop / restart / status / logs / upgrade / uninstall;
检查架构和配置,自动导入镜像,替换容器时保留旧容器以便回退,数据永远保留,日志轮转
- 修正 bubblewrap 的可用性判断:以前只看有没有装 bwrap,容器里和 Ubuntu 24.04 默认配置下装了却建不了命名空间,
每次执行代码都失败;现在真起一次试,不能用就退回下一个后端,并写明原因
- README 增加「生产部署」一节,部署细节见 deploy/README.md
|
2026-09-30 09:48:16 +08:00 |
|
ThearchyHelios
|
f45ccbfc0c
|
README:去掉工业场景的表述,改用通用场景的例子
- 「受限动态编排」一节开头的「工业场景中……(接单报价、周报、体检)」改成通用说法,
例子换成内置模板里就有的场景:写周报、核对数据、审批后发布
|
2026-09-29 19:12:59 +08:00 |
|
ThearchyHelios
|
5b0c0e3a32
|
更新 README.md
|
2026-09-29 18:39:30 +08:00 |
|
ThearchyHelios
|
8e0817bbc4
|
README 更新到最新:可点击证据、受管门禁与发布前修复、agent 护栏、测试与检查的新跑法;图片重拍
- 新开一节「可点击证据」:引用标记的全部写法、取数链路、点开能看到什么、可疑实体、结论句与裁判(成本上限可设不限)、
审计导出、旧运行的猜测来源、一键升级;子节「受管门禁与发布前修复」写明 G1–G5 和三类修法
- 核心能力表补上 agent 护栏、可点击证据、发布前检查;节点 17 种、模板 9 个、内置工具 15 个,都按代码数过
- 新增「agent 的护栏取代固定步数」一节;工具审批写明三档 ask / gated / always
- 快速开始补上 ./scripts/dev.sh --host(写明没有登录、只在信得过的网络里开)
- 启用 microVM:安装命令换成能跑的写法(原写法报 no running event loop);补上手动拉镜像(auto 只选镜像已缓存的
microVM,不手动拉永远选不到)、改完要重启、Linux 上的 KVM 权限、doctor 全绿不等于装好、拉不下来时走代理或镜像源
- 开发与验证:pytest 带 env -u 和 -n auto(约 2860 个测试、约 16 秒);check-all 的默认跑法、--stacks、只跑某几项
- 5 张图在只装内置模板、只用 Mock 的干净环境里重拍(深色、2 倍像素);新增证据面板图,用前端测试夹具的示例数据
|
2026-09-29 18:07:08 +08:00 |
|
ThearchyHelios
|
62aac187d8
|
工具审批三档、智能体护栏取代固定 12 步、检查脚本分道并行
MCP / 自定义工具的审批三档(tools/trust.py)
- 平台看不出这两类工具做什么,以前审批关卡一律当它们安全、照跑不误。现在默认每次调用都等审批;
工具页可以逐个改成「始终允许 · 门控把关」或「始终允许」,审批卡上的「始终允许」等于前者
- 门控把关:每次调用先由门控模型审一遍工具说明、参数和节点任务;判可疑、出错、超时、答不成格式,
一律交还给人,不会变成放行。判定包进 checkpoint,审批恢复重放时不再问一遍
- agent 节点、工具节点、协作团队三处关卡都接上;团队成员停不下来等人,门控没放行的调用不执行
- 每次运行在发起时快照档位(runs.tool_trust),恢复和接着跑沿用同一份;正式运行不看档位,一律等审批;
升级前发起的运行照旧不问——它们可能正停在某个审批上,多问一次答复就会对错号
- 接口:GET /api/tools 带 trust / trust_key,PUT /api/tools/trust;设置新增门控模型;新事件 tool.gated
- 界面:工具页三选一、审批卡「始终允许」、设置页门控模型、运行记录解码 tool.gated;
顺手修了 MCP 工具详情 404、工具审批被驳回却显示成放行
智能体护栏(engine/guards.py),取代固定的「最多 12 步」
- 步数只留兜底:默认 100,设置里可改;以前画布自动写进节点的 12 按「没填」处理
- 同一个工具、同样的参数第二次不再执行,把上次的结果交还给它;连续 3 步拿不到新信息就收尾
- 每个节点的令牌预算(默认 200 万)和金额预算(默认不限),都可以在设置里改成不限
- 上下文用到窗口的 60% 先压缩早期的工具结果,到 85% 就收尾;临近任何一个上限先提醒模型一次
- 下游结构化校验失败时写明是上游哪个 agent 提前收了尾;复核信号带上收尾原因,
问数据页只在真是步数用满时才给「放宽步数重跑」
- 上限在发起时快照(runs.agent_limits);升级前发起的运行一字不改走旧逻辑
检查脚本
- check-all 默认 4 道并行:量时间最多的两项互不重叠;并行时没过的最后单独重跑一遍,重跑才过的
单列成「偶发」。16 项全量从约 21 分钟降到约 7 分钟(加上一次重跑约 10 分钟);--lanes 1 回到串行
顺带修的
- 设置接口里的 limits 改为只读:库里存着旧版设置页写进去的一份(max_agent_steps: 25),从不生效,
却盖住了真实上限,问数据页照着错的数许诺
- test_kb 里嵌入模型那条测试不再真连 api.openai.com(代理慢时一条要等近 4 分钟)
- check-stream 读滚动容器前先等它挂上,并行跑时不再偶发
验证(沙箱):tsc 干净,生产构建通过,pytest 1655 passed(两遍),check-all 16 项检查、3562 项全过;
新增后端测试 53 条,关键逻辑做了 22 处变异验证、全部抓到。
|
2026-09-28 11:47:45 +08:00 |
|
ThearchyHelios
|
3e311ec551
|
第三波收尾:跨模块整合、全站扫尾、检查脚本整合;网页工具认得本机代理的 fake-ip
整合(3c-integrate)
- 公共层:跨天时长(formatSpan / formatOffset / formatLapse)、本机署名(lib/actor)、检索分类色令牌、
数据源目录(useDatasources)收进公共层;失败说明能一次列出多个写坏的自定义工具,查询超时指到数据源的查询时限
- 管理页收尾:设置页接入统一的离开前确认;检查脚本不再把沙箱里的真实值打进输出
- 画布 ↔ 右栏:点出具印章、点节点能跳到右栏对应位置;「定位」直接聚焦到出问题的字段
- 回答流 / 问数据 / 记录页:失败信息带「去哪修」且不再被翻译两遍;协作团队的结局按执行截取;
等审批时断流重连、而运行已在空档里跑完的,补全事件
扫尾(3c-sweep)
- 术语统一:开始运行 / 继续运行、工作流最大步数;未保存的运行统一叫「未保存的工作流」(后端新运行同步)
- 沙箱报错不再带 Python 异常类名;新增 check-tokens,未定义的 CSS 变量为 0,两个旧别名迁移后删除
检查脚本(3c-checks)
- check-ui 跟上新界面(运行列表按 data 属性找行),加上令牌与选中态的回归断言,输出里的名字打码
- 新增 check-all:按顺序跑全部检查、汇总退出码,--repeat 列出偶发项
- 单节出错只记这一节失败、不再带崩整个脚本;外壳遥测浮层「重新检测」时焦点不再掉到 body
网页工具与 fake-ip
- Clash / mihomo 一类代理开 TUN + fake-ip 时,查什么都先拿到 198.18 段的假地址,被当成内网拦截。
新增 AGENTLAB_HTTP_TOOL_FAKE_IP_RANGES(默认空):落在段里的解析结果改向公共 DNS(DoH)核实真实地址,
公网放行、内网照拦、核实不了按拦截处理。DoH 默认先问境外的,境内公共 DNS 会对被封锁的域名返回污染结果
- 列表型环境变量接受逗号分隔(原来注释说逗号分隔、实际只认 JSON 数组);域名解析改为异步,不再阻塞事件循环
验证(沙箱):tsc 干净,pytest 866 passed(两遍),检查脚本全绿。
|
2026-09-27 23:37:32 +08:00 |
|
ThearchyHelios
|
95ff6470d1
|
后端依赖锁到测过的那一套:pyproject 卡版本范围,requirements.lock 写精确版本
langgraph 和四个 langchain 包原来完全不写版本,fastapi、sqlalchemy、aiosqlite 只有下限,
uv.lock 还在 .gitignore 里。按旧写法今天新装,22 个包和测过的版本不同,其中 sqlalchemy
会从 2.0.52 跳到 2.1.1。
1. pyproject.toml:LangGraph / LangChain 一族放行到下一个小版本——引擎依赖它们的断点
格式、interrupt / resume、流式事件和 thinking 块,这些在小版本里也改过行为。aiosqlite
与 SQLAlchemy 同样卡小版本:db/base.py 给 aiosqlite 0.22 的 stop() 打了补丁,连接池
强制断开时会走到它。mcp 卡在大版本 1。
2. backend/requirements.lock:后端全部依赖(含间接依赖、全部 extras)的精确版本,
--universal 跨平台。锁的是 473 条测试跑过的那个 conda 环境:本机要装的 96 个包逐一
对上,另外 3 个只在 Windows / emscripten 上装。
3. environment.yml 装包时以锁文件为约束(-c),换机器装到的是同一套。
4. scripts/lock-deps.sh 重新生成锁文件:已锁的版本默认不动,升级用 --upgrade-package /
--upgrade。README 补了用法,补装 extras 的命令都带上 -c。
验证:用同版本 Python 新建空环境,照 conda 的方式按 environment.yml 的 pip 行安装——
装到的 96 个包和测过的环境完全一致,473 passed。
|
2026-09-26 09:49:16 +08:00 |
|
ThearchyHelios
|
9d375f8f1c
|
循环跑满自己声明的轮数,不再被全局步数上限半路掐断
「测试 1」按校验提示改好之后仍然跑不完:while 循环配了 1005 轮,每轮是"循环节点 +
循环体"两步,而整次运行的步数上限(max_graph_steps)是 200——跑到 100 轮上下 LangGraph
抛 GraphRecursionError,报错是一段英文,叫人去调一个界面上碰不到的 recursion_limit。
图没写错,是平台自己的两个上限在打架:校验通过,跑到一半才死。
全局上限防的是没人把关的环;loop 节点的 max_iterations 是作者明说的轮数上限。现在循环
按自己的轮数另记一份预算(schema.loop_steps),加在全局上限之上,子图同理。取上界:
一个节点最多跑 Π(包住它的各层循环 max_iterations + 1) 次,嵌套相乘;done 出口之后的
节点只跑一次,不按轮数记账,否则预算虚高、等于没有上限。
没有 loop 节点把关的环(分支连回上游)照旧由全局上限拦住,报错改成中文、说清预算怎么
来的、该怎么改;子图里撞上限报子图自己的名字和步数——以前那段英文会被外层包进 NodeError
原样带出来。
实测:「测试 1」照提示改完,在真沙箱里 1000 轮跑满,25 秒,结果 501500(= 2+3+…+1001)。
测试:test_step_budget 8 条——预算的上界、嵌套相乘、done 之后不记账;全局上限压到 20 步
时循环照样跑满 30 轮;空转的环中文报错;子图里的循环有自己的预算、空转的子图报它自己的
名字。把 runner / 子图的预算换成 0,对应用例确实失败。README 补了常见问题,测试数更新为 470。
|
2026-09-25 17:04:49 +08:00 |
|
ThearchyHelios
|
0997603ccf
|
画完先自查:条件写错在校验时就拦下,Copilot 交付前按同一套规则查一遍、查出问题先改
开发库里四次运行死在同一句"循环条件写错了:表达式里不允许出现 Set"。条件原文是
`{{ vars.gate }} != "ok"`——把模板写法带进了表达式:`{{ x }}` 在 Python 里是"装着
一个集合的集合"。Copilot 的提示词写着"模板语法在任意字符串里用",模型照做而已;
校验又不看表达式,写错了只有跑到那一步才知道,前面的步骤白跑。
1. 表达式:解析和静态检查收成一个 parse_expression,运行时、校验、Copilot 自查共用,
不会出现"校验说能跑、跑起来报错"。多套的 {{ }} 意思无歧义,在语法树上剥掉(字符串
里的花括号不动),按 vars.x 理解并提示。真写错的给能照改的提示:| 过滤器 → len(x)、
集合 → 列表、不认识的函数列出能用的、= 当 ==、引号里的 {{ }} 永远不成立、推导式、
切片、私有属性。and / or 短路掉的那半边也查。
2. 校验:按节点类型和模式挑出真正求值的字段(分支条件、while 条件、整形表达式、口径卡
指标、skip_if)。写错是 error、挡住运行;漏写 vars. 的名字提示会取到空值;while 没写
条件、整形没填表达式也说出来。foreach 的 condition、模板模式的 expression 不求值,不查。
3. 代码节点:assign_to 拿的是 stdout。「测试 1」修好条件后跑通了、结果却是空的——代码
最后一行是裸表达式,那是 notebook 的行为。设了 assign_to 却找不到任何输出的 Python
代码,校验直接拦下,提示 print(json.dumps(结果))。宁可漏判不可误判:子进程、exec、
附带文件里的 print 都算有输出;整行只有一个 {{ }} 的代码是运行时才拿到的(⑤号示例
整段就是 {{ vars.code }}),看不见,不猜。库里 20 张工作流无一误拦。
4. Copilot 自查:搭完用同一套校验过一遍,error 级的问题连同图交回模型——只修这些、只
输出改动,最多两轮。改好了才自动运行;改不好照实交付、列出剩下的问题,不自动开跑。
没问题的图不多花一次调用;只是多套了 {{ }} 的不返工。提示词改成"模板只在普通文本
字段里用",并列出表达式字段的对 / 错写法和代码节点必须 print。
5. 前端:自查这一段在 Copilot 的过程里看得见——发现几处问题、交回去改、改好了没有;
改不好标红并说明没有自动运行。"搭好了,共几步"那一行不会被挤掉。
测试:新增 test_expressions(开发库里真实死过的四条条件、静态提示、按模式挑字段、代码
输出、带 {{ }} 的循环真跑一遍)与 test_copilot_selfcheck(脚本化模型:改好 → 自动运行;
改不好 → 不运行、最多两轮;干净的图一次调用;多套 {{ }} 不返工)。test_continue_run 里
用来制造运行时失败的表达式换成 `2 ** 100000 > 1`——原来那条现在在校验阶段就被拦下了。
check-decode 补了自查的解码断言。
|
2026-09-25 17:04:39 +08:00 |
|
ThearchyHelios
|
03830d4815
|
服务重启不再把运行记成"用户取消";接着跑也不再替人答掉下一个审批
dev.sh 开着 --reload,改一个后端文件就是一次关停。三件事以前都是错的:
1. 关停时在跑的运行一律记成 cancelled、原因"用户取消"——之后 resume 和
continue 都拒绝它,尽管 checkpoint 完好。现在关停时收到的取消记成 interrupted
(和强杀后启动扫描的处理一致),留一条 server_shutdown 日志说明原委,
不发 run.cancelled。
2. 关停会打断正在收尾的运行:状态已落、封存和 run.finished 还没写完就被取消。
现在已进入收尾的运行不取消,等它写完。
3. 因重启而中断的运行没有在等人的 interrupt,resume 却照样发 Command(resume=…):
那个值会被后面遇到的第一个 interrupt() 当成答复——一个还没轮到的人工关卡被
自动作答(审查时的实测);当前版本的 LangGraph 则直接在内部崩掉
(UnboundLocalError: resume_is_map),运行判 failed。现在没有待答的 interrupt
时从断点接着跑(输入 None)。
运行详情页:中断了却没有待审批的运行,以前显示"等待人工介入"却没有任何可点的
东西,现在说明原因并给「接着跑」。用真实库里的中断运行看过:无待审批的出横幅,
有待审批的仍由审批卡片处理。README 加了对应的常见问题。
test_shutdown.py 3 例,修前全部失败:关停不是用户取消;重启后接着跑,前面跑完的
节点不重跑、后面的人工关卡真的停下来等人;关停不打断收尾(封存照样写完)。
分两步修、中间跑了一次,确认第二例在关停修好之后确实撞上了 resume 的崩溃。
422 → 425 passed,连跑 8 轮全绿;check-guards / decode / stream / canvas-layout 不回归。
|
2026-09-25 16:05:14 +08:00 |
|
ThearchyHelios
|
5928cc052e
|
三道只配不管的护栏开始干活:运行时限、模型超时、清单核对
显示成生效却没生效,比明说没有更危险——它让人以为有东西在兜底。
1. max_run_seconds 只存在于配置和设置接口里,没有任何代码执行它:一个挂住的
模型或工具能把运行和它占着的并发名额一直拖着。现在 runner 用 asyncio.timeout
强制执行,按"一段执行"计(等人工审批时 _drive 已结束,不算);超时判 failed、
说清是哪道上限,可以接着跑。别处抛的 TimeoutError 不冒充这道上限(看
Timeout.expired())。
2. 模型调用从来没设过超时:ModelSpec.timeout 从没被赋值,那条传参分支一次都没
执行过,所有调用走 SDK 默认的 10 分钟外加重试。新增 model_timeout_seconds
(默认 300 秒)作为缺省,节点显式配的仍优先;已确认 ChatAnthropic / ChatOpenAI
都接这个参数。
3. manifest 哈希只写不验,而且是在 run.finished 落库之前算的——清单里恰恰少了
宣布"跑完了、成果是什么"的那条,改成果清单照样对得上。现在终态事件落库之后
再封存,并记下封到哪一条(manifest_seq,新列);新增 verify_manifest 与
GET /api/runs/{id}/verify,运行详情页加了核对按钮。封存之后追加的事件不算篡改。
老运行没有 manifest_seq,按当时的口径还原范围——开发库里 300 条带哈希的历史
运行全部核对通过(成功 / 失败 / 取消各类都有),没有一条误报。
设置页「运行环境」补上单次执行时限和模型调用超时两项,README 加了对应的常见问题。
顺带修了一个被 _seal 放大的老问题:_drive 的收尾被打断时(关停取消、库连接出错)
漏掉 _tasks.pop,留下的任务让下一次 shutdown 的 gather 在别的事件循环里抛
"future belongs to a different loop"——测试里表现为每八九轮一次、一出就是几十个
teardown error。pop 移进内层 finally,shutdown 只等未结束的任务并清空。修后全量
连跑 12 轮 12 轮全绿。
test_guardrails.py 8 例:超时中止(挂住的节点 1 秒后被停下)、缺省模型超时、封存覆盖
run.finished、改成果被戳穿、事后追加不误报、老运行按旧口径核、中断态未封存、接口
404。414 → 422 passed。
|
2026-09-25 15:59:32 +08:00 |
|
ThearchyHelios
|
429398a156
|
前端四处直接伤人的地方:输入法回车、覆盖别的图、停止不停、整站白屏
1. 中文输入法选词的回车被当成发送。问数据页输入框不判组字状态(Composer 判
了,这里没有):用户每选一个词,半句问题就被送去建图、跑图。同样的漏洞还在
会话重命名、知识库搜索、{{ }} 补全、⌘Enter 运行上。收成 ui.isComposing,六处
统一——Safari 结束组字那一下 isComposing 已经是 false、keyCode 还是 229,两个
都看。
2. 「在画布里打开」后 ⌘S 覆盖上一次打开的工作流。它只调了 setGraph:换掉画布
上的节点,store 里的 workflow 还是上一张图,保存就把那张图整张覆盖了(旧版本
还在版本表里,界面上没有入口找回);没打开过图时 ⌘S 则什么都不做。现在建成
一张新工作流(以这一轮的问题命名)、走它自己的地址,原来的图不受影响。
3. 问数据页的「停止」不停。它只关了自己这头的事件流,从不调 runs.cancel,而后端
断开订阅不会取消运行——模型和 SQL 其实还在跑、还在计费,界面上却已经显示
"已取消"。等人工审批的那一轮照旧不动。
4. Copilot 编出一个不存在的节点类型,整站白屏、没保存的编辑一起丢。三层都补:
- 后端 _apply_op 拒收未知类型,不进图、不转发,最终校验里说明跳过了哪一步;
- 前端流式加节点时再拦一道;sourceHandles、属性面板遇到未知类型不再崩;
- 全站加页面级 ErrorBoundary:导航栏留着,换一页自动恢复;编辑中的图在 store
里,点「重试」时它还在。
新增 scripts/check-guards.mjs(真浏览器,拦下所有非 GET 请求,不写库不花钱):
组字回车与 keyCode 229 不发送、普通回车照常发送、未知类型不白屏、渲染真出错时
只坏这一页且换页恢复,连跑三次全绿。等待一律等事件,只有"不该发生"的断言用
窗口。后端补了未知类型不进图的用例,413 → 414 passed;tsc 通过,decode / stream
/ canvas-layout 三个检查不回归。
|
2026-09-25 15:41:30 +08:00 |
|
ThearchyHelios
|
4559c96fdd
|
出具校验认得中文数字了:"增长三成、客户两千五百家"不再能盖 formal 章
校验器只抽阿拉伯数字。strict 契约下"本周营收增长三成、客户两千五百家"一个数
都抽不出来,判 formal;同样的意思写成 2500 却会被 withheld。叙述层换一种写法
就绕过了"不许现编数字"这条地基,而"出错自动改一次"的复核回路会把模型往这条
路上推——被拦一次,它学会的是写汉字。review.check_numbers 复用同一套抽取,
同样的洞。
中文数字难在两头,规则按"这是不是在报一个量"来定(文件头有完整说明):
- 多字且解析得通的一律抽:十二、两千五百、两千五(省略写法)、一万二、三点五万;
- 单字只在后面跟计数单位时抽:两家、五天。"一"加量词多半是冠词(一个问题),
不抽——放过一个值为 1 的现编,代价远小于满篇误杀;
- 成、倍、百分之、分之、一半单字也抽,按口语精度给容差(三成 = 30% ± 半成);
- 余 / 多 / 来按区间回指(两千余 = [2000, 3000]),不跳过——跳过就是新的绕法;
- 不抽:序数、星期、月日、季度名(三季度 = Q3)、"从三个方面看"这种结构性列举、
几十 / 数百 / 上千这种虚指、成语(五花八门、千方百计、万一、十分重要)。
顺带修了阿拉伯数字的两处:
- 万 / 亿后缀的容差按书写精度算。3.5万 写到千位,应是 ±500,以前按 3.5 的一位
小数给 ±0.05,只认 35000 整——README 承诺的"按书写精度"对带后缀的数不成立。
- 补上千 / 百万 / 千万后缀:"2千家"以前抽出来是 2,回指的是一个错的值。
出具校验以前没有一条直接测试(只经 check_numbers 间接覆盖)。新增 test_issuance.py
39 例:解析、该抽的、不该抽的两头都守,外加当初那条绕过(旧代码实测:抽不到、判
formal)。374 → 413 passed。
|
2026-09-25 15:30:32 +08:00 |
|
ThearchyHelios
|
a819f92903
|
审批只认明确的"同意",而且每个会执行危险操作的地方都得过这道门
三个口子,都实测复现过:
1. 回复"拒绝",工具照样执行。四个节点四套审批解析:工具节点和代码节点对
回复一律 bool(),"拒绝"、"no" 都是真;{"decision": "approve"} 反被当成
拒绝;{"approved": "false"} 也是批准。现在收成一份 engine/approval.py:
只认明确的批准,看不懂的一律按拒绝。填内容的 human input/edit 模式另算——
裸字符串是交稿,只有结构体里明说"不"才驳回。
2. 可写数据源上的 DELETE 从来不问人。数据源工具是动态生成的,查不到
ToolSpec,任何审批模式下都被当成安全;is_dangerous_call 写好了但全仓库
没人调用。现在危险与否逐次判定:registry.call_is_dangerous 统一问,数据源
工具把判定挂在 metadata["dangerous_if"] 上——同一个 db_query,查询直接
跑,可写源上的写要先确认。工具节点、agent 节点、协作成员都走它。
这一步以前没出事,只因为写入从不提交:run_query 走 stream,拿不到结果集就
抛 ResourceClosedError,连接关闭时再回滚——审批通过的写也没落过库。审批接
好之后才让写真正提交(先后不能反,反过来就是一个无审批写库的窗口);
RETURNING 这类带结果集的写照样返回行。工具页的"试一下"是人自己在执行,
不设审批。
3. 协作团队的成员调工具完全不经审批。成员们并行跑在一个节点里、停不下来等
人(恢复时节点整个重放,几个人的 interrupt 对不上号),所以需要确认的调用
不执行,把原因交还给成员让它换做法;节点上显式设成"全部自动放行"才跑。
前端补了这个选项。顺带修了同一处的两个老问题:成员步数不受 max_agent_steps
约束;步数用完时把工具的原始返回当结论交上去(agent 节点在 4057cdc 修过
同一个问题,这里没跟上)——现在补一轮不带工具的收尾。
连带修的:多条审批并存时,交给引擎的是库里存的那份回复,而它存之前被 _safe
截到了 2000 字,解包时又只留 value——人工改过的长稿被砍一截,带了内容的驳回
被当成交稿。现在存全文、只拆自己包的那层 {"value": x}。
test_approval.py 36 例;去掉修复重跑,引擎层 10 例全部失败,各对应一个真问题。
并行驳回那例翻出了一个运行卡死的老 bug,已在上一个提交单独修掉。
338 → 374 passed,连跑三次全绿。
|
2026-09-25 15:21:20 +08:00 |
|
ThearchyHelios
|
26ff8e1e06
|
只读数据源真的只读了:WITH … DELETE 不再从首关键字下面钻过去,连接本身也写不进去
守卫只看首关键字,而 with / pragma 都在只读白名单里。在只读的 SQLite 源上
实测:`WITH k AS (SELECT 1) DELETE FROM t` 被放行,5 行删得只剩 2 行;
`PRAGMA user_version = 7` 也写进去了。调用方只看到一个 ResourceClosedError——
pysqlite 只在 INSERT/UPDATE/DELETE 开头的语句前隐式开事务,WITH 开头的直接
自动提交,连接关闭时的回滚兜不住。Excel/CSV 上传生成的正是这种 SQLite 源。
两层一起收:
守卫:以查询开头的语句(SELECT / WITH / EXPLAIN)要把正文扫一遍,先抹掉注释
和引号里的内容,再找写关键字(DELETE、UPDATE、INTO、FOR UPDATE、EXPLAIN
ANALYZE 里的语句……),关键字后紧跟 ( 的是同名函数不算(MySQL 的 INSERT()、
TRUNCATE())。PRAGMA 改成只读白名单,`= 值` 和 `(值)` 两种赋值写法都拦。
另收一小撮有副作用的函数,其中 set_config 必须拦:PG 真库实测,它能把连接层
的只读关掉,同一连接的下一个事务就能写。函数名加引号、dblink 另开连接这两种
绕法也补上了。is_write 与只读判定共用一份判定,免得审批那道门另有一套口径。
连接层:只读源连接时就只读(engine_args)。SQLite 以 mode=ro 打开(file: URI,
路径带空格、中文、# 都测过);PostgreSQL 设会话默认事务只读;MySQL / MariaDB
设会话事务只读。Oracle 没有会话级开关,只剩守卫——README 写明请配只读账号。
真库验证(临时实例,已清理):PostgreSQL 18 与 MySQL 8.0 上,DELETE、WITH … DELETE、
PG 的数据修改 CTE、nextval、EXPLAIN ANALYZE 绕过守卫直连执行,都被数据库以
只读事务拒绝;可写源不受影响。
测试:守卫新增 33 例(藏在查询里的写、会写的 PRAGMA、同名函数与引号标识符不误杀),
去掉修复重跑是 17 例失败;test_readonly_source.py 6 例(当初那条绕过、绕过守卫
直连写、中文路径、可写源不受波及、各库的会话参数)。297 → 334 passed。
顺带查到但没在这里修的:可写源上的写操作既不审批也不生效——is_dangerous_call
全仓库没人调用,而 run_query 从不 commit,写完就被回滚。两件事必须一起修
(先接审批再让写入生效,反过来就是一个无审批写库的窗口),放在审批统一那一步。
|
2026-09-25 14:44:56 +08:00 |
|
ThearchyHelios
|
66cc96b463
|
汇合节点只跑一次:长短支路不再把它触发两遍,循环的 done 出口也不再被提前放行
多条边汇入同一个节点时,编译器对每条入边各 add_edge 一次。LangGraph 对这种
接法的语义是"任一上游跑完就触发一次":两条支路一样长时,两次触发落在同一步
被合并,看不出问题;一长一短时,汇合节点先拿短支路的结果跑一次,长支路到了
再跑一次——模型调用、工具副作用、下游全部翻倍。循环体里更糟:每轮汇合两次,
循环节点就多推进一格,done 出口在循环跑到一半时就放行了,成果节点跑了 3 次。
README 写的"自动等待汇聚"只在支路等长时成立。
修法是给汇合节点加 defer(等图里其余待执行的任务都跑完再跑一次),而不是
屏障 add_edge([a, b], j):分支之后的二选一汇合,没走的那条永远不会到,屏障
会一直等,而 LangGraph 没有可执行任务时会安静结束——汇合节点和下游就被无声
跳过。代价写在 _join_nodes 的注释和 README 里:它也会等图里无关、恰好在跑的支路。
汇合 = 两个以上前向上游,循环回边不算。回边识别因此从 layout.py 挪到
schema.back_edges,加了 roots 参数:执行语义要从入口起 DFS,否则循环体里的
前向边可能被误判成回边;排版照旧按节点顺序起算,行为不变(check-canvas-layout
全过)。
新增 test_fan_in.py 5 例:长短支路、循环体内汇合(修前分别跑了 2 次和 4 次);
二选一汇合、被分支剪掉一路的汇合(守着别把修法做成屏障);回边不算汇合。
292 → 297 passed。内置模板里 ③④ 的成果节点是二选一汇合,行为不变。
|
2026-09-25 14:33:56 +08:00 |
|
ThearchyHelios
|
8905fe5e60
|
多 agent 节点在画布上展开协作矩阵,运行时的动效统一成一套语汇
多 agent 节点原本是个黑盒:卡片转三十秒圈,然后吐一段文本。"它同时派了三个
人"、"谁还在跑"、"并行到底省了多少"全都要点开右栏才知道,而右栏是线性的
时间线,看不出并发的形状。
现在它跑起来会在卡片里展开一块协作矩阵。三条设计上的选择:
- 花名册固定在原地,不按派单顺序重排——几轮下来眼睛知道谁在哪一行
- 条形长度按**这一轮里最慢的那个人**归一化。三个人并排三条长短不一的条,
墙钟为什么等于最长那条、而不是三条之和,不用解释就看懂了;页脚给出
并行一共省下多少
- 本轮没被派到的人不显示成"待命",而是留着上一轮的成绩(压暗)——它已经
交回来了,说它待命是错的,看的人会以为它还没干活
矩阵和右栏泳道读的是同一份翻译:把 decodeRun 里那段攒泳道的逻辑抽成
reduceTeam(不可变,每次返回新对象,画布那份挂在 zustand 上需要新引用)。
两边各写一遍的话,同一次运行在右栏和画布上会给出不同的并行度——而"几个人
同时在跑、省了多少"正是这个节点唯一值得看的东西。抽完之后 check-decode
一条没红。
其余节点按同一套语汇动:边框上转一圈光弧 + 扫描线 = 正在跑,绿色扫一遍 =
刚跑完(只扫一次——常驻动画会让整张画布一直在动),短促抖动 = 刚失败,
琥珀呼吸 = 在等人。循环卡片显示"第 1/5 轮";分支跑完点亮命中的出口、压暗
其余,实际走过的边留在画布上,那就是这次的执行路径。连线上的虚线换成顺着
路径跑的光点:虚线只让人觉得"在动",光点能看出往哪走,速度按路径长度归一化
(长边上的光点走得慢会像卡住了)。
原来那个往外扩的声纳圈(pulse-ring)删掉了。同一个意思说两遍只会更吵,而且
声纳扩出去会和邻居卡片的边框糊在一起。
一个前提先验证过:offset-path 在 SVG 子元素上能不能对齐路径。测下来和
getPointAtLength 的位置差 0px,才敢用它。
排版要按**展开后**的高度给多 agent 节点留位置(layout.py 的 _height 按名册
人数算)。不留的话它一跑起来就盖住下面那张卡,而且运行结束后矩阵不会收起来
(那正是要回看的东西),重叠是永久的。
前庭敏感的人由 prefers-reduced-motion 兜住:光弧、扫描线、流光条、光点整体
不绘制,而不是把时长压到 0.01ms——那样它们会停在动画的最后一帧,光弧卡在
角落、光点全堆在起点,看着像渲染坏了。静态下"谁在跑"由实心圆点和"进行中"
三个字承担。
新增 scripts/check-canvas-fx.mjs:把脚本化的事件灌进 store(走的是页面上那一份
applyEvent / NodeCard / FlowEdge,只有事件来源是脚本),断言协作矩阵真的长出来、
并行度算对、条形长度和耗时成正比、分支命中的出口被点亮、关掉动效时光效确实不
绘制。真跑一张多 agent 的图要连模型、要等十几秒,而且撞不上"三个人同时还在跑"
那一瞬间——那样的检查会变成偶发失败。另外用仓库里 fixtures.json 那份真实导出
的事件验过一遍,含老运行那种只有中文消息串的 log(走正则兜底)。
顺手修掉检查脚本互相下绊子:check-canvas-fx 原来会留下一张没坐标的工作流
(节点全叠在原点),而 check-ui 打开 /studio 会落到"最近更新"的那张上,于是
点节点被挡住。现在落库前先让后端排好版。
292 passed(新增 2 条:展开的多 agent 卡片必须在排版里留出位置)。
|
2026-09-25 12:47:07 +08:00 |
|
ThearchyHelios
|
75be5f485e
|
画布上的线不再叠在一起:排版按车道留走廊,走线不再交给 smoothstep
原来所有边都交给 React Flow 的 smoothstep,它的竖直段一律落在源和目标的
正中间。同一列的边于是全挤在同一个 x 上:一张"入口扇出三路 → 归并 → 分支
→ 出具/驳回"的图上,跨层的 a3→join 和 m2→join 的横段**完全压在同一条线
上**,长边还直接从"归并B"卡片中间穿过去。排版那边同样糙:同层按 id 字典序
竖排,所以 out_no 排在 out_yes 上面("n" < "y"),分支的 yes/no 是反的;
层内没有任何减少交叉的排序;层间距写死 300。
后端 app/engine/layout.py 重写成分层布局:先剔回边再按最长路径分层(loop
的回边不参与分层,否则循环体会被压到循环节点左边);层内中位数启发式上下扫
六轮取交叉最少的一版,分支/循环的出口再按声明顺序占位重排;y 先均匀堆叠再按
邻居重心迭代松弛,同列节点因此和上下游对齐,长边也走得直;最后按"穿过这条
走廊的连线在竖直方向最多重叠几条"给走廊留宽——区间图上的贪心染色,和前端
用的是同一套,走廊留窄了前端再聪明也只能把线叠起来。
前端 canvas/routing.ts 自己算走线:出边沿右边缘错开、入边沿左边缘错开(入边
按上游纵向位置排序),竖直段按区间染色分配车道——真叠在一起的才各占一条,
首尾相接的(同一个扇出点)共用一条,看起来就是一条总线;跨层的长边和循环的
回边在中间各列的纵向占用里找空档绕过去,不再压过卡片。边换成自定义组件后
React Flow 不再自动加动画类,实测确认 .edge-active 仍然生效。
顺带修掉"排完版看不见图":整张图换过坐标后(自动排版 / Copilot 生成完 /
切图)自动重新取景。坐标变了视角没变,人盯着的是一片空白。
新增 scripts/check-canvas-layout.mjs:把夹具图交给真后端 /api/copilot/layout
排版,再直接 import('/src/canvas/routing.ts') 用页面上跑的那份代码算路径,
按几何断言没有两条线压在同一段上、没有线穿过别人的卡片、两端都接在节点边缘,
另有 1325 条随机坐标的 fuzz 防手拖之后算出 NaN 路径(NaN 的 path 什么都不
画,界面上就是"线没了",一声不吭)。这条检查做过变异验证——把 laneX 改成
永远返回走廊中点,它立刻报 a3→join × m2→join,正是原图上那处重叠。
285 passed(新增 12 条排版不变量)。check-ui 69 项通过,唯一失败项"本地哈希
要标出没有语义能力"已 git stash 到基线复现,与本次无关。
|
2026-09-24 22:58:54 +08:00 |
|
ThearchyHelios
|
69129bba9c
|
Add license section to README
Added licensing information and usage terms to README.
|
2026-09-23 16:22:44 +08:00 |
|
ThearchyHelios
|
4d237c3b08
|
重写 README:加入实机截图与架构图,改为陈述性技术文档
原 README 停留在 9 月 14 日,且没有任何图示。这一版补齐了此后落地的能力,
并把语气从口语转成技术文档该有的陈述式。
**图示。** 4 张实机截图 + 3 张 mermaid 图:
- 运行中的画布(主图):已完成节点标绿、执行中节点高亮、右栏实时时间线,
一张图说清"运行时逐节点观察执行过程"这句话
- 人工审批分支、出具链路、多 Agent 协作三张流程图,按节点包围盒裁剪,
不带侧栏——README 里看流程结构不需要连带半屏 UI
- 三层编排关系、出具链路、系统架构三张 mermaid(GitHub 原生渲染,
无需图片文件),已逐块用 mermaid.parse 验证可解析
截图由一个空数据目录启动的临时实例产出(AGENTLAB_DATA_DIR 指到 /tmp),
只含内置模板和 Mock provider,不含任何真实数据——README 里的图不该把
谁的生产库名和用户邮箱印出去。这一点在文末也写明了。
**补上此后落地的能力:** 对话式取数与会话持久化、URL 寻址、断点续跑、
产出复核(规则扫描 + 不得新增数字的机械校验)、Excel/CSV 转可查的表、
PowerPoint 解析、倒排索引与模型重排、向量模型接本地端点。
**检索那段给了实测表格**而不只是一句"混合更好":纯向量 81% 低于纯关键词 88%、
混合加 Qwen3 到 94%、再加重排 100%,并注明样本只有 16 题、单题即 6 个百分点,
方向可信而精度不可过度解读。
**语气。** 去掉"看着它跑""拍板""直接玩""照实说""纯属白花钱"这类说法,
改成陈述句。但保留原有的如实披露:Seatbelt 限不住内存、microVM 首次拉镜像
54.5 秒、以及 UDP/53 堵不上导致 DNS 隧道外泄通道始终开放——后者单独用引用块
提到显要位置。写清楚缺口是专业的一部分,不是减分项。
文中引用的数字逐条核过:271 个测试、15 个内置工具、16 种节点、8 个模板、
四个可选依赖 extra 的名字。图片路径和目录锚点全部可解析。
|
2026-09-20 18:43:33 +08:00 |
|
ThearchyHelios
|
cdf7f9fc9d
|
README:说清 microVM 的三步安装都是一次性的
原文把一次性设置放在「怎么启用」标题下紧跟命令,容易读成每次启动都要跑。
另外那条 pip install 对用 environment.yml 建环境的人本来就是多余的。
|
2026-09-14 14:16:36 +08:00 |
|
ThearchyHelios
|
7d00c24ab1
|
microVM 沙箱后端:内存限额终于真限得住,但网络关不干净
Seatbelt 在 macOS 上最难受的缺口是 RLIMIT_AS 不被强制——设 256MB 仍能分配
900MB。microVM 不是"更严格的访问控制",是换了一类边界:宿主 Darwin 27.0.0,
VM 里 Linux 6.12.99(libkrunfw),PID 1 是 init.krun,/Users 根本不存在,
free 只看得见 512MB。申请 900MB 会被 OOM killer 杀掉而 VM 照常存活。
实现按实测契约写,不按别的 SDK 的惯例推断:create() 直接返回已启动的
Sandbox,没有 handle/connect 两层;cwd/env/timeout 都是 exec 的原生参数;
超时抛 ExecTimeoutError 而不是返回非零码。
必须写明的缺口:network=false 时 HTTP/HTTPS 与域名解析都断得掉,但 UDP/53
拦不住,手写 DNS 包仍能拿到真实响应。default_egress=DENY、Rule.deny_dns()、
显式 deny UDP、max_connections=0 全试过都堵不上——deny_dns 生成的规则只针对
宿主,DNS 出口在 microsandbox 网络栈里是硬编码放行的。所以 health 里 network
标成 partial 而不是 true,设置页对应显示黄色「部分生效」:拦了一半要是显示成
全绿,比显示成全红更危险。
成本也照实说:首次拉 OCI 镜像实测 54.5s,之后热启动 0.19s、执行 7~30ms。
贵的只是第一次,所以 auto 在镜像没缓存时先用 Seatbelt,不让人干等一分钟;
显式选 strict 档不受此限——那是使用者自己要的硬隔离。
端到端 17 项验证通过:隔离、内存拦截、超时 124、退出码透传、多文件与 env、
会话间互不可见、VM 回收。Seatbelt 那档回归未受影响。
|
2026-09-14 14:10:10 +08:00 |
|
ThearchyHelios
|
e905426dfe
|
发布门禁、操作者归属、治理遥测与前端支撑
审批记录批准人(X-Actor 先落库再恢复执行)。设置页可配操作者署名,
随请求头发送——这是归属记录不是身份认证,界面上写明了区别。
治理遥测三件套,全部从既有事件流取材:
- 工具白名单衰减报表:授了权但从未用过的工具摆上台面,放宽可被回收
- 探索问题聚类:同一问题反复出现(≥3 次)标记为晋升候选——模板生长
的触发器
- 轨迹→模板提取器:把探索性运行实际走过的路径确定性提取成草稿工作流
(剪掉未走的分支、输入参数化),人审发布后才成为模板——探索层的
价值在路径沉淀,不在单次答案
前端:口径卡节点与指标编辑器、出具契约配置、发布对话框(两级门禁、
问题列表)、试运行/正式运行双按钮、出具档位横幅(含缺数据声明与
未回指数字点名)、运行列表正式/探索徽标、运行详情版本与清单哈希、
提取模板按钮。
真模型验证闭环:周报模板 governed 发布 → formal 运行,Opus 5 正文
数字全部回指,但结尾'(约 100 字)'被校验器抓住降档——修 prompt
禁元话语而非加白名单,重发 v2 后正式档。8/8 模板回归通过。
|
2026-09-14 10:27:13 +08:00 |
|
ThearchyHelios
|
dd57c12016
|
沙箱改用系统自带的隔离原语,移除 Docker 依赖
跑一段不可信代码不需要一整套容器运行时。macOS 用 Seatbelt
(sandbox-exec,系统自带),Linux 用 bubblewrap;冷启动从 ~250ms
降到 ~25ms,且不再需要装任何东西。
守住三件事:默认断网、家目录不可读、只有工作区可写。策略由内核
强制且对子进程继承——沙箱内 subprocess 出来的 cat 读家目录同样是
Operation not permitted。解释器改用 sys.base_prefix 下那个干净的
Python,沙箱代码因此 import 不到后端的 FastAPI、SQLAlchemy 和凭据
处理代码。
如实标注能力边界,不给虚假的安全感:
- macOS 不强制 RLIMIT_AS,内存限不住(实测设 256MB 仍可分配 900MB),
health 接口申报 enforced 字段,界面把限不住的项划掉
- Seatbelt 是访问控制而非虚拟化:进程表共享,以当前用户身份运行
- bubblewrap 侧多隔离 PID/IPC/挂载视图,内存限额真实生效
顺带修两个 bug:
- LocalSandbox 设 RLIMIT_NPROC=64 会误伤——macOS 上它按 uid 全局
计数,用户已有上千进程时沙箱内任何 fork 都失败,连 bash 都起不来
- 模型所属 provider 被停用时,原先静默换一家继续用原模型名,必然
404 且报错指不到原因;改为直接说清是哪个 provider 被停用了
写 SBPL 的坑记在注释里:(deny default) 会让 Python 直接 SIGABRT,
改用「默认允许 + 精确拒绝」。
7 个模板全部回归通过。
|
2026-09-13 18:04:36 +08:00 |
|
ThearchyHelios
|
964eeaa829
|
AgentLab:可视化 Agent 编排实验台
在画布上拖拽编排 agent 工作流,并实时看着它执行。
后端 FastAPI + LangGraph:把画布 JSON 编译成 StateGraph,15 种节点
(模型/Agent/多Agent、工具/沙箱、分支/循环/子图、记忆/检索/整形、
人工介入/结构校验)。选 LangGraph 是因为可视化编排真正难的是暂停、
恢复和回放,而 checkpointer + interrupt() 正好把这几件事做在了底层。
前端 React + React Flow:节点元数据驱动属性面板与连接桩,运行时
节点高亮、边流动画、卡片内流式 token 全部由同一份事件流驱动。
关键实现:
- Agent 内工具审批用 @task 缓存模型调用,interrupt 重放时不重复计费
- 沙箱保持只读根文件系统,代码经 exec+base64 写入(put_archive 会被
只读容器拒绝),断网、非 root、内存/CPU/超时限额
- 检索为向量与 BM25 混合,本地哈希 embedding 零配置可用
- 分支条件走 AST 白名单求值器;HTTP 工具逐 IP 拦截内网与元数据地址
- Mock provider 让无 API Key 也能跑通完整链路
7 个内置模板全部冒烟通过,含真实模型端到端验证。
|
2026-09-13 17:27:00 +08:00 |
|