mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
feat(金句分析): 明确告知 LLM 在 reason(选择理由/锐评)中提到群成员时,应使用 [用户ID] 格式
This commit is contained in:
+1
-1
@@ -401,7 +401,7 @@
|
||||
"type": "text",
|
||||
"editor_mode": true,
|
||||
"editor_language": "markdown",
|
||||
"default": "请从以下群聊记录中挑选出 **{max_golden_quotes}** 句最具冲击力、最令人惊叹的「金句」。\n\n## 金句标准:\n\n- **核心标准**:**逆天的神人发言**,即具备颠覆常识的脑洞、逻辑跳脱的表达或强烈反差感的原创内容\n- **典型特征**:包含某些争议话题元素、夸张类比、反常规结论、一本正经的「胡说八道」或突破语境的清奇思路,并且具备一定的冲击力,让人印象深刻\n\n## 对于每个金句,请提供:\n\n1. **原文内容**(完整保留发言细节)\n2. **发言人用户ID**(必须严格使用消息记录中提供的 [用户ID])\n3. **选择理由**(具体说明其「逆天」之处,如逻辑颠覆点/脑洞角度/反差感/争议话题元素)\n\n## 严格约束:\n\n- 优先筛选 **逆天指数最高** 的内容:\n - 发情、性压抑话题 > 争议话题 > 元素级 > 颠覆认知级 > 逻辑跳脱级 > 趣味调侃级\n - 剔除单纯玩梗或网络热词堆砌的普通发言\n- 重点标记包含极端类比、反常识论证或无厘头结论的内容,并且包含一定的争议话题元素\n- **身份对齐**:返回的 `sender` 字段必须是 `[用户ID]` 格式(例如 `[123456]`)。我们会根据 ID 自动还原昵称和头像。\n\n## 群聊记录格式: [HH:MM] [用户ID]: 消息内容\n\n## 群聊记录:\n\n{messages_text}\n\n---\n\n### 返回格式示例:\n\n```json\n[\n {{\n \"content\": \"金句原文\",\n \"sender\": \"[123456789]\",\n \"reason\": \"选择这句话的理由(需明确说明逆天特质)\"\n }}\n]\n```\n\n**注意**:请以纯 JSON 格式返回,不要包含 markdown 代码块标记。"
|
||||
"default": "请从以下群聊记录中挑选出 **{max_golden_quotes}** 句最具冲击力、最令人惊叹的「金句」。\n\n## 金句标准:\n\n- **核心标准**:**逆天的神人发言**,即具备颠覆常识的脑洞、逻辑跳脱的表达或强烈反差感的原创内容\n- **典型特征**:包含某些争议话题元素、夸张类比、反常规结论、一本正经的「胡说八道」或突破语境的清奇思路,并且具备一定的冲击力,让人印象深刻\n\n## 对于每个金句,请提供:\n\n1. **原文内容**(完整保留发言细节)\n2. **发言人用户ID**(必须严格使用消息记录中提供的 [用户ID])\n3. **选择理由**(具体说明其「逆天」之处,如逻辑颠覆点/脑洞角度/反差感/争议话题元素)\n\n## 严格约束:\n\n- 优先筛选 **逆天指数最高** 的内容:\n - 发情、性压抑话题 > 争议话题 > 元素级 > 颠覆认知级 > 逻辑跳脱级 > 趣味调侃级\n - 剔除单纯玩梗或网络热词堆砌的普通发言\n- **用户引用**:在选择理由(reason)中,如果提到了具体用户,请使用 `[用户ID]` 的格式来指代(例如 `[123456]`)。不要只写昵称。我们会自动渲染头像。\n- **身份对齐**:返回的 `sender` 字段必须是 `[用户ID]` 格式(例如 `[123456]`)。我们会根据 ID 自动还原昵称和头像。\n\n## 群聊记录格式: [HH:MM] [用户ID]: 消息内容\n\n## 群聊记录:\n\n{messages_text}\n\n---\n\n### 返回格式示例:\n\n```json\n[\n {{\n \"content\": \"金句原文\",\n \"sender\": \"[123456789]\",\n \"reason\": \"这句话太逆天了,尤其是对 [987654321] 的逻辑降维打击。\"\n }}\n]\n```\n\n**注意**:请以纯 JSON 格式返回,不要包含 markdown 代码块标记。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,9 @@ class GoldenQuoteAnalyzer(BaseAnalyzer):
|
||||
quote.user_id = potential_id
|
||||
quote.sender = id_to_nickname[potential_id]
|
||||
else:
|
||||
logger.warning(f"[金句分析] 无法匹配 User ID: {potential_id},金句将无法显示真实头像。")
|
||||
logger.warning(
|
||||
f"[金句分析] 无法匹配 User ID: {potential_id},金句将无法显示真实头像。"
|
||||
)
|
||||
|
||||
return quotes, usage
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ class ReportGenerator(IReportGenerator):
|
||||
|
||||
for i, topic in enumerate(topics[:max_topics], 1):
|
||||
# 处理话题详情中的用户引用头像
|
||||
processed_detail = await self._process_topic_detail(
|
||||
processed_detail = await self._render_mentions(
|
||||
topic.detail, avatar_getter, nickname_getter, user_analysis
|
||||
)
|
||||
topics_list.append(
|
||||
@@ -341,11 +341,15 @@ class ReportGenerator(IReportGenerator):
|
||||
if quote.user_id
|
||||
else None
|
||||
)
|
||||
# 处理解析锐评中的用户引用头像
|
||||
processed_reason = await self._render_mentions(
|
||||
quote.reason, avatar_getter, nickname_getter, user_analysis
|
||||
)
|
||||
quotes_list.append(
|
||||
{
|
||||
"content": quote.content,
|
||||
"sender": quote.sender,
|
||||
"reason": quote.reason,
|
||||
"reason": processed_reason,
|
||||
"avatar_url": avatar_url,
|
||||
}
|
||||
)
|
||||
@@ -391,22 +395,22 @@ class ReportGenerator(IReportGenerator):
|
||||
logger.info(f"渲染数据准备完成,包含 {len(render_data)} 个字段")
|
||||
return render_data
|
||||
|
||||
async def _process_topic_detail(
|
||||
async def _render_mentions(
|
||||
self,
|
||||
detail: str,
|
||||
text: str,
|
||||
avatar_getter,
|
||||
nickname_getter=None,
|
||||
user_analysis: dict | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
处理话题详情,将 [123456] 格式的用户引用替换为头像+名称的胶囊样式
|
||||
处理文本,将 [123456] 格式的用户引用替换为头像+名称的胶囊样式
|
||||
"""
|
||||
import re
|
||||
|
||||
pattern = r"\[(\d+)\]"
|
||||
matches = re.findall(pattern, detail)
|
||||
matches = re.findall(pattern, text)
|
||||
if not matches:
|
||||
return detail
|
||||
return text
|
||||
|
||||
async def replacer(match):
|
||||
uid = match.group(1)
|
||||
@@ -457,12 +461,12 @@ class ReportGenerator(IReportGenerator):
|
||||
# 这里为了保持异步特性,我们需要手动处理
|
||||
|
||||
# 1. 找出所有匹配项
|
||||
matches = list(re.finditer(pattern, detail))
|
||||
matches = list(re.finditer(pattern, text))
|
||||
if not matches:
|
||||
return detail
|
||||
return text
|
||||
|
||||
# 2. 从后往前替换,保持索引正确
|
||||
result = detail
|
||||
result = text
|
||||
for match in reversed(matches):
|
||||
replacement = await replacer(match)
|
||||
start, end = match.span()
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
<div class="q-analysis-note">
|
||||
<span class="note-label">🤣👉 AI 锐评:</span>
|
||||
{{ quote.reason }}
|
||||
{{ quote.reason | safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user