docs(intelligent-eval): align domain language with trigger-driven execution (ADR-0009)
All checks were successful
CI / test (push) Successful in 4m2s
All checks were successful
CI / test (push) Successful in 4m2s
方案③落地后,智能评估执行机制从'常驻 cron 每分钟自唤醒'改为'平台每 60s 扫描入队 + 按需触发无状态 headless agent'(触发式执行)。对齐领域语言: - CONTEXT.md:Cron 池/工作单元(Worker)标 deprecated;新增触发式执行词条; 修正时间窗口(cron 自唤醒→平台扫描时段到期)、任务队列(消费端)、决策日志 - ADR-0009 新增:记录触发式执行取代 cron 池的决策(原因:cron 需外部 channel, OpenClaw webchat 非 channel 账号无法 delivery);ADR-0007 标 superseded - 代码标 deprecated:cron_pool / fault_tolerance / openclaw_cron_pool 路由 / CronPoolMonitor 页(导航入口已从 App.tsx 移除,监控由 TaskQueueMonitor 承担) 895 passed, vitest 19 passed
This commit is contained in:
parent
cc2ac8da89
commit
2dd023fdd9
14
CONTEXT.md
14
CONTEXT.md
@ -135,19 +135,23 @@ OpenClaw 在智能评估中按职责拆分的三个角色:规划师(planner
|
|||||||
_Avoid_: 岗位(与模型用途的"岗位"概念冲突)
|
_Avoid_: 岗位(与模型用途的"岗位"概念冲突)
|
||||||
|
|
||||||
**时间窗口(Time Window)**:
|
**时间窗口(Time Window)**:
|
||||||
智能评估的模拟约束:模拟一个完整服务周期(如 24h)内的用户交互分布。OpenClaw 规划时考虑交互时机(早高峰、午间冷清、晚间投诉多),通过 cron 自唤醒在对应时间点执行。是模拟约束而非硬截止。
|
智能评估的模拟约束:模拟一个完整服务周期(如 24h)内的用户交互分布。OpenClaw 规划时考虑交互时机(早高峰、午间冷清、晚间投诉多),执行时机由平台扫描判断时段到期后经触发式执行保证。是模拟约束而非硬截止。
|
||||||
_Avoid_: 窗口(与静态评估的"服务周期窗口"混淆时需加前缀)
|
_Avoid_: 窗口(与静态评估的"服务周期窗口"混淆时需加前缀)
|
||||||
|
|
||||||
|
**触发式执行(Trigger-driven Execution)**:
|
||||||
|
智能评估的执行机制:**平台掌控节奏**——每 60s 扫描 executing 评估,判断时段到期/欠账后入队;**有任务时触发一个无状态 OpenClaw agent**(headless,执行 worker skill 后即退)从任务队列取任务执行。执行单元自主决策(执行会话/等待/开始分析),平台负责节奏与兜底(assigned 超时重入队、决策日志补录)。取代旧"常驻 cron 每分钟自唤醒"机制(见 Cron 池,已废弃)。(决策见 ADR-0009)
|
||||||
|
_Avoid_: 轮询、调度(与静态评估活动调度混淆)
|
||||||
|
|
||||||
**Cron 池(Cron Pool)**:
|
**Cron 池(Cron Pool)**:
|
||||||
OpenClaw 侧的工作单元池(5-20 个 cron),每个 cron 可以处理任意智能评估。池化管理避免"一个评估一个 cron"导致的 cron 爆炸,同时保持每个 cron 的自主决策能力。平台负责创建/删除 cron,OpenClaw 负责执行。(决策见 ADR-0007)
|
~~已废弃(deprecated)~~:描述旧执行机制,方案③改为触发式执行后不再使用。原定义:OpenClaw 侧的工作单元池(5-20 个 cron),每个 cron 可以处理任意智能评估;池化管理避免 cron 爆炸。代码中 cron_pool 模块、Cron 池监控页为遗留。(原决策 ADR-0007 已被 ADR-0009 取代)
|
||||||
_Avoid_: 任务池、工作池(太泛)
|
_Avoid_: 任务池、工作池(太泛)
|
||||||
|
|
||||||
**工作单元(Worker)**:
|
**工作单元(Worker)**:
|
||||||
Cron 池中的一个 cron + 其 state,表示一个可用的执行单元。Worker 每分钟唤醒,从平台任务队列取一个任务执行,完成后归还到池中。Worker 有完整的决策权:执行会话、等待、开始分析。
|
~~已废弃(deprecated)~~:并入触发式执行。原定义:Cron 池中 cron + state 的常驻执行单元,每分钟唤醒取任务。现在执行单元是被平台触发的无状态 agent(见触发式执行)。`agenteval-intelligent-worker` 等 skill 名/代码标识符沿用不改。
|
||||||
_Avoid_: 执行器、处理器(失去自主性含义)
|
_Avoid_: 执行器、处理器(失去自主性含义)
|
||||||
|
|
||||||
**任务队列(Task Queue)**:
|
**任务队列(Task Queue)**:
|
||||||
平台侧的待处理评估队列,持久化在 DB。每分钟扫描所有 executing 评估,判断哪些需要立即处理(时段到期、有欠账),按优先级排序(时段到期 > 欠账多 > 等待时间长)。Worker 从队列取任务。
|
平台侧的待处理评估队列,持久化在 DB。每分钟扫描所有 executing 评估,判断哪些需要立即处理(时段到期、有欠账),按优先级排序(时段到期 > 欠账多 > 等待时间长)。触发式执行中被触发的 agent 从队列取任务。
|
||||||
_Avoid_: 消息队列(与 MQ 混淆)、任务列表
|
_Avoid_: 消息队列(与 MQ 混淆)、任务列表
|
||||||
|
|
||||||
**配置快照(Config Snapshot)**:
|
**配置快照(Config Snapshot)**:
|
||||||
@ -155,7 +159,7 @@ _Avoid_: 消息队列(与 MQ 混淆)、任务列表
|
|||||||
_Avoid_: 版本(与场景版本混淆)、备份
|
_Avoid_: 版本(与场景版本混淆)、备份
|
||||||
|
|
||||||
**决策日志(Decision Log)**:
|
**决策日志(Decision Log)**:
|
||||||
Worker 每次唤醒时的决策记录(执行会话/等待/开始分析 + 原因 + 上下文)。持久化在 DB,用于调试和审计 OpenClaw 的自主决策过程。
|
执行单元每次唤醒/触发时的决策记录(执行会话/等待/开始分析 + 原因 + 上下文)。持久化在 DB,用于调试和审计 OpenClaw 的自主决策过程。agent 未上报时由平台兜底补录(`cron_id=platform`)。
|
||||||
_Avoid_: 日志(太泛)、审计日志(与安全审计混淆)
|
_Avoid_: 日志(太泛)、审计日志(与安全审计混淆)
|
||||||
|
|
||||||
## 模型配置
|
## 模型配置
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
"""Cron pool management for intelligent evaluations (Cron 池管理).
|
"""Cron pool management for intelligent evaluations (Cron 池管理).
|
||||||
|
|
||||||
|
DEPRECATED (ADR-0009): 智能评估已改为触发式执行(平台扫描入队 + 触发 headless
|
||||||
|
agent),cron 池不再使用,initialize_pool 不进 lifespan,t480 worker cron 已禁用。
|
||||||
|
遗留保留仅供回溯;卡死检测由 ``task_queue.requeue_stale_assigned_tasks`` 承担。
|
||||||
|
|
||||||
Platform manages a pool of OpenClaw crons (5-20) that can process any
|
Platform manages a pool of OpenClaw crons (5-20) that can process any
|
||||||
intelligent evaluation. Pool automatically scales up/down based on load.
|
intelligent evaluation. Pool automatically scales up/down based on load.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
"""Fault tolerance and recovery for cron pool (故障恢复).
|
"""Fault tolerance and recovery for cron pool (故障恢复).
|
||||||
|
|
||||||
|
DEPRECATED (ADR-0009): 智能评估已改为触发式执行,cron 池不再使用,本模块无调用者。
|
||||||
|
遗留保留仅供回溯。卡死检测现由 ``task_queue.requeue_stale_assigned_tasks`` 承担。
|
||||||
|
|
||||||
Handles:
|
Handles:
|
||||||
- Stuck cron detection and cleanup
|
- Stuck cron detection and cleanup
|
||||||
- State reconciliation (platform DB vs OpenClaw state)
|
- State reconciliation (platform DB vs OpenClaw state)
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
"""API routes for OpenClaw cron pool management."""
|
"""API routes for OpenClaw cron pool management.
|
||||||
|
|
||||||
|
DEPRECATED (ADR-0009): 智能评估已改为触发式执行,cron 池不再使用(worker cron 已禁用)。
|
||||||
|
端点遗留保留仅供回溯;监控职责由前端任务队列页(TaskQueueMonitor)承担。
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# ADR-0007: 智能评估 OpenClaw 集成采用 Cron 池模式
|
# ADR-0007: 智能评估 OpenClaw 集成采用 Cron 池模式
|
||||||
|
|
||||||
**状态**: 已接受
|
**状态**: 已接受(已被 ADR-0009 取代——方案③改为触发式执行,cron 池不再使用)
|
||||||
**日期**: 2026-08-11
|
**日期**: 2026-08-11
|
||||||
**决策者**: 架构团队
|
**决策者**: 架构团队
|
||||||
**相关**: ADR-0003(评估活动分期)、CONTEXT.md(智能评估词汇)
|
**相关**: ADR-0003(评估活动分期)、CONTEXT.md(智能评估词汇)
|
||||||
|
|||||||
32
docs/adr/0009-trigger-driven-execution-replaces-cron-pool.md
Normal file
32
docs/adr/0009-trigger-driven-execution-replaces-cron-pool.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# ADR-0009: 智能评估执行改为触发式执行(取代 Cron 池)
|
||||||
|
|
||||||
|
**状态**: 已接受
|
||||||
|
**日期**: 2026-08-17
|
||||||
|
**决策者**: 架构团队
|
||||||
|
**相关**: 取代 ADR-0007(Cron 池模式)、CONTEXT.md(智能评估词汇)
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
智能评估原按 ADR-0007 采用 **Cron 池模式**:平台维护 5-20 个 OpenClaw cron(工作单元),每个 cron 每分钟自唤醒、从平台任务队列取任务执行。2026-08 实际部署验证发现该机制**依赖外部 IM channel**:OpenClaw 的 cron delivery 需要一个 channel 账号,而 webchat 是 Control UI 内置、非 channel 账号,无法用于 delivery;`--command` cron 同样 fail-closed。结果 cron worker 永远无法被唤醒执行,评估卡在 assigned。
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
将智能评估执行改为**触发式执行(Trigger-driven)**:
|
||||||
|
|
||||||
|
1. **平台掌控节奏**:lifespan 后台循环每 60s 扫描 executing 评估 → 判断时段到期/欠账 → 入队(任务队列语义不变)
|
||||||
|
2. **平台按需触发**:有 pending 任务时 `docker exec openclaw-eval openclaw agent --agent main -m "<worker skill + 立即完成,不要等待下一节拍>" --json`,触发一个**无状态 headless agent**(`--deliver` 默认 false,免外部 channel)执行 worker skill,从任务队列取任务,完成即退
|
||||||
|
3. **平台兜底**:assigned 超时(>10min)重入队(`requeue_stale_assigned_tasks`);agent 未上报决策日志时按状态补录(`cron_id=platform`)
|
||||||
|
|
||||||
|
任务队列、决策日志、评估状态机等共享层原样保留;变化只在"执行主体":常驻 cron(pull、有状态)→ 按需触发的一次性 agent(push、无状态)。
|
||||||
|
|
||||||
|
### 已否决的方案
|
||||||
|
|
||||||
|
- **常驻 cron worker**(ADR-0007 原方案):需外部 IM channel,OpenClaw webchat 非 channel 账号,`--command` cron fail-closed——cron 无法被唤醒
|
||||||
|
- **平台静态执行**:平台直接驱动对话会退化为静态评测,失去 OpenClaw 的自主决策(ADR-0007 已否决过)
|
||||||
|
|
||||||
|
### Consequences
|
||||||
|
|
||||||
|
- **Cron 池代码遗留**:cron_pool.py / fault_tolerance.py / openclaw_cron_pool 路由 / Cron 池监控页为遗留,标注 deprecated,导航入口移除;t480 上旧 `intelligent-eval-worker` cron 已禁用(保留 `agenteval-patrol` 独立 cron)
|
||||||
|
- **卡死检测机制变化**:cron 的 busy/last_active stuck 检测对无状态 agent 不适用,改为平台 assigned 超时重入队
|
||||||
|
- **触发指令必须带"立即完成"语义**:`openclaw agent` 无 cron state,若只发 skill 名会按 worker skill 的"跨节拍"设计决策后等下一拍而死锁
|
||||||
|
- **监控载体变化**:旧"定时触发"可视化由任务队列监控页(TaskQueueMonitor)取代
|
||||||
@ -38,7 +38,6 @@ const OpenClawPage = lazy(() => import('./pages/OpenClaw'))
|
|||||||
const FilesPage = lazy(() => import('./pages/Files'))
|
const FilesPage = lazy(() => import('./pages/Files'))
|
||||||
const ModelConfigsPage = lazy(() => import('./pages/ModelConfigs'))
|
const ModelConfigsPage = lazy(() => import('./pages/ModelConfigs'))
|
||||||
const IntelligentEvalsPage = lazy(() => import('./pages/IntelligentEvals'))
|
const IntelligentEvalsPage = lazy(() => import('./pages/IntelligentEvals'))
|
||||||
const CronPoolMonitorPage = lazy(() => import('./pages/CronPoolMonitor'))
|
|
||||||
|
|
||||||
function PageLoader({ children }: { children: ReactNode }) {
|
function PageLoader({ children }: { children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
@ -68,7 +67,6 @@ const routeConfigs: RouteConfig[] = [
|
|||||||
{ path: '/campaigns', name: '评估活动', icon: <ScheduleOutlined />, component: () => <PageLoader><CampaignsPage /></PageLoader> },
|
{ path: '/campaigns', name: '评估活动', icon: <ScheduleOutlined />, component: () => <PageLoader><CampaignsPage /></PageLoader> },
|
||||||
{ path: '/reports', name: '评测报告', icon: <BarChartOutlined />, component: () => <PageLoader><ReportsPage /></PageLoader> },
|
{ path: '/reports', name: '评测报告', icon: <BarChartOutlined />, component: () => <PageLoader><ReportsPage /></PageLoader> },
|
||||||
{ path: '/intelligent-evals', name: '智能评估', icon: <BulbOutlined />, component: () => <PageLoader><IntelligentEvalsPage /></PageLoader> },
|
{ path: '/intelligent-evals', name: '智能评估', icon: <BulbOutlined />, component: () => <PageLoader><IntelligentEvalsPage /></PageLoader> },
|
||||||
{ path: '/cron-pool', name: 'Cron 池监控', icon: <DashboardOutlined />, component: () => <PageLoader><CronPoolMonitorPage /></PageLoader> },
|
|
||||||
{ path: '/models', name: '模型配置', icon: <CloudServerOutlined />, component: () => <PageLoader><ModelConfigsPage /></PageLoader> },
|
{ path: '/models', name: '模型配置', icon: <CloudServerOutlined />, component: () => <PageLoader><ModelConfigsPage /></PageLoader> },
|
||||||
{ path: '/files', name: '原始文件', icon: <FolderOpenOutlined />, component: () => <PageLoader><FilesPage /></PageLoader> },
|
{ path: '/files', name: '原始文件', icon: <FolderOpenOutlined />, component: () => <PageLoader><FilesPage /></PageLoader> },
|
||||||
]
|
]
|
||||||
@ -99,7 +97,6 @@ const menuItems: MenuProps['items'] = [
|
|||||||
label: '智能评估',
|
label: '智能评估',
|
||||||
children: [
|
children: [
|
||||||
{ key: '/intelligent-evals', icon: <BulbOutlined />, label: '评估列表' },
|
{ key: '/intelligent-evals', icon: <BulbOutlined />, label: '评估列表' },
|
||||||
{ key: '/cron-pool', icon: <DashboardOutlined />, label: 'Cron 池监控' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
// DEPRECATED (ADR-0009): 智能评估已改为触发式执行,cron 池不再使用(worker cron 已禁用)。
|
||||||
|
// 本页已从导航移除,遗留保留仅供回溯。监控职责由 TaskQueueMonitor(任务队列页)承担。
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
Alert, Button, Card, Descriptions, Empty, InputNumber, Space, Statistic, Table, Tag, message,
|
Alert, Button, Card, Descriptions, Empty, InputNumber, Space, Statistic, Table, Tag, message,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user