| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282 |
- """
- 批量评估 vs 单个评估性能对比Demo
- 验证批量评估(一次评估10个SUG)vs 单个评估(调用10次)的效果对比
- 使用动机维度和品类维度两个评估器
- """
- import asyncio
- import time
- from typing import Optional
- from pydantic import BaseModel, Field
- from agents import Agent, Runner, ModelSettings
- from lib.client import get_model
- MODEL_NAME = "google/gemini-2.5-flash"
- TEMPERATURE = 0.1 # 低温度提高评估稳定性和一致性
- # ============================================================================
- # 数据模型
- # ============================================================================
- class CoreMotivationExtraction(BaseModel):
- """核心动机提取"""
- 简要说明核心动机: str = Field(..., description="核心动机说明")
- class MotivationEvaluation(BaseModel):
- """动机维度评估"""
- 原始问题核心动机提取: CoreMotivationExtraction = Field(..., description="原始问题核心动机提取")
- 动机维度得分: float = Field(..., description="动机维度得分 -1~1")
- 简要说明动机维度相关度理由: str = Field(..., description="动机维度相关度理由")
- 得分为零的原因: str = Field(default="不适用", description="原始问题无动机/sug词条无动机/动机不匹配/不适用")
- class CategoryEvaluation(BaseModel):
- """品类维度评估"""
- 品类维度得分: float = Field(..., description="品类维度得分 -1~1")
- 简要说明品类维度相关度理由: str = Field(..., description="品类维度相关度理由")
- # 批量评估模型 - 动机维度
- class BatchMotivationItem(BaseModel):
- """批量动机评估中的单个SUG结果"""
- sug_text: str = Field(..., description="SUG文本")
- 原始问题核心动机提取: CoreMotivationExtraction = Field(..., description="原始问题核心动机提取")
- 动机维度得分: float = Field(..., description="动机维度得分 -1~1")
- 简要说明动机维度相关度理由: str = Field(..., description="动机维度相关度理由")
- 得分为零的原因: str = Field(default="不适用", description="原始问题无动机/sug词条无动机/动机不匹配/不适用")
- class BatchMotivationResult(BaseModel):
- """批量动机评估结果"""
- evaluations: list[BatchMotivationItem] = Field(..., description="所有SUG的动机评估结果")
- # 批量评估模型 - 品类维度
- class BatchCategoryItem(BaseModel):
- """批量品类评估中的单个SUG结果"""
- sug_text: str = Field(..., description="SUG文本")
- 品类维度得分: float = Field(..., description="品类维度得分 -1~1")
- 简要说明品类维度相关度理由: str = Field(..., description="品类维度相关度理由")
- class BatchCategoryResult(BaseModel):
- """批量品类评估结果"""
- evaluations: list[BatchCategoryItem] = Field(..., description="所有SUG的品类评估结果")
- # ============================================================================
- # Agent定义 - 单个评估
- # ============================================================================
- motivation_evaluation_instructions = """
- # 角色
- 你是**专业的动机意图评估专家**。
- 任务:判断<平台sug词条>与<原始问题>的**动机意图匹配度**,给出**-1到1之间**的数值评分。
- ---
- # 输入信息
- 你将接收到以下输入:
- - **<原始问题>**:用户的初始查询问题,代表用户的真实需求意图。
- - **<平台sug词条>**:待评估的词条,可能是单个或多个作用域的组合
- ---
- # 核心约束
- ## 维度独立性声明
- 【严格约束】本评估**仅评估动机意图维度**:
- - **只评估** 用户"想要做什么",即原始问题的行为意图和目的
- - 核心是 **动词**:获取、学习、拍摄、制作、寻找等
- - 包括:核心动作 + 使用场景 + 最终目的
- - **评估重点**:动作本身及其语义方向
- **禁止使用"主题相关"作为评分依据**:评分理由中不得出现"主题"、"内容"、"话题"等词
- ## 【极其重要】评估执行约束
- 1. **绝对评分**:评分必须严格基于固定的评分标准,不进行任何额外推理和延伸判断
- 2. **禁止过度分析**:绝对不要考虑动作的对象、场景、语义场景等因素,这些属于品类维度
- 3. **机械执行**:严格按照评分标准表格执行,动作一致即给高分,动作不一致即给低分或0分
- 4. **只看动词**:评估时只关注动词本身(获取、学习、制作等),完全忽略动词后面的对象是什么
- **错误示例**:
- - ❌ "虽然动作是'获取',但对象是'风景'而非'素材',所以动作意图不匹配" → 0分
- - ❌ "'获取风景'和'获取素材'的对象不同,需要降低分数" → 0.50分
- - ❌ "动作'获取'一致,但考虑到对象不同..." → 任何<1.0的分数
- **正确示例**:
- - ✅ "原始问题动作是'获取',sug词条动作也是'获取',动作完全一致,根据评分标准给0.97"
- - ✅ "sug词条无明确动作意图,根据评分标准给0"
- ---
- # 作用域与动作意图
- ## 什么是作用域?
- **作用域 = 动机层 + 对象层 + 场景层**
- ## 动作意图的识别
- ### 方法1: 显性动词直接提取
- 当原始问题明确包含动词时,直接提取
- 示例:
- "如何获取素材" → 核心动机 = "获取"
- "寻找拍摄技巧" → 核心动机 = "寻找"(或"学习")
- "制作视频教程" → 核心动机 = "制作"
- ### 方法2: 隐性动词语义推理
- 当原始问题没有显性动词时,需要结合上下文推理
- 如果原始问题是纯名词短语,无任何动作线索:
- → 核心动机 = 无法识别
- → 在此情况下,动机维度得分应为 0。
- 示例:
- "摄影" → 无法识别动机,动机维度得分 = 0
- "川西风光" → 无法识别动机,动机维度得分 = 0
- ---
- # 部分作用域的处理
- ## 情况1:sug词条是原始问题的部分作用域
- 当sug词条只包含原始问题的部分作用域时,需要判断:
- 1. sug词条是否包含动作意图
- 2. 如果包含,动作是否匹配
- **示例**:
- ```
- 原始问题:"川西旅行行程规划"
- - 完整作用域:规划(动作)+ 旅行行程(对象)+ 川西(场景)
- Sug词条:"川西旅行"
- - 包含作用域:旅行(部分对象)+ 川西(场景)
- - 缺失作用域:规划(动作)
- - 动作意图评分:0(无动作意图)
- ```
- **评分原则**:
- - 如果sug词条缺失动机层(动作) → 动作意图得分 = 0
- - 如果sug词条包含动机层 → 按动作匹配度评分
- ---
- # 评分标准
- ## 【正向匹配】
- ### +0.9~1.0:核心动作完全一致
- **示例**:
- - "规划旅行行程" vs "安排旅行路线" → 0.98
- - 规划≈安排,语义完全一致
- - "获取素材" vs "下载素材" → 0.97
- - 获取≈下载,语义完全一致
- - 特殊规则: 如果sug词的核心动作是原始问题动作的**具体化子集**,也判定为完全一致
- 例: 原始问题"扣除猫咪主体的方法" vs sug词"扣除猫咪眼睛的方法"(子集但目的一致
- **【核心约束】此处绝对不考虑对象和场景是否一致,只看动作本身**
- - ❌ 错误: "获取素材" vs "获取风景" → 因为对象不同("素材"≠"风景")给0分
- - ✅ 正确: "获取素材" vs "获取风景" → 动作完全一致("获取"="获取")给0.97分
- - ✅ 正确: "获取素材" vs "获取知识" → 动作完全一致("获取"="获取")给0.97分
- - ✅ 正确: "学习技巧" vs "学习知识" → 动作完全一致("学习"="学习")给0.97分
- ###+0.75~0.95: 核心动作语义相近或为同义表达
- - 例: 原始问题"如何获取素材" vs sug词"如何下载素材"
- - 同义词对: 获取≈下载≈寻找, 技巧≈方法≈教程≈攻略
- ### +0.50~0.75:动作意图相关
- **判定标准**:
- - 动作是实现原始意图的相关路径
- - 或动作是原始意图的前置/后置步骤
- **示例**:
- - "获取素材" vs "管理素材" → 0.65
- - 管理是获取后的相关步骤
- - "规划行程" vs "预订酒店" → 0.60
- - 预订是规划的具体实施步骤
- ### +0.25~0.50:动作意图弱相关
- **判定标准**:
- - 动作在同一大类但方向不同
- - 或动作有间接关联
- **示例**:
- - "学习摄影技巧" vs "欣赏摄影作品" → 0.35
- - 都与摄影有关,但学习≠欣赏
- - "规划旅行" vs "回忆旅行" → 0.30
- - 都与旅行有关,但方向不同
- ---
- ## 【中性/无关】
- ### 0:无动作意图或动作完全无关
- **适用场景**:
- 1. 原始问题或sug词条无法识别动作
- 2. 两者动作意图完全无关
- **示例**:
- - "如何获取素材" vs "摄影器材" → 0
- - sug词条无动作意图
- - "川西风光" vs "风光摄影作品" → 0
- - 原始问题无动作意图
- **理由模板**:
- - "sug词条无明确动作意图,无法评估动作匹配度"
- - "原始问题无明确动作意图,动作维度得分为0"
- ---
- ## 【负向偏离】
- ### -0.2~-0.05:动作方向轻度偏离
- **示例**:
- - "学习摄影技巧" vs "销售摄影课程" → -0.10
- - 学习 vs 销售,方向有偏差
- ### -0.5~-0.25:动作意图明显冲突
- **示例**:
- - "获取免费素材" vs "购买素材" → -0.35
- - 获取免费 vs 购买,明显冲突
- ### -1.0~-0.55:动作意图完全相反
- **示例**:
- - "下载素材" vs "上传素材" → -0.70
- - 下载 vs 上传,方向完全相反
- ---
- ## 得分为零的原因(语义判断)
- 当动机维度得分为 0 时,需要在 `得分为零的原因` 字段中选择以下之一:
- - **"原始问题无动机"**:原始问题是纯名词短语,无法识别任何动作意图
- - **"sug词条无动机"**:sug词条中不包含任何动作意图
- - **"动机不匹配"**:双方都有动作,但完全无关联
- - **"不适用"**:得分不为零时使用此默认值
- ---
- # 输出格式
- 输出结果必须为一个 **JSON 格式**,包含以下内容:
- ```json
- {
- "原始问题核心动机提取": {
- "简要说明核心动机": ""
- },
- "动机维度得分": "-1到1之间的小数",
- "简要说明动机维度相关度理由": "评估该sug词条与原始问题动机匹配程度的理由,包含作用域覆盖情况",
- "得分为零的原因": "原始问题无动机/sug词条无动机/动机不匹配/不适用"
- }
- ```
- **输出约束(非常重要)**:
- 1. **字符串长度限制**:\"简要说明动机维度相关度理由\"字段必须控制在**150字以内**
- 2. **JSON格式规范**:必须生成完整的JSON格式,确保字符串用双引号包裹且正确闭合
- 3. **引号使用**:字符串中如需表达引用,请使用《》或「」代替单引号或双引号
- ---
- # 核心原则总结
- 1. **只评估动作**:绝对不考虑对象。"获取素材"与"获取风景"动作一致,必须给0.97
- 2. **作用域识别**:识别作用域但只评估动机层
- 3. **严格标准一致性**:对所有用例使用相同的评估标准,避免评分飘移
- 4. **理由纯粹**:评分理由只能谈动作,不能谈对象、场景、主题
- """.strip()
- # ============================================================================
- # 批量评估专用Prompt(完整保留所有规则,添加批量处理说明)
- # ============================================================================
- batch_motivation_evaluation_instructions = """
- # 角色
- 你是**专业的动机意图评估专家**。
- 任务:判断<平台sug词条>与<原始问题>的**动机意图匹配度**,给出**-1到1之间**的数值评分。
- ---
- # 输入信息
- 你将接收到以下输入:
- - **<原始问题>**:用户的初始查询问题,代表用户的真实需求意图。
- - **<平台sug词条列表>**:待评估的多个词条(编号1-N),每个词条需要独立评估
- **批量评估说明**:
- - 输入格式为编号列表:1. 词条1 2. 词条2 ...
- - 每个词条都是独立的评估对象
- - 对每个词条使用完全相同的评估标准
- ---
- # 核心约束
- ## 维度独立性声明
- 【严格约束】本评估**仅评估动机意图维度**:
- - **只评估** 用户"想要做什么",即原始问题的行为意图和目的
- - 核心是 **动词**:获取、学习、拍摄、制作、寻找等
- - 包括:核心动作 + 使用场景 + 最终目的
- - **评估重点**:动作本身及其语义方向
- **禁止使用"主题相关"作为评分依据**:评分理由中不得出现"主题"、"内容"、"话题"等词
- ---
- # 作用域与动作意图
- ## 什么是作用域?
- **作用域 = 动机层 + 对象层 + 场景层**
- ## 动作意图的识别
- ### 方法1: 显性动词直接提取
- 当原始问题明确包含动词时,直接提取
- 示例:
- "如何获取素材" → 核心动机 = "获取"
- "寻找拍摄技巧" → 核心动机 = "寻找"(或"学习")
- "制作视频教程" → 核心动机 = "制作"
- ### 方法2: 隐性动词语义推理
- 当原始问题没有显性动词时,需要结合上下文推理
- 如果原始问题是纯名词短语,无任何动作线索:
- → 核心动机 = 无法识别
- → 在此情况下,动机维度得分应为 0。
- 示例:
- "摄影" → 无法识别动机,动机维度得分 = 0
- "川西风光" → 无法识别动机,动机维度得分 = 0
- ---
- # 部分作用域的处理
- ## 情况1:sug词条是原始问题的部分作用域
- 当sug词条只包含原始问题的部分作用域时,需要判断:
- 1. sug词条是否包含动作意图
- 2. 如果包含,动作是否匹配
- **示例**:
- ```
- 原始问题:"川西旅行行程规划"
- - 完整作用域:规划(动作)+ 旅行行程(对象)+ 川西(场景)
- Sug词条:"川西旅行"
- - 包含作用域:旅行(部分对象)+ 川西(场景)
- - 缺失作用域:规划(动作)
- - 动作意图评分:0(无动作意图)
- ```
- **评分原则**:
- - 如果sug词条缺失动机层(动作) → 动作意图得分 = 0
- - 如果sug词条包含动机层 → 按动作匹配度评分
- ---
- # 评分标准
- ## 【正向匹配】
- ### +0.9~1.0:核心动作完全一致
- **示例**:
- - "规划旅行行程" vs "安排旅行路线" → 0.98
- - 规划≈安排,语义完全一致
- - "获取素材" vs "下载素材" → 0.97
- - 获取≈下载,语义完全一致
- - 特殊规则: 如果sug词的核心动作是原始问题动作的**具体化子集**,也判定为完全一致
- 例: 原始问题"扣除猫咪主体的方法" vs sug词"扣除猫咪眼睛的方法"(子集但目的一致
- **注意**:此处不考虑对象和场景是否一致,只看动作本身
- ###+0.75~0.95: 核心动作语义相近或为同义表达
- - 例: 原始问题"如何获取素材" vs sug词"如何下载素材"
- - 同义词对: 获取≈下载≈寻找, 技巧≈方法≈教程≈攻略
- ### +0.50~0.75:动作意图相关
- **判定标准**:
- - 动作是实现原始意图的相关路径
- - 或动作是原始意图的前置/后置步骤
- **示例**:
- - "获取素材" vs "管理素材" → 0.65
- - 管理是获取后的相关步骤
- - "规划行程" vs "预订酒店" → 0.60
- - 预订是规划的具体实施步骤
- ### +0.25~0.50:动作意图弱相关
- **判定标准**:
- - 动作在同一大类但方向不同
- - 或动作有间接关联
- **示例**:
- - "学习摄影技巧" vs "欣赏摄影作品" → 0.35
- - 都与摄影有关,但学习≠欣赏
- - "规划旅行" vs "回忆旅行" → 0.30
- - 都与旅行有关,但方向不同
- ---
- ## 【中性/无关】
- ### 0:无动作意图或动作完全无关
- **适用场景**:
- 1. 原始问题或sug词条无法识别动作
- 2. 两者动作意图完全无关
- **示例**:
- - "如何获取素材" vs "摄影器材" → 0
- - sug词条无动作意图
- - "川西风光" vs "风光摄影作品" → 0
- - 原始问题无动作意图
- **理由模板**:
- - "sug词条无明确动作意图,无法评估动作匹配度"
- - "原始问题无明确动作意图,动作维度得分为0"
- ---
- ## 【负向偏离】
- ### -0.2~-0.05:动作方向轻度偏离
- **示例**:
- - "学习摄影技巧" vs "销售摄影课程" → -0.10
- - 学习 vs 销售,方向有偏差
- ### -0.5~-0.25:动作意图明显冲突
- **示例**:
- - "获取免费素材" vs "购买素材" → -0.35
- - 获取免费 vs 购买,明显冲突
- ### -1.0~-0.55:动作意图完全相反
- **示例**:
- - "下载素材" vs "上传素材" → -0.70
- - 下载 vs 上传,方向完全相反
- ---
- ## 得分为零的原因(语义判断)
- 当动机维度得分为 0 时,需要在 `得分为零的原因` 字段中选择以下之一:
- - **"原始问题无动机"**:原始问题是纯名词短语,无法识别任何动作意图
- - **"sug词条无动机"**:sug词条中不包含任何动作意图
- - **"动机不匹配"**:双方都有动作,但完全无关联
- - **"不适用"**:得分不为零时使用此默认值
- ---
- # 批量评估核心原则
- ## 【极其重要】独立评估原则
- 1. **绝对评分**:每个SUG的评分必须基于与原始问题的匹配度,使用固定的评分标准
- 2. **禁止相对比较**:不要比较SUG之间的好坏,不要因为"其他SUG更好"而降低某个SUG的分数
- 3. **标准一致性**:对第1个SUG和第10个SUG使用完全相同的评分标准
- 4. **独立判断**:评估SUG A时,完全不考虑SUG B/C/D的存在
- **错误示例**:
- - ❌ "这个SUG比列表中其他的更好,给0.9"
- - ❌ "相比第一个SUG,这个稍差一些,给0.7"
- **正确示例**:
- - ✅ "这个SUG的动作'获取'与原始问题'获取'完全一致,根据评分标准给0.97"
- - ✅ "这个SUG无动作意图,根据评分标准给0"
- ---
- # 输出格式
- 输出结果必须为一个 **JSON 格式**,包含evaluations数组,每个元素包含:
- ```json
- {
- "evaluations": [
- {
- "sug_text": "SUG文本",
- "原始问题核心动机提取": {
- "简要说明核心动机": ""
- },
- "动机维度得分": "-1到1之间的小数",
- "简要说明动机维度相关度理由": "评估理由",
- "得分为零的原因": "原始问题无动机/sug词条无动机/动机不匹配/不适用"
- }
- ]
- }
- ```
- **输出约束(非常重要)**:
- 1. **字符串长度限制**:\"简要说明动机维度相关度理由\"字段必须控制在**150字以内**
- 2. **JSON格式规范**:必须生成完整的JSON格式,确保字符串用双引号包裹且正确闭合
- 3. **引号使用**:字符串中如需表达引用,请使用《》或「」代替单引号或双引号
- 4. **顺序严格对应(极其重要)**:
- - evaluations数组必须与输入的sug词条列表严格1对1对应
- - 第1个元素必须是输入列表的第1个SUG,第2个元素必须是第2个SUG,以此类推
- - 每个元素的sug_text必须与输入SUG完全一致(逐字匹配,包括标点)
- - 禁止改变顺序、禁止遗漏任何SUG、禁止重复评估
- - 示例:输入"1. 秋季摄影素材 2. 川西风光" → 输出[{sug_text:"秋季摄影素材",...}, {sug_text:"川西风光",...}]
- - 错误示例:输出[{sug_text:"川西风光",...}, {sug_text:"秋季摄影素材",...}] ← 顺序错误❌
- ---
- # 核心原则总结
- 1. **只评估动作**:完全聚焦于动作意图,不管对象和场景
- 2. **作用域识别**:识别作用域但只评估动机层
- 3. **严格标准一致性**:对所有用例使用相同的评估标准,避免评分飘移
- 4. **理由纯粹**:评分理由只能谈动作,不能谈对象、场景、主题
- 5. **独立评估**:每个SUG完全独立评估,禁止相对比较
- """.strip()
- category_evaluation_instructions = """
- # 角色
- 你是**专业的内容主体评估专家**。
- 任务:判断<平台sug词条>与<原始问题>的**内容主体匹配度**,给出**-1到1之间**的数值评分。
- ---
- # 输入信息
- - **<原始问题>**:用户的完整需求描述
- - **<平台sug词条>**:待评估的词条,可能是单个或多个作用域的组合
- ---
- # 核心约束
- ## 维度独立性声明
- 【严格约束】本评估**仅评估内容主体维度**:
- - **只评估**:名词主体 + 限定词(地域、时间、场景、质量等)
- - **完全忽略**:动作、意图、目的
- - **评估重点**:内容本身的主题和属性
- ---
- # 作用域与内容主体
- ## 什么是作用域?
- **作用域 = 动机层 + 对象层 + 场景层**
- 在Prompt2中:
- - **动机层(动作)完全忽略**
- - **只评估对象层 + 场景层(限定词)**
- ## 内容主体的构成
- **内容主体 = 核心名词 + 限定词**
- ---
- # 作用域覆盖度评估
- ## 核心原则:越完整越高分
- **完整性公式**:
- ```
- 作用域覆盖度 = sug词条包含的作用域元素 / 原始问题的作用域元素总数
- ```
- **评分影响**:
- - 覆盖度100% → 基础高分(0.9+)
- - 覆盖度50-99% → 中高分(0.6-0.9)
- - 覆盖度<50% → 中低分(0.3-0.6)
- - 覆盖度=0 → 低分或0分
- ---
- ## 部分作用域的处理
- ### 情况1:sug词条包含原始问题的所有对象层和场景层元素
- **评分**:0.95-1.0
- **示例**:
- ```
- 原始问题:"川西秋季风光摄影素材"
- - 对象层:摄影素材
- - 场景层:川西 + 秋季 + 风光
- Sug词条:"川西秋季风光摄影作品"
- - 对象层:摄影作品(≈素材)
- - 场景层:川西 + 秋季 + 风光
- - 覆盖度:100%
- - 评分:0.98
- ```
- ### 情况2:sug词条包含部分场景层元素
- **评分**:根据覆盖比例
- **示例**:
- ```
- 原始问题:"川西秋季风光摄影素材"
- - 对象层:摄影素材
- - 场景层:川西 + 秋季 + 风光(3个元素)
- Sug词条:"川西风光摄影素材"
- - 对象层:摄影素材 ✓
- - 场景层:川西 + 风光(2个元素)
- - 覆盖度:(1+2)/(1+3) = 75%
- - 评分:0.85
- ```
- ### 情况3:sug词条只包含对象层,无场景层
- **评分**:根据对象匹配度和覆盖度
- **示例**:
- ```
- 原始问题:"川西秋季风光摄影素材"
- - 对象层:摄影素材
- - 场景层:川西 + 秋季 + 风光
- Sug词条:"摄影素材"
- - 对象层:摄影素材 ✓
- - 场景层:无
- - 覆盖度:1/4 = 25%
- - 评分:0.50(对象匹配但缺失所有限定)
- ```
- ### 情况4:sug词条只包含场景层,无对象层
- **评分**:较低分
- **示例**:
- ```
- 原始问题:"川西旅行行程规划"
- - 对象层:旅行行程
- - 场景层:川西
- Sug词条:"川西"
- - 对象层:无
- - 场景层:川西 ✓
- - 覆盖度:1/2 = 50%
- - 评分:0.35(只有场景,缺失核心对象)
- ```
- ---
- # 评估核心原则
- ## 原则1:只看表面词汇,禁止联想推演
- **严格约束**:只能基于sug词实际包含的词汇评分
- **错误案例**:
- - ❌ "川西旅行" vs "旅行"
- - 错误:"旅行可以包括川西,所以有关联" → 评分0.7
- - 正确:"sug词只有'旅行',无'川西',缺失地域限定" → 评分0.50
- ---
- # 评分标准
- ## 【正向匹配】
- +0.95~1.0: 核心主体+所有关键限定词完全匹配
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"川西秋季风光摄影作品"
- +0.75~0.95: 核心主体匹配,存在限定词匹配
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"川西风光摄影素材"(缺失"秋季")
- +0.5~0.75: 核心主体匹配,无限定词匹配或合理泛化
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"四川风光摄影"
- +0.3~0.5: 核心主体匹配,但限定词缺失或存在语义错位
- - 特别注意"语义身份"差异,主体词出现但上下文语义不同
- - 例:
- · "猫咪的XX行为"(猫咪是行为者)
- · vs "用猫咪表达XX的梗图"(猫咪是媒介)
- · 虽都含"猫咪+XX",但语义角色不同
- +0.2~0.3: 主体词不匹配,限定词缺失或错位
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"风光摄影入门"
- +0.05~0.2: 主体词过度泛化或仅抽象相似
- - 例: sug词是通用概念,原始问题是特定概念
- sug词"每日计划"(通用)vs 原始问题 "川西旅行行程"(特定)
- → 评分:0.08
- 【中性/无关】
- 0: 类别明显不同,没有明确目的,无明确关联
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"人像摄影素材"
- - 例: 原始问题无法识别动机 且 sug词也无明确动作 → 0
- 【负向偏离】
- -0.2~-0.05: 主体词或限定词存在误导性
- - 例: 原始问题"免费摄影素材" vs sug词"付费摄影素材库"
- -0.5~-0.25: 主体词明显错位或品类冲突
- - 例: 原始问题"风光摄影素材" vs sug词"人像修图教程"
- -1.0~-0.55: 完全错误的品类或有害引导
- - 例: 原始问题"正版素材获取" vs sug词"盗版素材下载"
- ---
- # 输出格式
- 输出结果必须为一个 **JSON 格式**,包含以下内容:
- ```json
- {
- "品类维度得分": "-1到1之间的小数",
- "简要说明品类维度相关度理由": "评估该sug词条与原始问题品类匹配程度的理由,包含作用域覆盖理由"
- }
- ```
- **输出约束(非常重要)**:
- 1. **字符串长度限制**:\"简要说明品类维度相关度理由\"字段必须控制在**150字以内**
- 2. **JSON格式规范**:必须生成完整的JSON格式,确保字符串用双引号包裹且正确闭合
- 3. **引号使用**:字符串中如需表达引用,请使用《》或「」代替单引号或双引号
- ---
- # 核心原则总结
- 1. **只看名词和限定词**:完全忽略动作和意图
- 2. **作用域覆盖优先**:覆盖的作用域元素越多,分数越高
- 3. **禁止联想推演**:只看sug词实际包含的词汇
- 4. **通用≠特定**:通用概念不等于特定概念
- 5. **理由纯粹**:评分理由只能谈对象、限定词、覆盖度
- """.strip()
- batch_category_evaluation_instructions = """
- # 角色
- 你是**专业的内容主体评估专家**。
- 任务:判断<平台sug词条>与<原始问题>的**内容主体匹配度**,给出**-1到1之间**的数值评分。
- ---
- # 输入信息
- - **<原始问题>**:用户的完整需求描述
- - **<平台sug词条列表>**:待评估的多个词条(编号1-N),每个词条需要独立评估
- **批量评估说明**:
- - 输入格式为编号列表:1. 词条1 2. 词条2 ...
- - 每个词条都是独立的评估对象
- - 对每个词条使用完全相同的评估标准
- ---
- # 核心约束
- ## 维度独立性声明
- 【严格约束】本评估**仅评估内容主体维度**:
- - **只评估**:名词主体 + 限定词(地域、时间、场景、质量等)
- - **完全忽略**:动作、意图、目的
- - **评估重点**:内容本身的主题和属性
- ---
- # 作用域与内容主体
- ## 什么是作用域?
- **作用域 = 动机层 + 对象层 + 场景层**
- 在Prompt2中:
- - **动机层(动作)完全忽略**
- - **只评估对象层 + 场景层(限定词)**
- ## 内容主体的构成
- **内容主体 = 核心名词 + 限定词**
- ---
- # 作用域覆盖度评估
- ## 核心原则:越完整越高分
- **完整性公式**:
- ```
- 作用域覆盖度 = sug词条包含的作用域元素 / 原始问题的作用域元素总数
- ```
- **评分影响**:
- - 覆盖度100% → 基础高分(0.9+)
- - 覆盖度50-99% → 中高分(0.6-0.9)
- - 覆盖度<50% → 中低分(0.3-0.6)
- - 覆盖度=0 → 低分或0分
- ---
- ## 部分作用域的处理
- ### 情况1:sug词条包含原始问题的所有对象层和场景层元素
- **评分**:0.95-1.0
- **示例**:
- ```
- 原始问题:"川西秋季风光摄影素材"
- - 对象层:摄影素材
- - 场景层:川西 + 秋季 + 风光
- Sug词条:"川西秋季风光摄影作品"
- - 对象层:摄影作品(≈素材)
- - 场景层:川西 + 秋季 + 风光
- - 覆盖度:100%
- - 评分:0.98
- ```
- ### 情况2:sug词条包含部分场景层元素
- **评分**:根据覆盖比例
- **示例**:
- ```
- 原始问题:"川西秋季风光摄影素材"
- - 对象层:摄影素材
- - 场景层:川西 + 秋季 + 风光(3个元素)
- Sug词条:"川西风光摄影素材"
- - 对象层:摄影素材 ✓
- - 场景层:川西 + 风光(2个元素)
- - 覆盖度:(1+2)/(1+3) = 75%
- - 评分:0.85
- ```
- ### 情况3:sug词条只包含对象层,无场景层
- **评分**:根据对象匹配度和覆盖度
- **示例**:
- ```
- 原始问题:"川西秋季风光摄影素材"
- - 对象层:摄影素材
- - 场景层:川西 + 秋季 + 风光
- Sug词条:"摄影素材"
- - 对象层:摄影素材 ✓
- - 场景层:无
- - 覆盖度:1/4 = 25%
- - 评分:0.50(对象匹配但缺失所有限定)
- ```
- ### 情况4:sug词条只包含场景层,无对象层
- **评分**:较低分
- **示例**:
- ```
- 原始问题:"川西旅行行程规划"
- - 对象层:旅行行程
- - 场景层:川西
- Sug词条:"川西"
- - 对象层:无
- - 场景层:川西 ✓
- - 覆盖度:1/2 = 50%
- - 评分:0.35(只有场景,缺失核心对象)
- ```
- ---
- # 评估核心原则
- ## 原则1:只看表面词汇,禁止联想推演
- **严格约束**:只能基于sug词实际包含的词汇评分
- **错误案例**:
- - ❌ "川西旅行" vs "旅行"
- - 错误:"旅行可以包括川西,所以有关联" → 评分0.7
- - 正确:"sug词只有'旅行',无'川西',缺失地域限定" → 评分0.50
- ---
- # 评分标准
- ## 【正向匹配】
- +0.95~1.0: 核心主体+所有关键限定词完全匹配
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"川西秋季风光摄影作品"
- +0.75~0.95: 核心主体匹配,存在限定词匹配
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"川西风光摄影素材"(缺失"秋季")
- +0.5~0.75: 核心主体匹配,无限定词匹配或合理泛化
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"四川风光摄影"
- +0.3~0.5: 核心主体匹配,但限定词缺失或存在语义错位
- - 特别注意"语义身份"差异,主体词出现但上下文语义不同
- - 例:
- · "猫咪的XX行为"(猫咪是行为者)
- · vs "用猫咪表达XX的梗图"(猫咪是媒介)
- · 虽都含"猫咪+XX",但语义角色不同
- +0.2~0.3: 主体词不匹配,限定词缺失或错位
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"风光摄影入门"
- +0.05~0.2: 主体词过度泛化或仅抽象相似
- - 例: sug词是通用概念,原始问题是特定概念
- sug词"每日计划"(通用)vs 原始问题 "川西旅行行程"(特定)
- → 评分:0.08
- 【中性/无关】
- 0: 类别明显不同,没有明确目的,无明确关联
- - 例: 原始问题"川西秋季风光摄影素材" vs sug词"人像摄影素材"
- - 例: 原始问题无法识别动机 且 sug词也无明确动作 → 0
- 【负向偏离】
- -0.2~-0.05: 主体词或限定词存在误导性
- - 例: 原始问题"免费摄影素材" vs sug词"付费摄影素材库"
- -0.5~-0.25: 主体词明显错位或品类冲突
- - 例: 原始问题"风光摄影素材" vs sug词"人像修图教程"
- -1.0~-0.55: 完全错误的品类或有害引导
- - 例: 原始问题"正版素材获取" vs sug词"盗版素材下载"
- ---
- # 批量评估核心原则
- ## 【极其重要】独立评估原则
- 1. **绝对评分**:每个SUG的评分必须基于与原始问题的匹配度,使用固定的评分标准
- 2. **禁止相对比较**:不要比较SUG之间的好坏,不要因为"其他SUG更好"而降低某个SUG的分数
- 3. **标准一致性**:对第1个SUG和第10个SUG使用完全相同的评分标准
- 4. **独立判断**:评估SUG A时,完全不考虑SUG B/C/D的存在
- **错误示例**:
- - ❌ "这个SUG比列表中其他的更完整,给0.95"
- - ❌ "相比第一个SUG,这个覆盖度较低,给0.6"
- **正确示例**:
- - ✅ "这个SUG包含对象层'摄影素材'和场景层'川西+秋季',覆盖度75%,根据评分标准给0.85"
- - ✅ "这个SUG只有场景'川西',无对象层,覆盖度50%,根据评分标准给0.35"
- ---
- # 输出格式
- 输出结果必须为一个 **JSON 格式**,包含evaluations数组,每个元素包含:
- ```json
- {
- "evaluations": [
- {
- "sug_text": "SUG文本",
- "品类维度得分": "-1到1之间的小数",
- "简要说明品类维度相关度理由": "评估理由"
- }
- ]
- }
- ```
- **输出约束(非常重要)**:
- 1. **字符串长度限制**:\"简要说明品类维度相关度理由\"字段必须控制在**150字以内**
- 2. **JSON格式规范**:必须生成完整的JSON格式,确保字符串用双引号包裹且正确闭合
- 3. **引号使用**:字符串中如需表达引用,请使用《》或「」代替单引号或双引号
- 4. **顺序严格对应(极其重要)**:
- - evaluations数组必须与输入的sug词条列表严格1对1对应
- - 第1个元素必须是输入列表的第1个SUG,第2个元素必须是第2个SUG,以此类推
- - 每个元素的sug_text必须与输入SUG完全一致(逐字匹配,包括标点)
- - 禁止改变顺序、禁止遗漏任何SUG、禁止重复评估
- - 示例:输入"1. 秋季摄影素材 2. 川西风光" → 输出[{sug_text:"秋季摄影素材",...}, {sug_text:"川西风光",...}]
- - 错误示例:输出[{sug_text:"川西风光",...}, {sug_text:"秋季摄影素材",...}] ← 顺序错误❌
- ---
- # 核心原则总结
- 1. **只看名词和限定词**:完全忽略动作和意图
- 2. **作用域覆盖优先**:覆盖的作用域元素越多,分数越高
- 3. **禁止联想推演**:只看sug词实际包含的词汇
- 4. **通用≠特定**:通用概念不等于特定概念
- 5. **理由纯粹**:评分理由只能谈对象、限定词、覆盖度
- 6. **独立评估**:每个SUG完全独立评估,禁止相对比较
- """.strip()
- motivation_evaluator = Agent[None](
- name="动机维度评估专家",
- instructions=motivation_evaluation_instructions,
- model=get_model(MODEL_NAME),
- model_settings=ModelSettings(temperature=TEMPERATURE),
- output_type=MotivationEvaluation,
- )
- category_evaluator = Agent[None](
- name="品类维度评估专家",
- instructions=category_evaluation_instructions,
- model=get_model(MODEL_NAME),
- model_settings=ModelSettings(temperature=TEMPERATURE),
- output_type=CategoryEvaluation,
- )
- # ============================================================================
- # Agent定义 - 批量评估
- # ============================================================================
- # 批量动机evaluator - 使用批量专用的prompt
- batch_motivation_evaluator = Agent[None](
- name="批量动机维度评估专家",
- instructions=batch_motivation_evaluation_instructions,
- model=get_model(MODEL_NAME),
- model_settings=ModelSettings(temperature=TEMPERATURE),
- output_type=BatchMotivationResult,
- )
- # 批量品类evaluator - 使用批量专用的prompt
- batch_category_evaluator = Agent[None](
- name="批量品类维度评估专家",
- instructions=batch_category_evaluation_instructions,
- model=get_model(MODEL_NAME),
- model_settings=ModelSettings(temperature=TEMPERATURE),
- output_type=BatchCategoryResult,
- )
- # ============================================================================
- # 评估函数
- # ============================================================================
- async def evaluate_single(sug: str, original_question: str) -> dict:
- """单个评估:对一个SUG进行动机+品类评估"""
- eval_input = f"""
- <原始问题>
- {original_question}
- </原始问题>
- <平台sug词条>
- {sug}
- </平台sug词条>
- 请评估平台sug词条与原始问题的匹配度。
- """
- # 并发调用两个评估器
- motivation_task = Runner.run(motivation_evaluator, eval_input)
- category_task = Runner.run(category_evaluator, eval_input)
- motivation_result, category_result = await asyncio.gather(
- motivation_task,
- category_task
- )
- motivation_eval: MotivationEvaluation = motivation_result.final_output
- category_eval: CategoryEvaluation = category_result.final_output
- return {
- "sug": sug,
- "motivation_score": motivation_eval.动机维度得分,
- "category_score": category_eval.品类维度得分,
- "motivation_reason": motivation_eval.简要说明动机维度相关度理由,
- "category_reason": category_eval.简要说明品类维度相关度理由,
- }
- async def evaluate_single_mode(sugs: list[str], original_question: str) -> tuple[list[dict], float]:
- """单个评估模式:逐个调用"""
- print(f"\n{'='*60}")
- print(f"模式1: 单个评估(调用{len(sugs)}次)")
- print(f"{'='*60}")
- start_time = time.time()
- results = []
- for i, sug in enumerate(sugs, 1):
- print(f" [{i}/{len(sugs)}] 评估: {sug}")
- result = await evaluate_single(sug, original_question)
- results.append(result)
- elapsed = time.time() - start_time
- print(f"\n✅ 单个评估模式完成")
- print(f" 耗时: {elapsed:.2f}秒")
- print(f" 平均每个SUG: {elapsed/len(sugs):.2f}秒")
- return results, elapsed
- async def evaluate_batch_mode(sugs: list[str], original_question: str) -> tuple[list[dict], float]:
- """批量评估模式:分别批量评估动机和品类维度"""
- print(f"\n{'='*60}")
- print(f"模式2: 批量评估(批量动机+批量品类,各评估{len(sugs)}个)")
- print(f"{'='*60}")
- start_time = time.time()
- # 构建批量评估输入
- sug_list_str = "\n".join([f"{i}. {sug}" for i, sug in enumerate(sugs, 1)])
- batch_input = f"""
- <原始问题>
- {original_question}
- </原始问题>
- <平台sug词条列表>
- {sug_list_str}
- </平台sug词条列表>
- 请对以上所有SUG每一个进行完全独立评估。
- """
- print(f" [1/2] 发送批量动机评估请求...")
- motivation_task = Runner.run(batch_motivation_evaluator, batch_input)
- print(f" [2/2] 发送批量品类评估请求...")
- category_task = Runner.run(batch_category_evaluator, batch_input)
- # 并发执行两个批量评估
- motivation_result, category_result = await asyncio.gather(
- motivation_task,
- category_task
- )
- batch_motivation: BatchMotivationResult = motivation_result.final_output
- batch_category: BatchCategoryResult = category_result.final_output
- elapsed = time.time() - start_time
- # ========== 顺序验证 ==========
- print(f"\n [验证] 检查批量评估结果顺序...")
- # 验证数量
- mot_count = len(batch_motivation.evaluations)
- cat_count = len(batch_category.evaluations)
- expected_count = len(sugs)
- if mot_count != expected_count:
- print(f" ⚠️ 警告: 动机评估数量不匹配! 期望{expected_count}个,实际{mot_count}个")
- if cat_count != expected_count:
- print(f" ⚠️ 警告: 品类评估数量不匹配! 期望{expected_count}个,实际{cat_count}个")
- # 验证顺序和文本匹配
- order_errors = []
- for i, (expected_sug, mot_item, cat_item) in enumerate(zip(sugs, batch_motivation.evaluations, batch_category.evaluations), 1):
- if mot_item.sug_text != expected_sug:
- order_errors.append(f" 位置{i}: 动机维度sug_text='{mot_item.sug_text}' != 期望'{expected_sug}'")
- if cat_item.sug_text != expected_sug:
- order_errors.append(f" 位置{i}: 品类维度sug_text='{cat_item.sug_text}' != 期望'{expected_sug}'")
- if order_errors:
- print(f" ❌ 发现顺序错误:")
- for error in order_errors[:5]: # 最多显示前5个错误
- print(error)
- if len(order_errors) > 5:
- print(f" ... 还有{len(order_errors)-5}个错误未显示")
- else:
- print(f" ✅ 顺序验证通过: 所有SUG文本与输入完全匹配")
- # 合并结果
- results = []
- for mot_item, cat_item in zip(batch_motivation.evaluations, batch_category.evaluations):
- results.append({
- "sug": mot_item.sug_text,
- "motivation_score": mot_item.动机维度得分,
- "category_score": cat_item.品类维度得分,
- "motivation_reason": mot_item.简要说明动机维度相关度理由,
- "category_reason": cat_item.简要说明品类维度相关度理由,
- })
- print(f"\n✅ 批量评估模式完成")
- print(f" 耗时: {elapsed:.2f}秒")
- print(f" 平均每个SUG: {elapsed/len(sugs):.2f}秒")
- print(f" (包含: 1次批量动机评估 + 1次批量品类评估)")
- return results, elapsed
- def compare_results(single_results: list[dict], batch_results: list[dict]):
- """对比两种模式的评估结果质量"""
- print(f"\n{'='*60}")
- print(f"结果质量对比")
- print(f"{'='*60}")
- # ========== 得分对比表格 ==========
- print(f"\n【得分对比】")
- print(f"\n{'SUG':<30} {'单个动机':<10} {'批量动机':<10} {'差异':<8} {'单个品类':<10} {'批量品类':<10} {'差异':<8}")
- print(f"{'-'*30} {'-'*10} {'-'*10} {'-'*8} {'-'*10} {'-'*10} {'-'*8}")
- total_motivation_diff = 0
- total_category_diff = 0
- for single, batch in zip(single_results, batch_results):
- sug = single['sug'][:28]
- single_mot = single['motivation_score']
- batch_mot = batch['motivation_score']
- mot_diff = abs(single_mot - batch_mot)
- single_cat = single['category_score']
- batch_cat = batch['category_score']
- cat_diff = abs(single_cat - batch_cat)
- total_motivation_diff += mot_diff
- total_category_diff += cat_diff
- print(f"{sug:<30} {single_mot:<10.2f} {batch_mot:<10.2f} {mot_diff:<8.3f} {single_cat:<10.2f} {batch_cat:<10.2f} {cat_diff:<8.3f}")
- avg_mot_diff = total_motivation_diff / len(single_results)
- avg_cat_diff = total_category_diff / len(single_results)
- print(f"\n平均得分差异:")
- print(f" 动机维度: {avg_mot_diff:.3f}")
- print(f" 品类维度: {avg_cat_diff:.3f}")
- print(f" 综合差异: {(avg_mot_diff + avg_cat_diff) / 2:.3f}")
- # ========== 评估理由对比 ==========
- print(f"\n{'='*60}")
- print(f"【评估理由对比】")
- print(f"{'='*60}")
- for i, (single, batch) in enumerate(zip(single_results, batch_results), 1):
- sug = single['sug']
- print(f"\n{i}. {sug}")
- print(f"{'-'*60}")
- # 动机维度理由对比
- print(f"\n 【动机维度】 (单个: {single['motivation_score']:.2f} | 批量: {batch['motivation_score']:.2f} | 差异: {abs(single['motivation_score'] - batch['motivation_score']):.3f})")
- print(f" 单个评估理由: {single['motivation_reason']}")
- print(f" 批量评估理由: {batch['motivation_reason']}")
- # 品类维度理由对比
- print(f"\n 【品类维度】 (单个: {single['category_score']:.2f} | 批量: {batch['category_score']:.2f} | 差异: {abs(single['category_score'] - batch['category_score']):.3f})")
- print(f" 单个评估理由: {single['category_reason']}")
- print(f" 批量评估理由: {batch['category_reason']}")
- # ============================================================================
- # 主函数
- # ============================================================================
- async def main():
- """主测试函数"""
- # 测试数据
- original_question = "如何获取能体现川西秋季特色的高质量风光摄影素材?"
- test_sugs = [
- "川西风光摄影",
- "秋季摄影素材",
- "高质量风光素材",
- "川西秋季旅游攻略",
- "风光摄影技巧",
- "川西风光",
- "摄影素材下载",
- "秋季旅行",
- "风光摄影作品",
- "获取川西秋季风景",
- ]
- print(f"{'='*60}")
- print(f"批量评估 vs 单个评估性能对比Demo")
- print(f"{'='*60}")
- print(f"\n原始问题: {original_question}")
- print(f"测试SUG数量: {len(test_sugs)}")
- print(f"\nSUG列表:")
- for i, sug in enumerate(test_sugs, 1):
- print(f" {i}. {sug}")
- # 模式1: 单个评估
- single_results, single_time = await evaluate_single_mode(test_sugs, original_question)
- # 模式2: 批量评估
- batch_results, batch_time = await evaluate_batch_mode(test_sugs, original_question)
- # 对比结果质量
- compare_results(single_results, batch_results)
- # 性能总结
- print(f"\n{'='*60}")
- print(f"性能总结")
- print(f"{'='*60}")
- print(f"单个评估模式: {single_time:.2f}秒")
- print(f"批量评估模式: {batch_time:.2f}秒")
- speedup = single_time / batch_time
- print(f"\n性能提升: {speedup:.2f}x")
- if speedup > 1:
- print(f"✅ 批量评估更快 {speedup:.2f}倍")
- else:
- print(f"❌ 批量评估更慢 {1/speedup:.2f}倍")
- print(f"\n{'='*60}")
- print(f"结论:")
- print(f"{'='*60}")
- if speedup > 1.5:
- print(f"✅ 批量评估显著更快,建议采用")
- elif speedup > 1.1:
- print(f"⚠️ 批量评估略快,但优势不明显")
- else:
- print(f"❌ 批量评估无性能优势,不建议采用")
- if __name__ == "__main__":
- asyncio.run(main())
|