Hive Agent 用量与状态追踪:本地遥测能力盘点与云上可见架构方案
【免费下载链接】hiveMulti-Agent Harness for Production AI项目地址: https://gitcode.com/gh_mirrors/hive48/hive
本文基于 docs/internal/agent-usage-and-status-tracking.md 能力文档展开,面向 Lead Architect 与前端/业务侧读者。文章系统梳理 Hive 运行时在事件总线、三级运行日志、LLM 用量记账、Colony 进度库、任务面板、HTTP 接口与 Worker 健康快照七个层面今天已经具备的遥测能力,逐一对照"云上可见"业务诉求给出差距矩阵、数据模型提案、表面 API 与分片落地路线。读完本文,你将能评估 Queen → Colony → Worker 整棵代理树的状态与用量追踪可行边界,并理解"本地优先、Outbox 上云"这一核心架构决策的前因后果。
1. 为什么需要这份能力盘点
Hive 的业务侧存在一个明确诉求:从 Queen 代理开始,追踪Agent 用量(消耗了什么:Token、成本、运行时长、调用次数)与Agent 状态(代理处于什么状态:存活、阶段、进度、阻塞),并将这些数据呈现在云端,供产品与业务侧消费。
选 Queen 作为锚点是正确的:当前每个本地运行时会话都以 Queen 开始,而每个 Colony / Worker 都由 Queen 调用 fork 而来——以 Queen 为根的追踪面天然覆盖整棵代理树。
给架构师的头号约束:运行时是"本地优先"(local-by-default)。本文 §4 描述的每一字节数据——事件、运行日志、进度库、会话状态、LLM 成本数字——都写在用户机器上的
~/.hive/(或桌面端按平台指定的 ElectronuserData目录)中。今天没有任何数据上云。因此业务诉求隐含了一个全新的"本地 → 云"传输边界,以及随之而来的数据驻留、隐私与身份决策。§4.5 逐表面点明差距,§8 列出风险,§9 将云上切换(cloud cut-over)定义为任何 "Slice 2+" 工作的门禁决策。
2. 术语表——这套代码库里的准确含义
| 术语 | 在本代码库中的定义 |
|---|---|
| Session | 一个 Queen 运行时实例。ID 格式session_{YYYYMMDD_HHMMSS}_{uuid8},持久化于~/.hive/sessions/{session_id}/。 |
| Queen | 长生命周期对话代理,每个 Session 一个,单事件循环节点。阶段:independent → incubating → working → reviewing。参见 Queen 节点定义。 |
| Colony | 由create_colonyfork 出的持久化无状态容器,拥有独立的 SQLite 进度库~/.hive/colonies/{colony_name}/data/progress.db。 |
| Worker | 在 Colony 内执行任务的临时代理(ephemeral agent)。 |
| Run / execution | 节点内一次"触发器到完成"的调用,携带run_id、execution_id、trace_id(OTel 对齐)。 |
| Usage(用量) | 定量消耗:输入/输出/缓存 Token、USD 成本、墙钟延迟、工具调用次数。 |
| Status(状态) | 定性状态:阶段、存活/停滞、当前任务、阻塞于、队列深度、最后心跳。 |
3. 现状盘点——今天已经具备的能力
运行时已经高度埋点。业务侧想要的大部分数据已经被发出——真正的差距在于持久化、聚合与稳定的 API 面。
3.1 事件总线——整套追踪的脊椎
core/framework/host/event_bus.py 定义了进程内异步发布/订阅总线,拥有40+ 事件类型,按stream_id、session_id、colony_id、execution_id、run_id、correlation_id、timestamp进行作用域划分。
与用量/状态相关的事件类别:
- 生命周期:
EXECUTION_STARTED/COMPLETED/FAILED/PAUSED/RESUMED/RESURRECTED - Queen:
QUEEN_PHASE_CHANGED、QUEEN_IDENTITY_SELECTED - Colony / Worker:
COLONY_CREATED、WORKER_COLONY_LOADED、WORKER_COMPLETED、WORKER_FAILED、SUBAGENT_REPORT - LLM:
LLM_TURN_COMPLETE、LLM_TEXT_DELTA、LLM_REASONING_DELTA、CONTEXT_USAGE_UPDATED - 工具:
TOOL_CALL_STARTED、TOOL_CALL_COMPLETED、TOOL_CALL_REPLAY_DETECTED - 健康:
NODE_STALLED、NODE_TOOL_DOOM_LOOP、STREAM_TTFT_EXCEEDED、STREAM_INACTIVE、STREAM_NUDGE_SENT - 任务(右侧面板):
TASK_CREATED、TASK_UPDATED、TASK_DELETED、TASK_LIST_RESET - 触发器:
TRIGGER_AVAILABLE/ACTIVATED/DEACTIVATED/FIRED/REMOVED/UPDATED
从源码看实现细节(event_bus.py):
- 事件载体是
AgentEventdataclass,序列化字段包含type、stream_id、node_id、execution_id、data、timestamp、correlation_id、colony_id、seq、run_id——seq是EventBus.publish()分配的单调递增计数,前端可用它在磁盘历史与实时 SSE 回放两条路径间去重。 - 订阅支持
filter_stream/filter_node/filter_execution/filter_colony四维过滤,且每个 handler 有 15 秒硬超时(_HANDLER_TIMEOUT_SECONDS),防止慢订阅者冻结发布方。 - 持久化现状:内存驻留 + 可选 JSONL 导出。设
HIVE_DEBUG_EVENTS=1(或true/full)时写入~/.hive/event_logs/<ts>.jsonl,设置具体目录(如HIVE_DEBUG_EVENTS=/tmp/ev)则写入该目录。目前没有 SQL 事件表。 - 会话事件还会通过
set_session_log()落盘到该会话的events.jsonl;其中_STREAMING_DELTA_TYPES(CLIENT_OUTPUT_DELTA、LLM_TEXT_DELTA、LLM_REASONING_DELTA)会被内存聚合,直到LLM_TURN_COMPLETE时合并为一次快照写入——这正是 §8 风险 1 里"不要写 delta、写LLM_TURN_COMPLETE"的现有实现雏形。落盘副本还会剔除full_request这类诊断级大字段(_DISK_STRIPPED_DATA_FIELDS),避免事件日志膨胀到数十 MB。
3.2 三级运行日志(按会话)
core/framework/tracker/runtime_log_schemas.py 定义了三级 Pydantic 模型:
| 级别 | Schema | 文件 | 粒度 |
|---|---|---|---|
| L1 | RunSummaryLog | summary.json | 每次图运行——总量 +execution_quality+trace_id |
| L2 | NodeDetail | details.jsonl | 每个节点——exit_status、输入/输出 Token、latency_ms、retry/accept/escalate/continue 计数 |
| L3 | NodeStepLog | tool_logs.jsonl | 每个 LLM 步骤——工具调用、verdict、错误堆栈、latency_ms |
存储位置:~/.hive/sessions/{session_id}/logs/,由 runtime_log_store.py 管理。
从源码看字段细节:
- L1
RunSummaryLog携带run_id、agent_id、goal_id、status(success/failure/degraded)、total_nodes_executed、node_path、total_input_tokens、total_output_tokens、duration_ms、execution_quality(clean/degraded/failed)以及 OTel 对齐的trace_id、execution_id。 - L2
NodeDetail记录exit_status(success/failure/stalled/escalated/paused/guard_failure)、accept_count、retry_count、escalate_count、continue_count、needs_attention与attention_reasons。 - L3
NodeStepLog内嵌ToolCallLog(tool_name、tool_input、result、is_error、start_timestamp、duration_s),并带verdict(ACCEPT/RETRY/ESCALATE/CONTINUE)。
关键点:Schema 已携带 OTel 字段(trace_id、span_id、parent_span_id)——已就绪,尚未导出。测试覆盖可参见 core/tests/test_runtime_logger.py。
3.3 LLM 调用记账
core/framework/llm/provider.py 中的LLMResponsedataclass 携带:model、input_tokens、output_tokens、cached_tokens、cache_creation_tokens、cost_usd、stop_reason。成本由 core/framework/llm/model_catalog.py 在模型有定价时计算;无定价时cost_usd为0.0。
两个易误读的语义(源码注释明确):
cached_tokens/cache_creation_tokens是input_tokens的子集(provider 在prompt_tokens内上报),不要累加到总量上;cost_usd = 0.0表示"未上报",而非"免费"。
差距:成本活在响应对象里并滚入 L2/L3 日志,但不在事件总线流中,也不在任何聚合查询面上。
3.4 Colony 进度库
core/framework/host/progress_db.py 提供每个 Colony 独立的 SQLite(WAL 模式)进度库:
tasks(id、seq、priority、goal、status: pending|claimed|started|completed|failed、worker_id、claimed_at、started_at、completed_at、retry_count、last_error)steps、sop_checklist、colony_meta
源码补充的并发与生命周期细节:
- 建库即开
PRAGMA journal_mode = WAL、synchronous = NORMAL、foreign_keys = ON、busy_timeout = 5000,让 100 个并发 Worker 不至于串行化; - Worker 不持有长连接,每次调用走
sqlite3CLI,天然在 LLM 回合间释放锁; - 任务认领用
BEGIN IMMEDIATE; UPDATE tasks SET status='claimed' WHERE id=(SELECT ... LIMIT 1)原子完成; - 主机启动时跑陈旧认领回收(stale-claim reclaimer):超过
stale_after_minutes的认领退回pending并递增retry_count,达到max_retries则置为failed。
这是目前最接近"状态 SQL 存储"的东西,但它是按 Colony、任务形状的——不是按会话形状,也不是用量形状。测试见 core/tests/test_progress_db.py。
3.5 Queen 任务系统(右侧面板)
IDE 选择提示描述的任务机制是真实的:每次task_update都会向总线发出TASK_UPDATED,未来的 SSE/WS 面可以流式输出。状态迁移:pending → in_progress → completed。任务体携带subject、active_form、blocks、blocked_by、metadata。源码见 core/framework/tasks/events.py 的emit_task_created/emit_task_updated/emit_task_deleted。
源码补充:任务事件默认落在stream_id="primary",并通过set_bus_resolver()把session_id → 该会话自己的 EventBus解析,确保 SSE 连接的任务面板能收到对应 Colony 的实时 diff,而不是被"最后启动的会话"覆盖。
3.6 HTTP 面(已上线)
core/framework/server/routes_sessions.py 已提供:
POST /api/sessions— 创建GET /api/sessions/{session_id}— 当前状态,含queen_phase、queen_model、colony_id、uptime_seconds(源码确认响应里直接计算round(time.time() - session.loaded_at, 1))GET /api/sessions/{session_id}/stats— 运行时统计(扩展点)GET /api/sessions/{session_id}/events/history— 回放已持久化事件
SSE 原语已存在于 core/framework/server/sse.py(SSEResponse封装 aiohttpStreamResponse,设置text/event-stream、no-cache、X-Accel-Buffering: no等头),但尚未挂接到全局事件流路由——这正是实时状态流的自然挂载点。
3.7 Worker 健康快照
get_worker_health_summary()(core/framework/tools/worker_monitoring_tools.py)返回:session_id、session_status(running/completed/failed/in_progress/unknown)、total_steps、recent_verdicts、steps_since_last_accept、last_step_time_iso、stall_minutes、evidence_snippet。当前在 Queen 的 WORKING 阶段使用,可通过 API 暴露。源码补充:session_id可省略,此时按storage_path/sessions自动发现最近会话,注册时可传default_session_id以规避冷恢复后误选陈旧孤儿会话。
4. 每一字节数据今天住在哪里(数据驻留地图)
所有存储位置都在终端用户机器上。没有云 sink、没有遥测端点、没有托管数据库、没有分析服务。 core/framework/server/ 里的 HTTP 服务绑定 localhost 供桌面 UI 使用,它不是云 API。
HIVE_HOME默认~/.hive/,桌面 shell 会覆写为平台userData目录(macOS 如~/Library/Application Support/Hive/,Windows 如%APPDATA%\Hive\)。源码见 core/framework/config.py 的_resolve_hive_home()——优先读HIVE_HOME环境变量,否则Path.home() / ".hive"。
| 数据 | 磁盘位置(每台机器) | 格式 | 生命周期 | 目前是否离机 |
|---|---|---|---|---|
| 事件总线流 | 仅进程内内存 | Python 对象 | 进程生命周期 | 否 |
| 事件调试日志(opt-in) | HIVE_HOME/event_logs/<ts>.jsonl,当HIVE_DEBUG_EVENTS=1 | JSONL | 用户删除前 | 否 |
| 会话状态 | HIVE_HOME/sessions/{session_id}/state.json | JSON | 用户删除前 | 否 |
| 对话 | HIVE_HOME/sessions/{session_id}/conversations/ | JSON | 用户删除前 | 否 |
| 产物 | HIVE_HOME/sessions/{session_id}/artifacts/ | mixed | 用户删除前 | 否 |
| L1 运行汇总(Token、成本、质量) | HIVE_HOME/sessions/{session_id}/logs/summary.json | JSON | 用户删除前 | 否 |
| L2 节点明细 | HIVE_HOME/sessions/{session_id}/logs/details.jsonl | JSONL | 用户删除前 | 否 |
| L3 步骤 / 工具日志 | HIVE_HOME/sessions/{session_id}/logs/tool_logs.jsonl | JSONL | 用户删除前 | 否 |
| Colony 任务 / 步骤 / SOP 状态 | HIVE_HOME/colonies/{colony_name}/data/progress.db | SQLite (WAL) | 用户删除前 | 否 |
| Queen / Colony / Skill / Memory 配置 | HIVE_HOME/{queens,colonies,skills,memories}/ | 文件 | 用户删除前 | 否 |
LLMcost_usd数字 | 进程内由 model_catalog.py 计算,随后写入上述 L1/L2/L3 日志 | — | 与日志相同 | 否 |
这对云需求的含义:架构师的问题不是"数据从哪来"——数据已被完整捕获。问题是**"数据以什么形状、在谁的同意下、离开机器,落在哪里"**。这个决策位于 §6 每个端点和 §5 每个存储选项之前。
三种值得考虑的架构形态(由架构师选择):
- Shape A — 仅设备端,经 LAN/隧道查询。云产品通过经过认证的隧道访问运行时;不复制任何数据。隐私最强,但跨设备汇总最难。
- Shape B — Outbox 推送。运行时把本地存储作为源真相(source of truth),异步把脱敏后的、计费级子集(默认不含 prompt、不含工具参数)推送到云聚合。最适合典型的"Agent 状态看板 + 用量汇总"产品。
- Shape C — 云优先运行时。运行时直接把事件写到云总线,把本地文件当缓存。改动最大,不推荐桌面优先的产品采用。
Shape B 是达成业务结果摩擦最小的路径。本文其余部分默认 Shape B 撰写,并标注 Shape A / C 会在哪些地方改变结论。
5. 能力矩阵——我们能提供什么
每一行是一个候选前端/业务面,按当前状态可行性打分:
| # | 能力 | 状态 | 支撑依据 |
|---|---|---|---|
| 状态 | |||
| S1 | Queen 阶段指示(independent/incubating/working/reviewing) | Ready | QUEEN_PHASE_CHANGED事件 + 会话详情字段 |
| S2 | 任务级进度(右侧面板) | Ready | TASK_*事件 |
| S3 | 实时 LLM 流式指示(打字/思考/调工具) | Ready | LLM_TEXT_DELTA、LLM_REASONING_DELTA、TOOL_CALL_STARTED/COMPLETED |
| S4 | 停滞 / 卡死代理检测 | Ready | NODE_STALLED、STREAM_INACTIVE、NODE_TOOL_DOOM_LOOP |
| S5 | Colony 树(Queen → colonies → workers)快照 | Partial— 数据存在于会话/Colony 存储;需要一次 join 查询 | |
| S6 | 跨 Colony 的 Worker 健康汇总 | Partial— 已有按 Worker 的工具;需要聚合路由 | |
| S7 | 存活心跳("代理 X 最后可见于 Y 前") | Net-new— 必须从事件时间戳推导或新增周期性 ping | |
| S8 | 触发器日程(Queen 下次何时唤醒) | Ready | TRIGGER_*事件 |
| 用量 | |||
| U1 | 每会话 Token(输入/输出/缓存) | Partial— L3 按步捕获、L1 求和;无 API | |
| U2 | 每会话/Colony/模型的 USD 成本 | Partial— 日志中每次 LLM 调用有cost_usd;无汇总 | |
| U3 | 工具调用计数与类型 | Partial— 事件已存在;无聚合 | |
| U4 | 每代理墙钟运行时长与活跃时长 | Partial— 可由EXECUTION_STARTED/COMPLETED推导 | |
| U5 | 按 Queen 派生 Colony 的成本归因 | Partial— 每个事件都有colony_id;需要查询 | |
| U6 | 按用户 / 租户聚合 | Net-new— 事件中目前没有用户/租户身份 | |
| U7 | 日 / 月用量汇总用于计费 | Net-new— 需要持久化事件存储 | |
| U8 | 配额 / 上限强制(超预算拦截) | Net-new— 需要实时计量表 + 策略钩子 |
矩阵解读:约 70% 的"状态"面今天已是可上线级别(薄薄一层本地 API 即可暴露);约 70% 的"用量"面需要持久化 + 聚合层。事件本身不是瓶颈。
同一矩阵的本地 vs 云解读。上面每个 "Ready" / "Partial" 单元格都是在本地机器进程内就绪的。让每一行对云消费者可见需要额外的步骤:
| 能力类别 | 本地(今天 / 近期) | 云(业务诉求) |
|---|---|---|
| 实时状态(S1–S4, S8) | 从进程内事件总线经本地 SSE 流式输出 | 事件经 Outbox 推送 → 云 relay → 云 SSE/WS 到产品 UI |
| 树 / 健康(S5, S6) | join 本地会话 + Colony 存储 | 同样的 join,但跑在会话/Colony 索引的云侧副本上 |
| 存活(S7) | 从本地事件时间戳推导 | 需要运行时主动上报心跳;云无法从"缺席"推断存活 |
| 每会话用量(U1–U5) | 读取磁盘上的 L1/L2/L3 日志 | Outbox 发送持久化行(非增量)到云用量表 |
| 租户汇总(U6–U7) | 不可能——事件中无身份 | 云侧按 session→user join 键聚合,身份在 Outbox 时刻附加 |
| 配额(U8) | 本地计量表可行,但没有云真相就无意义 | 云是计量的权威;运行时"打电话回家"检查 |
6. 数据模型提案(架构师验证)
三个新的持久化实体,加上对现有事件类型的复用:
AgentSession UsageEvent StatusSnapshot ----------- ----------- --------------- session_id (PK) id (PK) session_id (FK) queen_id session_id (FK) taken_at queen_model colony_id phase started_at worker_id active_run_id ended_at agent_role (queen|worker) active_node status (active|done|failed) event_type (LLM|TOOL|...) open_task_count user_id (when multi-tenant) model in_flight_workers tenant_id (when multi-tenant) input_tokens last_event_at total_input_tokens output_tokens stall_score total_output_tokens cached_tokens total_cached_tokens cost_usd total_cost_usd latency_ms total_tool_calls tool_name (nullable) last_event_at occurred_at trace_id execution_id存储选型(架构师决策)。三个选项今天都是本地的;只有 Option C 到达云业务面。
- Option A — 本地 SQLite Outbox,位于
HIVE_HOME/runtime.db。优点:零基础设施、契合桌面端、本地查询便宜。缺点:按主机隔离;无法跨设备聚合;单靠它不满足云需求。 - Option B — 在现有 JSONL 事件日志上跑 DuckDB。优点:零摄取代码;分析师友好。缺点:大历史冷启动延迟;同样仅限本地。
- Option C — 通过 Outbox 模式把事件推到托管云存储(Postgres、ClickHouse、BigQuery)。优点:跨主机汇总、计费级、是唯一真正交付云可见状态/指标产品的选项。缺点:引入新传输、身份、隐私/脱敏叙事;桌面构建需要显式用户 opt-in。
现实形态是 §4 点名的混合:本地用 A作为持久缓冲与源真相,云上用 C作为业务面聚合,由单向 Outbox 搬运脱敏后的、仅持久化事件子集过网。本文推荐该混合形态;§6 与 §7 的所有内容均按它撰写。
7. 表面 API——前端将要消费什么
所有路由假设"事件总线 → SSE 桥"已存在(那条缺失的线,见 §3.6)。前端从第一天起就会看到这些。
本地性说明。下面的
/api/...路由今天由本地运行时 HTTP 服务提供。对云产品,相同形状需要由 Outbox 供给的云侧对应物。两种务实模式:(1) 云产品调用这些路由的云托管版本(针对聚合数据),或 (2) 云产品把经认证的请求代理回用户的运行时。§4 的 Shape A vs Shape B 在二者之间选择。
实时通道
GET /api/sessions/{session_id}/events/stream (SSE) ↳ filter=phase,task,llm_stream,tool,worker,trigger,health GET /api/agents/queen/stream (SSE) — 全局 Queen 事件状态读取
GET /api/sessions/{session_id} — 已上线 GET /api/sessions/{session_id}/tree — Queen → colonies → workers GET /api/sessions/{session_id}/health — stall_score, last_event_at, in_flight GET /api/colonies/{colony_id}/workers — 健康汇总用量读取
GET /api/sessions/{session_id}/usage — tokens, cost, latency, tool-calls GET /api/sessions/{session_id}/usage/by-model — 按模型拆分 GET /api/colonies/{colony_id}/usage — 相同形状,Colony 作用域 GET /api/agents/queen/usage?range=...&group_by=... — 汇总视图(计费)管理 / 业务
GET /api/usage/rollup?range=...&group_by=user|tenant|model|colony POST /api/quotas/{tenant} — 设置上限(若配额工作纳入范围)8. 新增工作清单——按衬衫码(而非天数)估量
| 工作流 | 本地 / 云 | 规模 | 依赖 | 说明 |
|---|---|---|---|---|
| 事件总线 → 本地 SSE 桥(sse.py 已存在,路由没有) | 本地 | S | — | 解锁桌面 UI 的全部实时状态面。杠杆最高的一块。 |
| 持久化本地事件存储(SQLite Outbox) | 本地 | M | 决策 §6 | 单写者、追加式;复用现有 JSONL 写入器。云推送的源真相。 |
本地聚合查询 +/usage端点 | 本地 | M | 持久化存储 | 磁盘上的每会话用量。 |
| Outbox 传输(本地 → 云) | 边界 | M–L | 本地存储 + 认证 | 新工作:持久队列、重试、脱敏策略、opt-in 开关、schema 版本化。通往云产品的桥。 |
| 云事件摄取 + 聚合存储 | 云 | L | Outbox 传输 | 新云基础设施(Postgres/ClickHouse/BigQuery)。托管、运维、保留策略、访问控制。 |
| 云侧状态/用量 API + 看板 | 云 | M | 云聚合 | 对照云存储镜像 §7 端点;这是业务用户实际看到的。 |
| 身份层(事件上的 user_id / tenant_id) | 边界 | M | 认证模型 | 事件中当前无用户身份。身份在 Outbox 时刻附加,而非发射时刻。 |
| OpenTelemetry 导出器(schema 已就绪) | 边界 | S–M | — | trace_id/span_id已填充;OTel collector 可替代自定义 Outbox 作为云 sink。 |
| 配额 / 策略钩子 | 云权威 | L | 云存储 + 身份 | 云持有计量表;运行时在关键路径上同步"打电话回家"。 |
| 存活 / 心跳(S7) | 本地发射、云消费 | S | Outbox | 运行时必须主动上报;云无法从缺席推断存活。 |
| 成本归因 UI 汇总 | 云 | S | 云/usage端点 | 与前端文档共享。 |
首个前端发布(本地桌面 UI)的关键路径:SSE 桥 → 状态端点(S1–S5)→ 每会话用量端点(U1、U2)。其余都是增量。
首个云发布(业务诉求)的关键路径:本地事件存储 → 带脱敏 + opt-in 的 Outbox 传输 → 云摄取 → 云/usage与/status端点。上述本地 UI 工作不是云切换的前置条件,但大多数本地侧原语(事件存储、持久化事件过滤)是共享的,按序做能最小化返工。
9. 架构师应权衡的风险与取舍
- 事件量。
LLM_TEXT_DELTA每个 Token 触发一次。持久化存储必须过滤——不要写 delta,写LLM_TURN_COMPLETE。这是表爆炸的头号原因。(事件总线的_STREAMING_DELTA_TYPES聚合逻辑已展示这种过滤可行性。) - 隐私 / 桌面姿态——核心架构约束。运行时默认本地(config.py)。§4 的数据清单证实今天没有任何数据离开用户机器,包括业务诉求需要在云端的数据。弥合这个差距不是"加一个指标推送"——而是一个新系统边界,涉及:(a) 显式用户 opt-in(默认值必须对 OSS / 自托管用户安全)、(b) 文档化的脱敏清单(默认载荷不含 prompt、工具参数、文件路径)、(c) schema 版本化,避免运行时升级破坏云聚合、(d) 对云 sink 不可达的自托管 / 隔离(air-gapped)部署的明确答案、(e) 国际化销售时的区域数据驻留规则。这是本文档中最大的设计决策。
- 成本表准确性。
cost_usd由静态目录计算。用它计费意味着承诺持续维护目录(或从 provider 发票拉取)。展示场景当前做法够用;计费场景不够。 - 身份耦合。事件目前按会话作用域。到处加
user_id/tenant_id是侵入性的。建议把身份钉在会话边界,查询时按会话 join,而不是把身份穿进每个事件载荷。 - 状态 vs 心跳语义。"空闲"不等于"死亡"。坐在
independent等用户消息的 Queen 是健康的,不应打扰任何人。§6 的 stall-score 必须区分"设计上的空闲"与"出 bug 的停滞"——现有STREAM_INACTIVE/NODE_STALLED事件已经做出区分;保留它。 - 可观测性带来的背压。如果用量追踪位于 LLM 调用路径上(为了配额),它不得增加延迟。建议:计量表对展示是异步/最终一致的;只有配额检查是同步的,且仅在客户有配额时才同步。
- Worker 侧缺口。Worker 的 LLM 调用记在其自己的会话 L1–L3 日志里,但不会自动滚入父 Queen 会话。Queen → 派生 Colony 的成本归因需要 (a) 在 Colony 会话行上加
parent_session_id字段,或 (b) 查询时遍历COLONY_CREATED事件图。(a) 更干净。
10. 推荐:四个薄切片落地
前两个仅限本地并解锁桌面 UI;后两个才是真正交付"云可见状态与指标"这一业务诉求的。
Slice 1 — 实时本地状态(1 个 sprint,全本地)。SSE 桥 +
/sessions/{id}/events/stream+/sessions/{id}/health+/sessions/{id}/tree。前端(本地 UI)获得右侧面板与代理树。无持久化、无云。(S1–S5, S8。)Slice 2 — 每会话本地用量存储(1–2 个 sprint,全本地)。持久化事件存储(
HIVE_HOME/runtime.db的 SQLite Outbox),仅过滤持久化事件类型。/sessions/{id}/usage+/colonies/{id}/usage。无身份、无汇总、尚无云传输。这是云切片骑乘的基础。(U1–U5。)Slice 3 — 本地 → 云 Outbox + 云摄取(云切换,范围定义性工作)。持久化 Outbox 队列、脱敏策略、opt-in 开关、身份附加、schema 版本化、重试/退避。云侧摄取服务 + 聚合存储。这是"仅本地世界"变成"云产品"的地方。架构师必须在此切片启动前定下 §4 Shape、§6 存储、脱敏默认值与身份模型。
Slice 4 — 云汇总、看板、配额(范围与产品 TBD)。租户聚合、日/月汇总、配额强制、OTel 导出、业务看板。(U6–U8。)推迟到业务确认计费模式——答案(按席位 vs 按 Token vs 按 Colony)会改变数据模型。
Slice 1 和 2 大多是接线——事件已存在、schema 已存在、存储路径已存在。Slice 3 是第一个引入新架构边界(本地 → 云传输 + 身份 + 隐私契约)的切片;业务诉求的全部新颖之处都在那里。Slice 4 是业务设计,不是工程范围。
11. 留给架构师的开放问题
前四个是 §4 与 §9.2 所指"本地优先 / 云必需"差距的直接后果。
- 云传输形态——§4 的 Shape A、B 还是 C?该决策位于整个数据模型之前。除非有强隐私理由选 Shape A,否则推荐 Shape B(Outbox 推送)。
- 云载荷的脱敏默认值。什么上云(模型、Token 数、延迟、工具名、状态)vs 什么留本地(prompt、工具参数、工具结果、文件路径、对话内容)?需要在 Slice 3 开始前写好一份 allowlist。
- 自托管 / 隔离(air-gapped)用户。云 sink 不可达或禁用时运行时做什么——无限缓冲、丢最旧、还是拒绝启动?OSS 与 SaaS 分发的默认值不同。
- 身份绑定点。在事件发射时(侵入性,把身份穿进每个节点)、会话创建时(干净,需要会话级认证)、还是 Outbox 刷新时(最简单,但丢失逐事件来源)附加
user_id/tenant_id?推荐会话创建。 - v1 需要配额强制,还是只需要配额可见性?
- 前端文档:状态与用量渲染在同一面板还是不同表面?这决定是发布一个合并端点还是两个。
- 我们是否愿意承担成本表维护负担,还是让"成本"保持"估算"标签、不用于开票?
附录——源码索引
- Queen 生命周期:core/framework/agents/queen/nodes/init.py
- 事件总线 + 类型:core/framework/host/event_bus.py
- 运行日志 schema:core/framework/tracker/runtime_log_schemas.py
- 运行日志存储:core/framework/tracker/runtime_log_store.py
- LLM 记账:core/framework/llm/provider.py、core/framework/llm/model_catalog.py
- Colony 进度库:core/framework/host/progress_db.py
- 任务事件:core/framework/tasks/events.py
- 会话 HTTP:core/framework/server/routes_sessions.py
- SSE 原语:core/framework/server/sse.py
- Worker 健康:core/framework/tools/worker_monitoring_tools.py
- 配置 / 环境变量:core/framework/config.py
- 相关测试:core/tests/test_event_bus.py、core/tests/test_progress_db.py、core/tests/test_runtime_logger.py、core/tests/test_tracker_db.py
一句话总结这份文档的架构取向:事件、日志、成本、任务、健康快照五类遥测今天全部在本地完整捕获;让它们对云可见,本质是"本地 SQLite Outbox 持久化 + 脱敏单向推送 + 云侧聚合/API"这条 Shape B 路径上的工程,而不是"从零开始采集数据"。评估任何追踪需求的正确起点,是 §4 的数据驻留地图与 §5 的能力矩阵。
【免费下载链接】hiveMulti-Agent Harness for Production AI项目地址: https://gitcode.com/gh_mirrors/hive48/hive
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考