diff --git a/.scratch/v0.9/spec.md b/.scratch/v0.9/spec.md index 89b4680..e01fa43 100644 --- a/.scratch/v0.9/spec.md +++ b/.scratch/v0.9/spec.md @@ -51,7 +51,10 @@ - `POST /api/exploration/sessions`:body = campaign_id、persona、goal、seed_ref(可空);平台硬校验(活动存在且 running、正式线仅接受 auto 或 manual 触发;加速线仅接受 manual;预算余量)→ 创建 running 会话;超限 409 + 原因 - `POST /api/exploration/sessions/{id}/messages`:body = content;平台转发到目标的通道(复用 ChannelFactory)、持久化双方轮次、返回回复与延迟;单会话轮数超限 409;会话非 running 状态 409 - `POST /api/exploration/sessions/{id}/close`:body = 体验记录(goal_achieved: bool、blockers[]、misled[]、emotion、notes);结构校验 + 非法值归一(沿 v0.7 白名单经验);会话转 completed -- `GET /api/campaigns/{id}/exploration`:会话列表 + 探索发现聚合(会话数、达成率、问题清单) +- 探索发现读出口(实现裁决:不设独立 `/api/campaigns/{id}/exploration`,避免与报告链重复聚合): + - `GET /api/campaigns/{id}/report` 的 `exploration` 键携带探索发现聚合(会话数、达成率、问题清单、judge 复核),无探索数据时缺则无痕 + - `GET /api/exploration/campaigns/{id}/sessions`:会话列表(下钻用) + - `GET /api/exploration/sessions/{id}/messages`:单会话对话记录(下钻用) - 活动窗口 finalize 时:仍 running 的会话转 expired,不再接受消息(在 `resolve_finalize` 同处挂接) ### 护栏(平台硬执行,不信任客户端自律) @@ -62,11 +65,11 @@ ### 判定双证据线 - 体验判定:close 接口收结构化自报,为第一手证据 -- judge 抽样复核:会话结束后平台对对话抽样(默认 ≤3 段,控 token),经 judge 岗位模型产出质量维度复核;ChatClient 可注入(沿 v0.7 分析 seam);异步后台执行,失败落错误不阻塞 +- judge 抽样复核:会话结束后平台对对话抽样(实现裁决:按「轮」抽样,默认 ≤3 轮即最多 6 条消息、每条截断 500 字符控 token),经 judge 岗位模型产出质量维度复核;ChatClient 可注入(沿 v0.7 分析 seam);异步后台执行,失败落错误不阻塞 ### 报告 / 分析 / 导出 -- 活动报告聚合新增"探索发现"维度(会话数、目标达成率、问题清单来自体验记录聚合);周期对比口径不变(探索数据不参与) +- 活动报告聚合新增"探索发现"维度(会话数、目标达成率、问题清单来自体验记录聚合);judge 复核结论一并纳入(实现裁决:findings 全量收各档发现、poor 档排前,而非只收 poor);周期对比口径不变(探索数据不参与) - v0.7 分析输入追加探索**摘要**(问题清单 + 达成统计,非全量对话) - Markdown 导出:存在探索数据时追加「探索发现」附录(缺则无痕),附录顺序:智能分析 → 周期对比 → 探索发现 diff --git a/backend/agenteval/exploration/judge.py b/backend/agenteval/exploration/judge.py index 5008c25..5bac344 100644 --- a/backend/agenteval/exploration/judge.py +++ b/backend/agenteval/exploration/judge.py @@ -38,10 +38,15 @@ VALID_DIMENSIONS = ("attitude", "professionalism", "hallucination") VALID_RATINGS = ("good", "acceptable", "poor") JUDGE_SYSTEM_PROMPT = """你是评测平台的 judge 岗位模型,负责独立复核一段「虚拟用户」与被评对象的探索对话。 -只依据给定对话抽样判断,不要臆测抽样之外的内容。输出必须是合法 JSON,且仅包含以下结构: +只依据给定对话抽样判断,不要臆测抽样之外的内容。 +输出必须是合法 JSON,且仅包含以下结构: { "dimensions": [ - {"dimension": "attitude | professionalism | hallucination", "rating": "good | acceptable | poor", "comment": "一句话依据"} + { + "dimension": "attitude | professionalism | hallucination", + "rating": "good | acceptable | poor", + "comment": "一句话依据" + } ], "summary": "一句话总体结论" } diff --git a/backend/agenteval/exploration/summary.py b/backend/agenteval/exploration/summary.py index b0994f2..d261cb9 100644 --- a/backend/agenteval/exploration/summary.py +++ b/backend/agenteval/exploration/summary.py @@ -58,7 +58,8 @@ def summarize_campaign_exploration(db_session: Session, campaign_id: str) -> Opt def _summarize_judge_reviews(sessions: list[ExplorationSession]) -> Optional[dict[str, Any]]: - """只纳入复核完成的会话;findings 全量收各档发现(poor 档排前),summaries 收复核总体结论。""" + """只纳入复核完成的会话;findings 全量收各档发现(poor 档排前), + summaries 收复核总体结论。""" findings: list[dict[str, Any]] = [] summaries: list[str] = [] reviewed = 0 diff --git a/backend/agenteval/web/routers/exploration.py b/backend/agenteval/web/routers/exploration.py index f8e4ab7..5257830 100644 --- a/backend/agenteval/web/routers/exploration.py +++ b/backend/agenteval/web/routers/exploration.py @@ -63,7 +63,8 @@ class CloseSessionRequest(BaseModel): def _coerce_reply_text(content: Any) -> str: - """Flatten a reply payload to text; tutu returns msgBody as a parsed object, and str(dict) would leak a Python repr into the view.""" + """Flatten a reply payload to text; tutu returns msgBody as a parsed object, + and str(dict) would leak a Python repr into the view.""" if isinstance(content, str): return content if isinstance(content, dict):