fix: 修改提示词同时添加后端校验,保证总占比不超过 100% (#119 @J621111)

* fix: 修改提示词同时添加后端校验,保证总占比不超过 100%

* fix: 将 ai 返回的占比限制在  [0, 100]
This commit is contained in:
NyaaByte
2026-03-23 00:42:18 +08:00
committed by Helian Nuits
parent ca104f2503
commit 4ffcb3065f
4 changed files with 22 additions and 35 deletions
+3 -3
View File
@@ -421,7 +421,7 @@
"type": "object",
"hint": "金句分析提示词模板,可自定义修改,保留变量 {max_golden_quotes} 和 {messages_text} 写法不要更改,需要写 JSON 块请使用双花括号 {{ ... }} 兼容当前编辑存在的问题。非常推荐根据实际群聊情况进行优化,保留一定提示样本示例供模型参考",
"items": {
"golden_quote_v2_prompt": {
"golden_quote_v2_prompt": {
"description": "默认金句分析提示词",
"type": "text",
"editor_mode": true,
@@ -440,7 +440,7 @@
"type": "text",
"editor_mode": true,
"editor_language": "markdown",
"default": "你是一个毒舌且幽默的群聊质量分析师,请生成聊天质量锐评内容。你需要按照下面的格式返回结果。\n\n分析接下来的群聊内容,给出多个维度的分析(3-6个)和汇总内容。\n\n群聊记录:\n{messages_text}\n\n### 返回格式示例:\n\n```json\n{{\n \"title\": \"群聊质量分析报告\",\n \"subtitle\": \"今天的群里发生了什么?\",\n \"dimensions\": [\n {{\n \"name\": \"水群闲聊\",\n \"percentage\": 50.0,\n \"comment\": \"群友们今天也在努力划水呢。\"\n }}\n ],\n \"summary\": \"今天也是元气满满的一天。\"\n}}\n```"
"default": "你是一个毒舌且幽默的群聊质量分析师,请生成聊天质量锐评内容。你需要按照下面的格式返回结果。\n\n分析接下来的群聊内容,给出多个维度的分析(3-6个,所有维度的占比加起来小于等于100%)和汇总内容。\n\n群聊记录:\n{messages_text}\n\n### 返回格式示例:\n\n```json\n{{\n \"title\": \"群聊质量分析报告\",\n \"subtitle\": \"今天的群里发生了什么?\",\n \"dimensions\": [\n {{\n \"name\": \"水群闲聊\",\n \"percentage\": 50.0,\n \"comment\": \"群友们今天也在努力划水呢。\"\n }}\n ],\n \"summary\": \"今天也是元气满满的一天。\"\n}}\n```"
}
}
}
@@ -471,4 +471,4 @@
}
}
}
}
}
@@ -91,7 +91,7 @@ class ChatQualityAnalyzer(BaseAnalyzer):
## 任务目标:
1. 将聊天内容划分为 3-6 个不同的维度/类别(如:技术探讨、水群闲聊、就业焦虑、深夜发情等)。
2. 为每个维度计算一个大致的百分比占位(总和 100%)。
2. 为每个维度计算一个大致的百分比占位(总和小于等于 100%)。
3. 为每个维度写一句犀利、幽默、毒舌或温情的点评。
4. 给出一句总结性的全群表现评价。
5. 设定一个本次报告的主题标题和副标题。
@@ -153,12 +153,26 @@ class ChatQualityAnalyzer(BaseAnalyzer):
Returns:
QualityReview 数据对象
"""
# 控制维度占比总和不超过100%
total_percentage = sum(
max(0.0, min(100.0, float(d.get("percentage", 0))))
for d in data.get("dimensions", [])
)
factor = 1.0
if total_percentage > 100:
factor = 100.0 / total_percentage
dimensions = []
for d in data.get("dimensions", []):
raw_p = float(d.get("percentage", 0))
final_p = round(max(0.0, min(100.0, raw_p)) * factor, 1)
dimensions.append(
QualityDimension(
name=d.get("name", "未知"),
percentage=float(d.get("percentage", 0)),
percentage=final_p,
comment=d.get("comment", ""),
)
)
@@ -139,25 +139,13 @@
<!-- Stacked dimension bar chart -->
<div class="retro-dimension-bar-container">
{% set total = 0 %}
{% for dim in dimensions %}
{% set total = total + dim.percentage %}
{% endfor %}
{% set scale = 1 %}
{% if total > 100 %}
{% set scale = 100 / total %}
{% elif total > 0 %}
{% set scale = 100 / total %}
{% endif %}
{% set bg_colors = ['var(--c-accent)', 'var(--c-dec-1)', 'var(--c-dec-3)', 'var(--c-dec-2)', '#FFBA08', '#273C75', '#E07A5F', '#8D99AE'] %}
{% set txt_colors = ['#ffffff', '#ffffff', '#000000', '#ffffff', '#000000', '#ffffff', '#000000', '#ffffff'] %}
{% for dim in dimensions %}
{% if dim.percentage > 0 %}
<div class="retro-dimension-segment"
style="width: {{ dim.percentage * scale }}%; background-color: {{ bg_colors[loop.index0 % bg_colors|length] }}; color: {{ txt_colors[loop.index0 % txt_colors|length] }};"
style="width: {{ dim.percentage }}%; background-color: {{ bg_colors[loop.index0 % bg_colors|length] }}; color: {{ txt_colors[loop.index0 % txt_colors|length] }};"
title="{{ dim.comment }}">
<span style="display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; padding: 0 5px;">
{{ dim.name }} {{ dim.percentage }}%
@@ -233,21 +233,6 @@
<div class="dimension-bar-container">
<div class="dimension-bar">
{% set ns = namespace(total=0) %}
{% for dim in dimensions %}
{% set safe_percentage = dim.percentage|float %}
{% if safe_percentage < 0 %}
{% set safe_percentage = 0 %}
{% elif safe_percentage > 100 %}
{% set safe_percentage = 100 %}
{% endif %}
{% set ns.total = ns.total + safe_percentage %}
{% endfor %}
{% set scale = 1 %}
{% if ns.total > 0 %}
{% set scale = 100 / ns.total %}
{% endif %}
{% set colors = ['#ffb74d', '#ff8a65', '#ba68c8', '#4db6ac', '#4dd0e1', '#64b5f6', '#81c784', '#e57373'] %}
{% for dim in dimensions %}
{% set safe_percentage = dim.percentage|float %}
@@ -258,7 +243,7 @@
{% endif %}
{% if safe_percentage > 0 %}
<div class="dimension-segment"
style="width: {{ safe_percentage * scale }}%; background-color: {{ colors[loop.index0 % colors|length] }};"
style="width: {{ safe_percentage }}%; background-color: {{ colors[loop.index0 % colors|length] }};"
title="{{ dim.comment }}">
<span class="segment-label"
style="display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;">
@@ -287,7 +272,7 @@
<div class="small-tape" style="transform: translateX(-50%) rotate({{ tape_rot }});"></div>
<div style="display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px;">
<strong class="dim-sticker-title" style="color: {{ colors[loop.index0 % colors|length] }}; border-color: {{ colors[loop.index0 % colors|length] }}; margin-bottom: 0;">{{ dim.name }}</strong>
<span style="font-size: 0.86em; font-weight: 700; color: {{ colors[loop.index0 % colors|length] }};">{{ '%.1f'|format(safe_percentage * scale) }}%</span>
<span style="font-size: 0.86em; font-weight: 700; color: {{ colors[loop.index0 % colors|length] }};">{{ '%.1f'|format(safe_percentage) }}%</span>
</div>
<span>{{ dim.comment }}</span>
</div>