:事件契约、权限边界与 Langfuse 导出全解)
OpenWork Models 任务分析models-task-analytics事件契约、权限边界与 Langfuse 导出全解【免费下载链接】openworkThe open-source alternative to Claude Cowork (powered by opencode)项目地址: https://gitcode.com/GitHub_Trending/ope/openwork本文基于仓库 docs/features/models-task-analytics/README.md 展开系统讲解 OpenWork Models 附带的组织级任务分析task analytics功能从组织能力开关modelsAnalytics的灰度逻辑、不可变事件与版本化同意consent的边界设计到事件上报 API、数据表结构、Langfuse 导出通道的源码级实现再到「先迁移、后发布、再放量」的升级顺序与端到端验证。读完你既能独立完成该功能的部署顺序规划也能理解其事件契约与安全边界是如何在 ee/packages/telemetry-contracts/src/models-analytics.ts 等核心文件中落地的。功能定位与放量控制任务分析Task analytics随付费的OpenWork Models订阅提供但默认不生效。它由一个内部组织能力internal organization capabilitymodelsAnalytics控制放量该开关默认关闭。只有放量开启后工作区管理员才会在 Models 页面看到Unlock custom insights入口并可选择Enable task analytics或Not now。关键结论原文档明确购买或启用 Models 本身并不等于授予分析同意consent。所有数据收集、读取与导出必须同时满足四个条件组织已获得modelsAnalytics放量能力存在有效或试用中的 Models 订阅Models 处于启用状态管理员完成显式的、带版本的同意versioned consent当前版本为1。权限模型是双向区分的组织成员只能上报自己的任务只有管理员才能读取组织级分析数据、更改分析设置。事件在组织与成员两个维度上都做了作用域限定scoped运行时事件必须与该成员真实的 Models 请求匹配这一点在服务端会做二次校验见后文 POST events 路由。从流程图可以看出本功能的边界推理路径与订阅计费保持原样本功能不引入任何新的 AI SDK、模型选择或路由层直接 BYOKBring Your Own Key与网关 BYOK 均不在本功能范围内分析错误与模型响应完全隔离绝不会因为分析链路故障而影响聊天。数据边界记录什么、不记录什么原文档对数据边界做了严格定义这是整个功能合规设计的核心不可变事件每条上报的模型调用、工具执行、技能加载都被完整保留。事件使用稳定的事件 ID 做去重重试不会产生重复记录。模型调用记录包含实际上报的模型/提供商、时间、结果、token 数、缓存使用与提供商报告的成本。缺失的计量missing accounting保持为 unknown不推测补全。任务与标识符桌面端集成通过本文档引入的上报 API 追加任务生命周期、可用工具、技能/版本与 MCP 标识符事件契约同时接受有界的自定义标量元数据。标识符覆盖度取决于运行时暴露程度任务上报为 best effort要求桌面端处于活跃且已登录状态。明确排除内容提示词prompts、响应、工具参数/结果、文件内容一律不采集。提示词分类与生成式洞察generated insights不属于当前版本。消费数据定位Consumption 是诊断性数据不替代现有计费账本billing ledger或订阅限额UI 支持的时间跨度最长 90 天。关闭与重开的语义也很重要关闭分析会停止新采集并禁用导出但保留既有历史删除工作区会连带清除分析数据与已存储的集成凭据重新启用后从新的同意时间点开始采集不回填关闭期间的任务。订阅降级或移除放量会拒绝分析访问但不改动既有 Models 密钥后续满足条件的订阅可恢复对已保留历史的访问。事件契约从 schema 看字段与约束事件契约定义在 ee/packages/telemetry-contracts/src/models-analytics.ts由 zod 实现可被桌面端、den-web 与 den-api 三方共享解析。核心约束如下标识符id、sessionId、taskId、callId、tool、skill、mcp等/^[a-zA-Z0-9_.:-]{1,128}$/1~128 字符标签model、provider1~255 字符计数token、durationMs非负整数自定义元数据最多16 个字段键需匹配/^[a-zA-Z][a-zA-Z0-9_.-]{0,63}$/值只能是字符串≤128 字符、有限数字或布尔值。事件类型为七种枚举task.started、task.completed、task.failed、task.cancelled、tool.executed、skill.loaded、model.call。schema 顶部注释明确说明内容采集被刻意排除启用 Models 或元数据分析绝不等于授权内容采集。批上报契约modelsTaskBatchSchema每次 1~50 条并带有一条关键的 refine 规则运行时事件runtime events不得上报模型消费字段——model.call事件之外的事件若携带costUsd、token 或provider等字段会被直接拒绝。消费记录只能由经过认证的推理服务inference service写入这就把「谁可以报账」和「谁只能报元数据」在契约层面强制分开。查询契约modelsAnalyticsQuerySchema约束days为 1~90默认 30分页游标要求before与beforeId成对出现。设置契约modelsAnalyticsSettingsSchema暴露available、subscribed、modelsEnabled、enabled、consentedAt、consentVersion、exportEnabled、langfuseHost、langfuseConfigured等字段是 UI 与桌面端判断「能否上报」的统一依据。服务端 APIsettings / events / activity / consumption四个分析路由集中在 ee/apps/den-api/src/routes/org/models-analytics.ts全部挂在v1/inference/analytics/*下方法与路径权限说明GET /v1/inference/analytics/settings任意成员读取组织分析状态可用性、订阅、Models 启用、是否开启、同意时间/版本、导出状态PATCH /v1/inference/analytics/settings仅管理员开启/关闭采集开启必须满足放量订阅Models 启用且带consentVersion: 1否则返回403 models_analytics_unavailable重复开启不会前移同意时间采集截止点不变关闭会同时关停导出POST /v1/inference/analytics/events任意成员上报该成员真实运行的任务元数据组织未开启时返回204只接受该成员自己 inference 来源的任务且校验上报的taskId/sessionId与数据库中的真实调用记录匹配其他成员的任务或 BYOK 调用一律丢弃GET /v1/inference/analytics/activity仅管理员读取最近days天默认 30最大 90的事件按时间倒序每页 200 条返回next游标可按memberId/taskId/sessionId过滤采集关闭时返回403GET /v1/inference/analytics/consumption仅管理员按model/provider/member/day聚合推理服务写入的消费调用数、失败/不完整调用数、输入/输出/缓存读 token、成本 USD分组超过 10,000 组时返回400 narrow_date_range其中 events 路由的成员匹配逻辑routes/org/models-analytics.ts体现了「运行时事件必须匹配该成员真实 Models 请求」这一原文档原则服务端先用inArray(taskId)查出该成员在本组织的 inference 记录再逐条过滤sessionId一致的事件后才入库。事件落库统一走appendModelsAnalyticsEvents返回acceptedIds供客户端清理待重试队列。存储与迁移两张表 一条 SQL迁移脚本0092_models_task_analytics.sql登记于 ee/packages/den-db/drizzle/meta/_journal.json只新增两张表和索引对推理路径完全无侵入——没有放量的组织根本不会在推理路径上读取新表因此即使应用先于迁移部署Models 也能继续正常工作。表结构定义在 ee/packages/den-db/src/schema/models-analytics.tsmodels_analytics_settings以org_id为主键的单行设置表含enabled、consented_at、consented_by、consent_version、export_enabled、export_enabled_at、langfuse_host以及加密存储的langfuse_public_key/langfuse_secret_keyencryptedTextColumn。凭据加密落盘且设置端点永远不会把它们返回给客户端。models_analytics_event不可变事件表。id为主键event_id配合唯一索引models_analytics_dedup(org_id, member_id, source, event_id)实现「同一组织/成员/来源内的重试去重」payload以 JSON 保存完整事件体另有activity、task、consumption、export四个索引分别支撑活动分页、按任务检索、消费聚合与导出游标。exported_at标记已导出的行供后台 outbox 增量扫描。桌面端采集异步、有界、失败可重试桌面端的上报实现位于 apps/app/src/app/lib/models-task-analytics.ts由observeModelsTaskEvent暴露给运行时事件流。几个值得注意的实现细节异步非阻塞所有上报走void observe(...).catch(() {})绝不阻塞聊天单次请求带AbortSignal.timeout(5_000)。批量与限额每 5 秒 flush 一次每次最多 50 条待发队列上限 500 条事件在队列中 120 秒过期token 类字段在客户端从不产生契约层已禁止。上传前重新校验同意flush 前先请求 settings只有enabled true且拿到与事件一致的consentedAt才发送缓存的放行许可30 秒过期后必须重新校验避免在退出同意后仍上传元数据、或把旧同意期事件回填进新同意期。工具/技能标识符采集从message.part.updated中解析toolSchema只挑选能力标识符工具名、skillVersion、mcp工具参数与结果永不离开设备openwork-cloud_*工具统一标记 MCP 来源为openwork-cloudskill.loaded与tool.executed据此区分。任务生命周期依据message.updated中的父消息判定task.started并在消息完成时依据finish/error判定completed/failed/cancelled附带durationMsMessageAbortedError被归类为 cancelled。可选导出Langfuse 的安全连接与后台 outboxLangfuse 导出是可选能力管理员在 UI 中测试并连接项目凭据test 端点发送空批次验证连通性不落任何数据。连接即从该时刻开始导出。其安全与隔离设计在原文档和 ee/apps/den-api/src/models-analytics-egress.ts、ee/apps/den-api/src/models-analytics-export.ts 中都有完整体现仅支持公开 HTTPS 目标URL 中不允许携带用户名/密码http直接拒绝防 DNS 重绑定DNS 只解析一次校验解析结果不是私有地址后连接固定到该公开 IP同时用checkServerIdentity按原主机名校验 TLS 证书保留目标 TLS 身份响应有界请求总时限 5 秒不跟随重定向响应体上限 65,536 字节后台 outbox 重试导出由后台任务扫描exported_at为空的记录批量发送使用稳定的 trace/span ID网络调用完全不在推理请求路径上同意与断开语义关闭分析或断开连接时会等待已授权批次导出完成后才确认变更已撤销同意之后不允许再有新批次发出重新开启分析不会自动重启导出需要管理员显式重新连接。升级顺序与端到端验证原文档给出了明确的部署顺序这也是本功能上线的最关键实操点先应用迁移0092_models_task_analytics.sql在启用能力之前再部署应用——这样即使应用先于迁移部署未放量组织也不会在推理路径触碰新表Models 保持可用先部署 Den 路由再发布桌面端集成最后为选定组织启用modelsAnalytics能力。对于拿到新路由不可用的旧环境较新的桌面端遇到不可用的 settings 路由时会保持分析关闭、聊天正常运行且失败的检查会被缓存避免在每一条流式更新上反复重试。仓库提供了完整的端到端验证命令README 与 evals/specs/models-analytics-upgrade.e2e.test.ts、evals/worlds/models-analytics.tspnpm evals:e2e models-analytics-upgrade该 journey 使用隔离的 Den 数据库、真实的 Gateway HTTP 服务、浏览器与桌面端上游与 Langfuse 见证均使用合成凭据。它从一个分析表尚不存在的既有付费账号开始应用真实迁移后依次校验同一模型密钥、同意 UI、计量准确性、租户/成员隔离、导出、降级、工作区删除与对话继续。其中还包含一个精彩的负向验证独立观察到的 HTTP 链路先对 analytics settings 返回404证明较新的桌面端在无路由时仍然正常聊天且不上传任务事件随后恢复端点在同一段对话中真实演练任务/技能/工具上报。整个过程不会发起真实的 Stripe 购买也不会调用付费模型提供商。小结Models 任务分析的设计脉络清晰可循契约先行telemetry-contracts 统一事件与设置 schema、权限收口成员报自己的任务、管理员读全量、存储隔离两张新表 去重唯一索引不动推理路径、导出安全HTTPS-only、防 DNS 重绑定、后台 outbox以及保守升级先迁移、后路由、再放量。无论是排查上报缺失、规划企业部署还是扩展新的分析维度如增加事件类型或元数据字段都可以从本文提到的契约文件、路由文件与迁移文件入手快速定位到对应的实现与验证点。【免费下载链接】openworkThe open-source alternative to Claude Cowork (powered by opencode)项目地址: https://gitcode.com/GitHub_Trending/ope/openwork创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考