Blizzard
|
ef6f525a74
|
refactor(dispatcher): T1.1 退役 graph.go —— 编排引擎收成单一 compose
compose 已默认数天、HITL/多智能体/评测全在其上真实跑过,soak 充分。删掉自研拓扑
解释器这第二套引擎,消灭"双实现 drift"税:
- 删 runGraph(graph.go 的自研解释器)+ composeEnabled/EINO_COMPOSE 逃生舱开关
+ runConversation(仅 runGraph 用的死代码)。
- executeGraph 直接走 runComposeGraph;compose 编译失败兜底改单轮对话(不再回退
graph.go);清掉仅 runGraph 用的 import(otel attribute/trace/otelx)。
- 保留 board / 各节点执行器(retriever/tool/agent/branch/approval/map/render/aggregate)
/ 工具函数 —— 它们是 compose 各节点 lambda 复用的,非 graph.go 专属。
- 测试:8 处 runGraph→runComposeGraph;等价测试(对照两引擎)转为 compose 正确性测试;
runConversation 的开关测试转为「无 ChatModel 降级 runAgent」。
go test ./... 全绿 + vet 干净;冒烟 简单 agent/分支图 跑通。此后每个编排改动不再两边
对齐,成本减半。DEPTH_ROADMAP T1.1 ✅。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-30 08:53:02 +08:00 |
|
Blizzard
|
515cf7f87a
|
feat(hitl): 增量3b —— 持久决定投递 + 生产激活(HITL 中断/恢复上线)
把中断/恢复模型在 dispatcher 接线启用,并让审批决定持久化抗离线。至此 HITL
从「阻塞 goroutine 等 5min、core NATS 非持久、不抗重启」升级为「持久化中断 +
决定持久投递 + 从 checkpoint 恢复续跑」。
- contract: 新增审批决定流 StreamApprovals(SUNDYNIX_APPROVALS)/通配
SubjectApprovalAll/消费者 ConsumerApprovals + checkpoint 桶 BucketCheckpoints。
- bus: EnsureApprovalStream(JetStream 流持久捕获 sundynix.approval.>,MaxAge 24h;
gateway 现有 nc.Publish 的决定被本流自动捕获,无需改 gateway)+ ConsumeApprovals
(持久消费者,队列组多副本安全)。
- orchestrator: HandleApprovalDecision(据 task_id 取 resume 记录续跑;无记录则忽略,
兼容阻塞态任务的决定 + 决定重投幂等)+ finishResumed(收尾对齐 Handle 尾段:
中断/拒绝/预算/失败/成功+评测落历史)。
- main: 开 checkpoint 存储 + 审批流 + 起决定消费者 → SetCheckpoints 启用中断模型;
任一步失败优雅降级回阻塞模型;停机 drain 在途 resume。
决定经 JetStream 持久:dispatcher 在决定发出时离线,重连后仍消费到并续跑;任一
dispatcher 副本都能据共享 KV 的 checkpoint+记录恢复(HA)。
测试:决定驱动恢复(续跑下游+判 done+清记录)、无记录忽略(幂等/兼容)。
全模块 go build + go test 绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-29 13:08:41 +08:00 |
|
Blizzard
|
368938ce89
|
feat(hitl): 增量3a —— resume 重入闭环(从 checkpoint 续跑审批)
把 HITL 的恢复半边补上:人工决定到达后从 checkpoint 重入图、喂给审批节点续跑。
至此中断→恢复全闭环在 compose 路径打通(in-process 端到端测试钉死)。
- runComposeGraph 重构为统一入口 execComposeGraph(rc):rc==nil 全新执行、rc!=nil
从 checkpoint resume,两路共用建图/编译,仅三处分叉——①记忆注入仅 fresh(resume
时黑板由 checkpoint 还原,重注入会覆盖已积累态);②Invoke ctx(resume 经
ResumeWithData 注入决定);③终态黑板来源。
- live 捕获:resume 时 compose 用 checkpoint 还原的实例作 local state(非闭包 b),
故节点 ProcessState 内捕获 live 指针,Invoke 后据此读终态(fresh 仍读 b)。
- resume 记录:中断时把 {interruptID, Task} 落 KV(pending:task_id),供决定在另一
goroutine/重启进程独立重建任务并续跑;终态清记录 + checkpoint(幂等)。
- ResumeApproval(t, dec) 入口:载记录定位中断点 → execComposeGraph resume。续跑
语义同 fresh:再遇审批→errInterrupted、批准跑完→稿+refs、拒绝→errRejected。
测试:批准(黑板无损还原 + 下游执行 + 状态拨回 running + 清记录/checkpoint)、
拒绝(errRejected + 拒绝语 + 下游不跑 + 清 checkpoint)。这条用例也透过 eino 真实
checkpoint 路径端到端验证了 board 序列化(2a)。全量 go test ./... 绿。
下一步 3b:审批决定改 JetStream 持久投递 + orchestrator 持久消费者触发 ResumeApproval
+ main 接 Bus.Checkpoints 打开开关。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-29 12:57:07 +08:00 |
|
Blizzard
|
bc7600625d
|
feat(hitl): 增量2b —— 审批节点改 compose.Interrupt + orchestrator 识别中断
接了 checkpoint 后端时,审批节点从「阻塞 goroutine 等 5min」改为持久化中断:
首次执行发待审 + 置 waiting + compose.Interrupt → compose 把整图状态(含 board)
落进 checkpoint store 并返回中断错误 → Handle 释放 goroutine、任务停在 waiting,
不收尾不评测不判 done。抗 dispatcher 重启。
- orchestrator: 新增 errInterrupted 哨兵 + checkpoints 字段 + SetCheckpoints
setter(沿用 guard/usageSink 的 setter 注入,不动构造签名);Handle 识别
errInterrupted → 释放 goroutine、保留 waiting、SSE 流不关。
- compose_compiler: 编译挂 WithCheckPointStore + WithGraphName("root"),Invoke
带 WithCheckPointID(task_id);审批节点接 checkpoint 时改走专用
approvalInterruptLambda(须把中断错误作节点返回值上抛,泛型 lambda 会吞掉);
ExtractInterruptInfo 识别中断 → 上抛 errInterrupted。
- graph.go: 抽出 approvalSummary / applyApprovalDecision,阻塞式与中断式审批共用,
杜绝两路文案/语义漂移。
双路径并存:未接 checkpoint 后端(store=nil)维持阻塞模型,行为不变;main 暂不
接,生产保持阻塞,待增量3 resume 闭环补齐再打开(建在 flag 后)。
测试:中断半边端到端——errInterrupted + 置 waiting + checkpoint 落 KV(key=task_id)
+ 下游 agent 不执行。既有阻塞式审批/等价测试全绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-29 12:46:48 +08:00 |
|
Blizzard
|
03225e31a9
|
refactor(dispatcher): compose 翻默认 —— 补平三缺口后退役 graph.go 在望
EINO_COMPOSE 默认改为开(留 =0 逃生舱回退权威 graph.go)。翻默认前补平
compose 路径三个会静默吃掉治理能力的缺口:
- HITL 审批:execDSLNode 无 approval 分支 → 审批节点被当未识别跳过、下游照跑;
补 case 调 approvalNode。
- 忠实度评测:executeGraph 把 refs 硬写 nil → 评测静默失效;runComposeGraph
改签名回传 refsOf(b)。
- 终态传播:rejected/fatalErr 不传播也不阻断下游 → 任务误判 done-空;加节点
lambda 入口守卫 + branch cond 守卫 + 终态上抛 errRejected/fatalErr,并让
runComposeConversation 模型失败置 fatalErr(对齐 graph.go 的 break 语义)。
新增等价测试:审批拒绝停下游、refs 回流。go test ./... 全绿。
soak 无回归后即可物理退役 graph.go。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-29 11:13:46 +08:00 |
|
Blizzard
|
446b784fc6
|
feat(harness): RAG 忠实度评测 —— judge 拿检索原文评幻觉
补 Harness 已知洞:此前 LLM-judge 只看 input+output,看不到检索来源,幻觉其实没评。
- Evaluator.Score 增 sources 参数;有来源时走 llmJudgeGrounded:一次调用同时评 quality 质量 +
faithfulness 忠实度,并列出 unsupported(未被来源支持的说法)→ 进 Flags。
综合分(有来源)=0.3规则+0.35质量+0.35忠实;无来源时维持原 0.4规则+0.6质量。Result 增 Faithful 字段。
- 透传检索来源:runGraph 返回 (answer, refs, err),executeGraph 同步;Handle→evaluate(input,output,refs);
refsOf(board)=检索资料+工具产出。compose 路径暂返回 nil refs(不评忠实度)。
- eval 日志增「忠实 X.XX,来源 N」。
测试:单测覆盖 grounded(quality/faithfulness/unsupported 解析 + 加权 + flags)与无来源跳过;
3 处测试 runGraph 三返回值更新。live 实测 RAG 任务忠实 1.00/来源 1,judge 正确判定无编造。
project_analysis Harness 清单勾掉该项。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-25 15:03:17 +08:00 |
|
Blizzard
|
2e927eca0a
|
feat(dispatcher): Eino 采纳 Phase C 完成 —— 全图 DSL→compose.Graph 编译器
把整张 DSL 图编译为 Eino compose.Graph 执行(编排归一):
- compose_compiler.go:每节点=Lambda,节点体复用 execDSLNode(全节点类型);
黑板进 compose 本地状态(WithGenLocalState + ProcessState);branch 走
AddBranch + 状态感知条件(复用 branchNode);边载荷 flowSignal(注册 no-op
合并支持 fan-in,真实数据全走黑板)。
- WithNodeTriggerMode(AllPredecessor) DAG 模式:无依赖节点并行调度(效率)。
- Handle→executeGraph 按 EINO_COMPOSE 开关选 compose/graph.go;compose 编译
失败自动降级回 graph.go(安全网)。默认关,graph.go 仍权威。
等价回归:线性图 + 分支图经解释器与 compose 两路径产出逐字一致(单测);
live 多节点分支图 compose 路径 2800 字答复 eval 1.00、FSM done、0 幽灵;
make test-go 全绿。
过渡期 soak 后翻默认到 compose、退役 graph.go。性能后续:编译图按 DSL-hash 缓存。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-23 11:02:32 +08:00 |
|