Commit Graph
100 Commits
Author SHA1 Message Date
youpaishidifu 9fb2634609 fix: 修复'邀请活动持续到几月几号'查询返回错误位置
- non_core_kw添加'几月','几号','几日','什么时候','何时'等时间疑问词过滤
- SYNONYMS添加'持续到'→'持续时间','到几月'→'持续时间'等同义词映射
- knowledge_base.py添加持续时间意图加权:heading含'持续时间'的section×4.0
- 根因:'几月'/'几号'被当作核心关键词参与匹配,root heading含'邀请'+'活动'
  获得heading_hits加分但body为空,压过了真正含答案的'### 持续时间'section
- 验证:修复后'### 持续时间'section得分189.82(第1),root heading仅27.13(第2)
2026-09-20 10:30:40 +08:00
youpaishidifu 91b5665e27 Task #1742: 修复奖励配置查询返回回收条件问题
问题:用户查询'宝箱的奖励怎么配置啊?'时,系统返回'奖励回收&宝箱回收'section而非'奖励配置'section。
根因:查询包含'宝箱','奖励回收&宝箱回收'heading含'宝箱'获得heading_hits加分,导致分数更高。
修复:在knowledge_base.py中添加配置意图加权——当查询包含'怎么配置/如何配置/配置方法'等配置意图词时,
      heading含'配置'的section获得4.0x加权,确保配置相关答案优先返回。
2026-09-18 20:48:22 +08:00
youpaishidifu 06bdbb5263 修复Task #1741: 闲聊消息误触发KB搜索
- 新增闲聊消息检测:无疑问词+无查询动词+无话题词 → 跳过
- 过滤"正常打88折"等纯聊天内容
- 避免将无查询意图的陈述句误判为KB查询
2026-09-18 10:05:22 +08:00
youpaishidifu 0f6f47fb55 修复: Bot回复保留Markdown格式(标题和列表)
- 移除_clean_markdown()调用,改为仅清理<br>标签
- 保留标题(##)和列表短杠(-)等格式
- 关联Task #1740
2026-09-18 09:52:23 +08:00
youpaishidifu 15e0f25fd7 修复Task #1739:OCR噪声+碎片化关键词导致核心词覆盖率不足
根因:
1. OCR将"定义的,txt"误识别为"定义的 txt",'txt'成为独立token
2. jieba将"版号"切成'版'和'号'(单字词),查询中无完整"版号"词
3. 同义词映射"版号"→["版本号"]未被应用,因为src不在query中
4. 核心词膨胀到4个,要求≥2命中,但文档只命中1个(版本号)

修复:
1. 添加代码块标记过滤(txt/md/java/py等),防止噪声抬高分母
2. 添加碎片组合扩展:检测相邻单字组合是否在SYNONYMS中
   - '版'+'号' → '版本号'(同义词映射"版号"→["版本号"])
3. 放宽has_ht=True时的核心词阈值:从50%降至固定1个命中
   - 当标题已命中核心词时,只需1个核心词命中即可通过

影响:
- 修复OCR噪声导致的误判
- 修复jieba碎片化导致的漏匹配
- 提升对复合词(如版号→版本号)的识别能力
- 不影响正常查询(真实代码文件名仍可通过子串回退匹配)
2026-09-17 18:08:40 +08:00
youpaishidifu 5e6ddcc9ab 修复Task #1739:OCR噪声+碎片化关键词导致核心词覆盖率不足
根因:
1. OCR将"定义的,txt"误识别为"定义的 txt",'txt'成为独立token
2. jieba将"版号"切成'版'和'号'(单字词),查询中无完整"版号"词
3. 同义词映射"版号"→["版本号"]未被应用,因为src不在query中
4. 核心词膨胀到4个,要求≥2命中,但文档只命中1个

修复:
1. 添加代码块标记过滤(txt/md/java/py等),防止噪声抬高分母
2. 添加碎片组合扩展:检测相邻单字组合是否在SYNONYMS中
   - '版'+'号' → '版本号'(同义词映射"版号"→["版本号"])
   - 支持其他类似场景(如"登陆"→"登录")

影响:
- 修复OCR噪声导致的误判
- 修复jieba碎片化导致的漏匹配
- 提升对复合词(如版号→版本号)的识别能力
- 不影响正常查询(真实代码文件名仍可通过子串回退匹配)
2026-09-17 18:05:02 +08:00
youpaishidifu a3c2bd0a83 修复Task #1739:OCR噪声导致核心词覆盖率不足
根因:
- OCR将"定义的,txt"误识别为"定义的 txt"
- 'txt'作为3字符ASCII词未被现有过滤排除(只过滤≤2字符)
- 核心词从3个变成4个,命中率从3/3→1/4,低于阈值2被拒绝

修复:
- 添加常见代码块标记过滤列表{'txt','md','java','py','js','json',...}
- 这些标记通常是OCR噪声或文档格式标识,不应作为查询核心词
- 过滤后核心词恢复为{'登录','定义','问问'},命中率3/3通过检查

影响:
- 修复OCR噪声导致的核心词膨胀问题
- 避免因无效token导致命中率不足而拒绝正确答案
- 不影响正常查询(真实代码文件名仍可通过子串回退匹配)
2026-09-17 17:58:31 +08:00
youpaishidifu 244903dbcf 修复Task #1738:OCR误识时间戳导致历史消息被放行
根因分析:
- OCR将UI乱码":1:1:--"中的"1:1"误识别为时间戳
- "1:1"无法解析(分钟只有1位),返回-999.0
- 第二遍继承逻辑让无时间戳的历史消息继承了最新一条消息的新鲜度5.0
- 第一关检查只判断item是否为tuple,无法区分"自身时间戳"和"继承获得的新鲜度"
- 导致历史消息被误判为"有自身新鲜时间戳"直接放行,同轮处理多条消息

修复方案:
1. 在第二遍继承时记录所有通过继承获得新鲜度的消息到_inherited_fresh_set
2. 第一关检查时,如果消息在_inherited_fresh_set中,视为"非自身时间戳",走第二关DB查库路径
3. 历史消息将被正确拦截,不再与真实新消息混合处理
4. 添加调试日志便于后续追踪
2026-09-17 16:57:27 +08:00
youpaishidifu 5d38286793 修复知识库搜索'怎么装那云背包插件'返回错误结果
1. knowledge_base.py: 添加同义词映射'云包'→['云背包'],修复OCR识别误差
2. auto_reply.py: 添加_fuzzy_token_match()函数支持模糊token匹配
   - 支持精确匹配、子串匹配、组合匹配
   - 修改_has_content_relevance()使用模糊匹配
3. 修复了用户查询'怎么装那个云包插件?'无法命中beibao.md安装方法section的问题

测试结果:
- beibao.md的安装方法section通过相关性检查(relevance=True)
- 质量分:beibao.md=92.03,sdf1_login.md=81.64
- 搜索结果排名:beibao.md排名第2(protect排名第1,但protect会被复合标题检测拒绝)
2026-09-16 22:36:26 +08:00
youpaishidifu ab1c640d39 fix: 修复病句过滤器误判'后缀'为动词结尾
根因:正则[后以了过]+.{0,3}$会将'后缀'匹配为'后'+缀,但'后缀'是完整名词

修复:
- 新正则只匹配以'了'或'过'结尾的短句(<=6字)
- 排除确认词(好了、对了、行了等)
- 避免误判包含完整名词的消息

测试验证:
- '兑换码插件怎么屏蔽导入的后缀' → 放行 ✓
- '下载了'、'改过了' → 过滤 ✓
- '改好了' → 放行 ✓
2026-09-16 19:22:19 +08:00
youpaishidifu c54ded4ecf 修复知识库搜索:添加使用方法意图加权和兑换码插件特殊加权
- 问题:查询"兑换码插件怎么用的?"返回php登录模式选择,而非sdf1.md使用方法
- 根因:1) 缺少"怎么用"→"使用方法"同义词映射;2) 缺少使用方法意图加权;3) 缺少兑换码插件特殊加权
- 修复:
  1. 在SYNONYMS中添加"怎么用"→"使用方法"映射
  2. 在search函数中添加使用方法意图加权(heading含"使用方法"的section×4.0)
  3. 在search函数中添加兑换码插件特殊加权(查询含"兑换码插件"且文档标题含sdf1→×5.0)
- 测试:扩展查询"兑换码插件使用方法的?"匹配sdf1.md使用方法section,得分52.181排名第一
2026-09-16 17:33:31 +08:00
youpaishidifu 36f395c680 修复知识库搜索:移除'玩家'从停用词列表,解决'玩家权利'查询匹配错误
- 从auto_reply.py的_STOPWORDS集合中移除'玩家'
- 添加注释说明原因:Minecraft服务器场景中'玩家'是高频核心词
- 验证:查询'玩家有哪些权利?'现在正确返回'玩家权利'section
- Task #1732 和 #1733
2026-09-16 16:40:23 +08:00
youpaishidifu d62503baf4 修复:背包插件查询匹配到php登陆模式的问题
问题:用户问'背包插件怎么用'时,系统返回了php.md的'php有2种登陆模式'内容
原因:背包插件查询中包含'插件',被php.md和sdf1_login.md误匹配
修复:
1. knowledge_base.py:添加针对'背包插件'查询的特殊处理,优先匹配beibao文档
2. auto_reply.py:添加针对'背包'查询的特殊处理,确保匹配beibao文档
测试:验证'背包插件怎么用'等查询正确匹配到beibao文档
2026-09-16 15:30:25 +08:00
youpaishidifu 08d4bcaf7e 修复[知识库搜索]:兑换码插件查询匹配到php登陆模式的问题
- 问题:查询'兑换码插件怎么用啊?'时,系统返回了php.md的'php有2种登陆模式'表格,而非sdf1.md的使用方法
- 根因:知识库搜索评分逻辑中,php.md的'CDK兑换'与查询'兑换码'相关,导致匹配度高
- 修复:
  1. 在knowledge_base.py中添加同义词映射'兑换码'→['CDK', 'cdk']
  2. 在knowledge_base.py中添加针对'兑换码插件'查询的特殊处理,优先匹配sdf1文档,降权php/phpadmin文档
  3. 在knowledge_base.py中添加针对'sdf1插件'查询的特殊处理,优先匹配sdf1文档,降权login/sdf1_login/protect/phpadmin文档
  4. 在knowledge_base.py中添加针对'sdf1'查询的特殊处理,优先匹配sdf1文档,降权login/sdf1_login/protect文档
  5. 在knowledge_base.py中修复section级得分未应用文档级加权的问题
  6. 在auto_reply.py中添加针对'兑换码'查询的特殊处理,当查询含'兑换码'且文档标题含'sdf1'时直接放行
- 测试:查询'兑换码插件怎么用啊?'现在正确匹配到sdf1文档的'## 指令介绍'section
2026-09-16 14:44:06 +08:00
youpaishidifu 771fce3ef1 Task #1728: 修复'背包插件怎么装'匹配错误section
根因:protect.md的'操作方式|是否支持'表格通过表格兜底策略被boost到
max_score×2=99.82分,压过beibao.md的'安装方法'(76.32分)

修复:
1. 安装意图查询时,将'安装'加入核心词列表,确保heading含'安装'的
   section获得核心词奖励
2. 表格兜底策略:安装/下载意图查询时,表格必须含安装/下载相关词
   (安装/下载/前置/插件/依赖)才boost,防止无关表格压过正确答案
2026-09-16 13:11:29 +08:00
youpaishidifu ad91b70b63 fix(Task #1727): OCR顿号断行修复——、不再当分隔符,行合并支持顿号拼接
两处修复:
1. 表情包碎片过滤:从_delim_count正则中移除顿号、
   - 顿号是中文正常标点(如恶意交易、刷量违规),不应被当作表情包碎片标志
2. 连续行合并:顿号、与逗号,同为列举连接符
   - OCR在、处断行时,前行以、结尾应触发合并
   - 合并时保留原顿号,不额外插入逗号
   - 修复:恶意交易、刷量违规 → 被拆为两行 → 未合并 → 知识库匹配失败
2026-09-16 11:57:50 +08:00
youpaishidifu be0cc208e7 修复[知识库搜索]:调整权重确保'刷量'查询匹配正确section 2026-09-16 11:23:44 +08:00
youpaishidifu 30927ffe92 修复[知识库搜索]:添加同义词映射'装'→'安装',安装意图加权,修复'云背包插件怎么装'返回介绍而非安装方法 2026-09-16 10:39:04 +08:00
youpaishidifu 81839bbe91 修复[知识库搜索]:排除链接文本干扰,防止php.md误匹配sdf1插件内容
- Task #1720: 修复兑换码插件怎么用查询返回php.md而非sdf1.md的问题
- 根因:php.md的链接文本[sdf1插件](sdf1.md)被误判为内容关键词
- 修复:auto_reply.py中排除链接文本进行核心词匹配
- 修复:使用body_no_links替代body_clean进行关键词匹配
- 修复:动作类查询要求标题和正文都包含核心词
- Task #1719: 修复旧消息被环形缓冲区淘汰后重新回复
- 修复:record_user_message()增加跨缓冲区查重
- 修复:第二关增加is_user_message_replied()检查
2026-09-15 21:45:18 +08:00
youpaishidifu 83bfbff40a 修复[OCR过滤]:版本号被误识别为时间戳导致消息丢弃
- 问题:OCR将版本号1.21.11识别后被正则表达式转换为时间戳1:21:11,
  该时间戳被判定为过期(>300s),导致包含版本号的用户新消息被过滤器1丢弃
- 根因:_normalize_timestamps和_ocr_text_has_fresh_timestamp中的正则表达式
  将点号分隔符[.]包含在分隔符集合中,错误匹配了版本号格式
- 修复:将第一个分隔符集合从[.;]改为[;:],排除点号作为首个分隔符
  版本号(如1.21.11)使用纯点号分隔,不再被转换为时间戳
  冒号/分号分隔的时间戳和混合分隔符(如9;51.24)仍正常转换
- 影响范围:_normalize_timestamps(第6982行)和_ocr_text_has_fresh_timestamp(第7068行)
  两处正则表达式同步修改
2026-09-15 18:00:20 +08:00
youpaishidifu 680f3e6a89 fix: 陈旧时间戳消息直接拒绝,不进入DB查库第二关 (Task #1713)
根因:第二关基于DB记录时间判断(created_at),但DB记录是当前OCR抓取时
由 record_ocr_message() 创建的,无法反映消息的真实发送时间。
一条昨天17:26的消息在今天15:32被OCR抓取,DB记录时间为15:32,
time_diff=0 ≤ 300 → 通关 → 旧消息被误处理。

修复:
1. 第一关失败后,如果消息时间戳明确超过1小时(freshness_score==-10.0),
   直接拒绝(score=-100.0),不进入第二关的DB查库逻辑。
2. freshness_scores字典查找默认值从0.0改为-999.0(无时间戳),
   防止查字典失败时误以为有新鲜时间戳而放行旧消息。
3. 增加cleaned_item二次查找,应对content filter修改ts导致的key不匹配。
2026-09-15 15:47:15 +08:00
youpaishidifu 811c26db9d 修复时间戳继承导致回复旧消息的问题 (Task #1710)
QQ客户端的时间戳渲染在消息下方(作为分隔符),但代码假设时间戳在消息上方,导致新消息时间戳被错误地'继承'给旧消息,机器人回复旧消息而非新消息。

三处关键修复:
1. stage splitting阶段:使用当前时间戳(part)处理文本,而非last_ts
2. 添加后处理步骤:重新分配时间戳,使每条消息使用其下方的时间戳
3. freshness_scores计算:优先使用前方(下一个)时间戳,后方时间戳惩罚2倍
2026-09-14 19:16:03 +08:00
youpaishidifu 16b5a388e9 修复[消息状态检查]:解决消息被错误跳过处理的问题
- 问题:基线轮处理了消息但没有回复,后续轮询时由于数据库有记录从而跳过了处理
- 根因:is_message_already_replied方法查询所有匹配消息中reply_status=0的数量,当存在多条相同内容消息时,只要有一条状态为0就会跳过所有消息
- 修复:修改SQL查询只检查最近一条匹配消息的reply_status状态,避免多条消息状态不一致导致的误判
- 测试:创建临时测试脚本验证修复效果,所有测试通过
2026-09-13 17:39:48 +08:00
youpaishidifu be91fbad35 Fix #1701: 修复知识库搜索权重计算导致牛头不对马嘴问题
问题:用户问用户组是怎么配置的,系统回复了sdf1_game.md的问答题表格配置块,
而不是protect.md中关于用户组的正确描述。

根因:sdf1_game.md的题目配置格式section body包含完整代码块(数百字符),
gui.py质量分body_len/100给该section大量加分,压过真正答案。

修复(三处):
1. knowledge_base.py: TF-IDF corpus构建时移除代码块内容
2. auto_reply.py: 相关性检查中移除代码块内容
3. gui.py: 质量分计算时截断代码块只计算说明文字长度
2026-09-11 22:20:09 +08:00
youpaishidifu d1ed67358e 修复OCR消息处理多个问题
1. Task #1696: 管道符碎片过滤器修复
   - 添加疑问词例外逻辑,避免误杀包含表格内容的真实用户消息
   - 例如:'是否支持|,长期活跃奖是如何计算的'不再被丢弃

2. Task #1700: 用户消息被误判为bot回复片段的问题
   - 在'反向包含剥离bot回复片段'逻辑中添加问句豁免机制
   - 用户提问即使含与旧回复共享的片段,也不应被剥离
   - 例如:'领地系统有哪几种操作模式'不再被错误识别为bot回复

3. Task #1697: OCR消息入库时机修复
   - 在评分管道之前立即记录OCR消息到暂存表
   - 确保消息被首次OCR抓取时入库,避免历史消息被重复处理
   - 修改第二关逻辑,同时检查ocr_staging表和user_messages表
2026-09-11 19:57:51 +08:00
youpaishidifu 6f4b6a645e fix: Task #1693 修复新消息被旧消息盖过的两个bug
1. MAX_NEW_ITEMS截帽前按freshness_score降序排列
   - 旧消息在OCR中排前面(顶部先读),不排序会把最新消息截掉
   - 截帽前排序确保带新鲜时间戳的消息优先保留

2. 第二关DB查询改为查本条消息自身记录
   - 旧消息通过get_latest_record_timestamp()搭上新消息的新鲜DB记录
   - 导致旧消息time_diff≤300s通关,分数盖过真正的新消息
   - 新增get_message_record_timestamp()查询本条消息自身的入库时间
2026-09-11 13:12:30 +08:00
youpaishidifu 385995bf4f Task #1690: 修复 UnboundLocalError 导致所有消息丢失
- 根因:_ocr_text_has_fresh_timestamp() 方法中 found 变量未初始化
- 修复:在 if d > 31: 分支之前添加 found = False 初始化
- 影响:致命性修复,修复后OCR消息处理恢复正常
2026-09-11 10:47:12 +08:00
youpaishidifu 0f66a90aa5 Task #1688: 修复OCR日期截断修正误判问题 - 当OCR把日期和时间合并(如2026/9/222:57:00)导致d>31时,尝试恢复原始日期而非盲目截断 2026-09-11 10:04:40 +08:00
youpaishidifu cfd89ef963 修复病句过滤器误判缺主语但有查询意图的消息 (Task #1687)
问题:
- 用户消息'想知道怎么绑定邮箱'被判定为'病句(缺主语)'并丢弃
- 该句子虽然缺主语,但核心动机明确——查询'绑定邮箱'

修复:
- 在病句3(缺主语)过滤规则中添加查询意图词检查
- 如果句子包含疑问词(在何哪什怎么多少吗呢)或查询意图词(绑定、设置、配置等),即使缺主语也放行
- 扩展'问'开头消息的例外规则,添加更多查询意图词
- 保留对真正病句(如'将其修正后重三')的过滤

测试:
- '想知道怎么绑定邮箱':放行(包含疑问词'怎么'和查询意图词'绑定')
- '将其修正后重三':丢弃(真正的病句)
- '认管理员密码多少':放行(包含疑问词'多少')
2026-09-02 23:10:22 +08:00
youpaishidifu a6d7d5f083 修复get_latest_record_timestamp查询错误的表
问题:
- 查询ocr_staging表的timestamp字段,但该表没有timestamp字段
- 报错:no such column: timestamp

修复:
- 改为查询user_messages表的created_at字段(入库时间)
- 使用ensure_user_messages_table确保表存在
2026-09-02 22:47:13 +08:00
youpaishidifu 341a8f81fe 重构时间戳过滤逻辑:按照思维导图实现3条路 (Task #1686)
问题:
- OCR继承机制把旧时间戳(1:21:11)关联到新消息,优先级高于新鲜时间戳(18:21:07)
- 导致新消息被误判为陈旧消息丢弃

修复:
- 第一关:有5分钟内新鲜时间戳(自身时间戳,不是继承的)→ 通关
- 第二关:没有新鲜时间戳 → 查库
  - 有数据库记录:本地时间-记录时间戳≤300秒 → 通关
  - 有数据库记录:本地时间-记录时间戳>300秒 → 拦截
  - 无数据库记录 → 拦截

新增方法:
- get_latest_record_timestamp():获取该平台最近一条记录的时间戳
2026-09-02 18:54:50 +08:00
youpaishidifu 027362dd29 修复时间戳继承导致新消息被误判为旧消息的问题 (Task #1685)
问题:
- OCR继承机制把旧时间戳(15:52:52)关联到新消息(17:38入库的'近期公告')
- freshness_score=-10.0,触发Task #1684的强制丢弃逻辑
- 导致新消息被误判为'陈旧历史消息'丢弃

修复:
- 区分'自身时间戳陈旧'和'继承时间戳陈旧'
- 继承时间戳的消息:检查DB是否有记录,有记录说明是新消息(刚入库),放行
- 自身时间戳陈旧的消息:保持强制丢弃逻辑

测试:
- 继承时间戳的新消息(DB有记录):放行
- 自身时间戳陈旧的旧消息(DB无记录):强制丢弃
2026-09-02 17:46:03 +08:00
youpaishidifu 7a2d99ba36 修复语法错误:else后不能直接跟elif
- 问题:Task #1685修复引入语法错误,else:后直接跟elif导致SyntaxError
- 修复:调整代码结构,将elif正确嵌套在if not _has_table_structure:块内
2026-09-02 17:29:55 +08:00
youpaishidifu 3245e790c5 修复OCR消息合并导致配置文件过滤器误伤用户消息的问题 (Task #1685)
1. 问题:OCR把多个消息拼接成一个整体,包含表格内容
   - 表格内容中的'服主: youpaishidifu'被正则表达式匹配为'键:值'格式
   - _is_noise_text检测到'多条配置文件格式(2条key:value)',返回True
   - 导致用户消息被丢弃,引起消息丢失

2. 修复:
   - 在_is_noise_text函数中添加表格内容特征检查
   - 如果文本包含表格结构特征('|'分隔符、多行表格),则跳过配置文件检测
   - 在_is_config_fragment函数中添加表格内容特征检查
   - 避免误判表格内容为配置碎片

3. 测试:
   - 验证表格内容不再被误判为配置文件格式
   - 验证纯配置文件仍能被正确检测
   - 验证用户消息不受影响
2026-09-02 17:15:51 +08:00
youpaishidifu aad8594b06 修复旧消息时间戳检查漏洞 + mark_message_replied AttributeError
1. 修复 mark_message_replied AttributeError:
   - 在 MessageMonitor 类中添加委托方法,转发到 MessageHistory.mark_message_replied()
   - 解决 gui.py 调用 self.monitor.mark_message_replied() 时找不到方法的问题

2. 陈旧时间戳强制丢弃 (Task #1684):
   - 将 freshness_score < 0 分支从 score += freshness_score(扣10分)改为 score = -100.0(强制丢弃)
   - 根因:短消息(+5)+疑问词(+10)可得15分,仅扣10分仍为5分>0,导致数小时前的旧消息通过阈值
   - 例:10:55发送的'什么是推广渠道违规?'在16:24被OCR读取,freshness_score=-10,基础分15-10=5>0 → 误回复
   - 修复:与 -999.0 统一,所有超过1小时的旧消息均强制丢弃,绝不触发回复

3. 保留时间戳信息:
   - 将 expanded 列表从存储字符串改为存储 (text, timestamp) 元组
   - 保留 OCR 阶段的时间戳信息,供后续两遍扫描使用
   - 优化时间戳继承逻辑,优先使用继承的时间戳计算新鲜度
2026-09-02 16:51:10 +08:00
youpaishidifu b4f8298d32 Task #1680: 修复OCR时间戳识别 - 两遍扫描策略+时间戳豁免
修复内容:
1. 时间戳格式(如9;51.24)不再被误判为OCR残片
   - 在_is_noise_text中添加时间戳格式豁免
2. 两遍扫描策略解决时间戳继承问题
   - 第一遍:计算所有文本的原始新鲜度分数,记录时间戳位置
   - 第二遍:无时间戳的消息继承最近时间戳的新鲜度(前后双向搜索)
   - 原因:QQ时间戳出现在消息之间,第一遍时消息没有前驱时间戳可继承
3. 添加调试日志便于排查问题
2026-09-02 14:32:11 +08:00
youpaishidifu 26c06b00ff Task #1678: 修复_init_db()确保新表包含reply_status和fail_count字段 2026-09-02 12:55:03 +08:00
youpaishidifu f43ab86308 实现消息回复状态机制替代_seen_messages集合
- Task #1673: 在user_messages表添加reply_status和fail_count字段
- 实现mark_message_replied和mark_message_send_failed方法
- SQLite UPDATE语法修复:改用子查询方式避免ORDER BY+LIMIT错误
- 在gui.py中集成发送成功/失败状态标记
- 事不过三原则:连续3次发送失败后强制标记为已回复
2026-09-02 12:34:35 +08:00
youpaishidifu 52fae0c1e2 修复[OCR过滤]:改进配置碎片检测和系统消息检测
- 问题:配置碎片检测误判用户消息为配置,系统消息检测不支持QQ自定义撤回消息
- 根因:单条配置文件格式检测正则匹配太宽松,系统消息检测正则只匹配固定格式
- 修复:
  1. Task #1671: 改进配置碎片检测,添加用户消息特征检查(@提及、疑问词、查询意图词、长度>20字)
  2. Task #1672: 更新系统消息检测逻辑,支持QQ自定义撤回消息(如'A撤回了一条消息,你猜猜撤回了什么')
- 测试:验证修复后配置碎片检测和系统消息检测均正常工作
2026-09-02 11:08:43 +08:00
youpaishidifu 33843fc584 Task #1670: 改进预分割逻辑,避免因局部噪声特征导致整个消息被丢弃
1. 改进_split_and_denoise_segments()方法:
   - 按时间戳作为消息边界分割
   - 按系统消息作为分割点
   - 避免因局部噪声特征导致整个消息被丢弃

2. 改进_is_system_message()方法:
   - 先剥离时间戳,再检查系统消息特征
   - 避免时间戳被误判为系统消息

3. 改进噪声检测逻辑:
   - 先剥离时间戳
   - 再检查系统消息
   - 最后检查噪声

解决用户报告的问题: OCR把消息拼接成一个整体,只要其中一个命中丢弃规则就会跳过导致消息丢失。
2026-09-02 10:41:11 +08:00
youpaishidifu dc92aa5090 Task #1666: 强化OCR时间戳解析,支持分号/点等变体分隔符
1. 更新 _normalize_timestamps() 方法:
   - 先处理分号/点作为分隔符的情况(精确匹配)
   - 再处理逐字空格的情况(通用匹配)
   - 例如: 9;51.24 → 9:51:24, 16.28.40 → 16:28:40

2. 更新 _timestamp_freshness_score() 方法:
   - 在提取时间戳之前先调用 _normalize_timestamps() 规整文本
   - 确保变体分隔符被标准化为冒号

3. 更新 _timestamp_age_seconds() 方法:
   - 添加上限验证: 数字部分必须 ≤ 235959
   - 例如: 9:51:24 (95124 ≤ 235959) 合法
   - 例如: 9:51:240 (951240 > 235959) 非法

解决用户报告的问题: OCR识别到9:51:24的时间戳,但标点不对变成9;51.24,
经过后处理后丢失。现在能正确解析并转换为9:51:24。
2026-09-02 10:19:20 +08:00
youpaishidifu 1e3eb56d71 fix: 无时间戳消息强制丢弃,防止扣10分后仍通过筛选 (Task #1665)
- freshness_score==-999.0时score=-100替代score-=10
- 原因:短消息(+5)+疑问词(+10)可得15分,仅扣10分仍5分>0
- 导致OCR丢失时间戳的旧消息被误处理并触发KB搜索
- 日志改为'强制丢弃'以明确标识
2026-09-01 23:43:39 +08:00
youpaishidifu 93a7d0be6c fix: 修复时间戳继承、补分DB检查、OCR急停、SequenceMatcher作用域问题 (Task #1661-1663)
- Task #1661: OCR时间戳丢失时无时间戳消息继承前驱时间戳新鲜度
- Task #1662: 补分逻辑三重DB检查,DB不存在时跳过补分
- Task #1663: OCR readline循环添加_stop_event检查,支持急停
- 修复SequenceMatcher局部导入导致的UnboundLocalError
2026-09-01 22:06:22 +08:00
youpaishidifu eccc1a4247 fix: 修复评分加分逻辑问题,确保补分到5真正达到至少5分 (Task #1660) 2026-09-01 11:41:44 +08:00
youpaishidifu b23b243695 fix: 修复OCR时间戳过滤失效问题,过去日期+问号放行,纯历史消息丢弃 (Task #1659) 2026-09-01 10:32:52 +08:00
youpaishidifu 1f8be2b569 fix: 全面防御性编程确保所有数据库表存在,解决多个no such table错误 (Task #1658) 2026-09-01 09:41:03 +08:00
youpaishidifu 9726945b25 fix: 防御性编程确保keyword_scores表存在,解决no such table错误 (Task #1657) 2026-08-31 23:39:38 +08:00
youpaishidifu 589ea7ef4e fix: 防御性编程确保数据库表存在,解决user_messages表不存在错误
- 添加_ensure_user_messages_table()方法:检查并创建user_messages表
- 添加_ensure_bot_messages_table()方法:检查并创建bot_messages表
- 添加_ensure_ocr_staging_table()方法:检查并创建ocr_staging表
- 在record_user_message、record_bot_reply、record_ocr_message、clear_ocr_staging方法开始处调用相应的防御性检查
- 解决0字节msg_history.db文件导致的'no such table: user_messages'错误

Task #1655
2026-08-31 22:28:14 +08:00
youpaishidifu ba6f3a3afb fix: 修复OCR消息被误判为bot回复碎片的问题 (Task #1654)
问题:'关于我们'、'服务器基本信息'等短查询被误判为bot回复碎片而丢弃
根因:bot回复碎片检测逻辑过于宽松,字符重叠率≥50%且cjk≥2就判定为碎片
修复:
1. 添加问句豁免:包含疑问词或以问号结尾的消息跳过碎片检测
2. 添加前缀豁免:短消息(<10字符)如果是已回复文本的前缀,视为用户查询
3. 调整策略1阈值:最长公共子串占比≥70%且≥5字符(原≥60%且≥3字符)
4. 调整策略2阈值:字符重叠率≥60%且cjk≥3(原≥50%且cjk≥2)
5. 策略3要求文本长度≥5(防止短消息误判)
2026-08-31 21:24:21 +08:00
youpaishidifu 5e81a79ec1 fix: 修复去重误判问题,使用exclude_self=True避免自我比较 (Task #1654)
问题:record_user_message调用_is_similar_to_history时使用exclude_self=False
导致自我比较产生100%相似度,误丢弃正常消息(如'服务器基本信息')

修复:
1. 使用exclude_self=True避免自我比较,只与历史消息比对
2. 添加防止重复入库的检查(插入前检查是否已存在完全相同的消息)
3. 测试验证:'服务器基本信息' vs '服务器I' → 20% < 50% → 通过检查
2026-08-31 18:31:50 +08:00
youpaishidifu 4f61ee3aac fix: 修复OCR捕捉含年月日消息导致后续消息丢失的问题 (Task #1652/#1653)
问题:当上面一条消息有年月日时,下面的消息会丢失目标定位,需通过表情包/图片才能重新加入消息队列
根因:_ocr_text_has_fresh_timestamp对整个文本块检查,任何部分含历史日期都会导致整段文本被丢弃
修复:
1. 新增_strip_historical_date_lines辅助方法,按行分割文本并智能剥离历史日期行
2. 修改_process_ocr_output中的时间戳新鲜性检查逻辑
3. 当检测到历史日期时,先尝试剥离旧消息行,保留新鲜消息继续处理
4. 仅含日期无时间的表格日期:剥离日期但保留行内容
5. 含日期+时间的历史消息行:完全剥离
6. 无日期的行:完整保留
2026-08-31 11:57:51 +08:00
youpaishidifu 5b9b0ff7ac 修复两个问题:
Task #1651:
1. OCR终止无响应修复
   - 在_dual_engine的join循环中添加_stop_event检查
   - 在ocr_read_qq和ocr_read_wechat的关键time.sleep前添加急停检查
   - 确保急停时能立即退出OCR流程

2. 年月日消息过滤优化
   - 修改ocr_text_has_fresh_timestamp方法
   - 当所有日期都没有时间时,判定为表格日期,剥离后继续处理
   - 当混合情况(部分有时间,部分无时间)时,剥离无时间的表格日期
   - 只有年月日+时分的消息才会被丢弃
   - 仅有年月日的表格消息会剥离后继续处理

测试验证:
- 急停响应时间:0.101秒(< 0.5秒)
- 年月日消息过滤:5个测试用例全部通过
2026-08-31 10:09:22 +08:00
youpaishidifu 63f8c749c1 修复两个问题:
Task #1647: 陈旧消息过滤策略重构
- 超过1小时的消息返回-10.0分(扣10分)
- 消息分数≤0时丢弃该消息
- 验证并提交

Task #1648: 异步非阻塞OCR处理
- 添加后台OCR状态变量和线程管理
- 实现_start_ocr_bg方法启动后台OCR
- 实现_check_ocr_bg_result非阻塞检查结果
- 修改_poll方法使用异步OCR避免GUI阻塞
- 添加超时处理和急停清理
- 所有测试通过
2026-08-31 00:10:24 +08:00
youpaishidifu 99abaa92bb fix: 修复病句漏过与陈旧时间戳放行(Task #1645/#1646)
- #1645: 候选处理循环补全病句/噪声二次拦截(_is_noise_text)。
  段级预分割在全噪声时回退返回原文本,导致"话又说回来。"这类
  无动作无主语破碎句漏到下游进KB搜索,现每条候选再跑一次兜底。
- #1646: 时间戳新鲜度逻辑增加硬性拒绝。freshness_score==1.0 表示
  含时间戳且距今>1小时(如22:32放行21:29的1h3m旧戳),视为OCR继承
  的陈旧时间戳,拒绝处理;无时间戳(freshness==0)仍按旧逻辑补分。
2026-08-30 23:05:17 +08:00
youpaishidifu 59ae875acc fix: 优化同轮语义去重——降低关键词重叠阈值至25%+动作词检测
- 骨架完全相同 → 跳过
- SequenceMatcher相似度>=70% → 跳过
- 关键词重叠>=25% 或 含核心动作词且重叠>=3 → 跳过

修复场景:"我想知道那个怎么撤销导入的兑换码" vs "那啥怎么去撤销那个导入过的激活码"
两消息共享动作词(撤销/导入)和4个关键词,判定为重复
2026-08-30 22:12:01 +08:00
youpaishidifu 4f378ee5b8 fix: 修复OCR变体误判和同轮重复回复问题
1. 添加OCR字符规范化:逍→道、甬→用、兕→兑等常见OCR错误
2. 添加同轮语义去重:骨架匹配+Jaccard相似度>=85%则跳过
3. 修复重复return语句
2026-08-30 21:56:23 +08:00
youpaishidifu 0e3ea2abc7 fix: 修复重复查重导致消息被误跳过(Task #1642 follow-up) 2026-08-30 19:07:58 +08:00
youpaishidifu bbc00f2c8b fix: 修复消息拼接/丢弃问题——同轮择优改为逐条处理所有候选消息 (Task #1642)
- 旧逻辑:_candidates列表按质量分排序,只选1条最好的处理,其余全部丢弃
- 新逻辑:for循环逐条处理所有候选消息,每条独立查重、入库、KB搜索和回复
- 修复用户报告:OCR一次读到4条消息后只有1条被处理,其余3条丢失
- 用户原话:不要把消息都拼接成一条,不然一个拦截剩余的全部丢了
2026-08-30 18:46:26 +08:00
youpaishidifu 3bb8c50969 fix: 修复消息去重相似度算法,改用3-gram Jaccard避免误判 (Task #1641)
- 添加 _generate_ngrams() 函数生成连续n字片段
- 修改 _is_similar_to_history() 使用3-gram Jaccard相似度
- 阈值从50%调整为30%,更准确地识别重复消息
- 解决不同问法被误判为重复的问题

测试结果:
- '如何打印玩家流水' vs '玩家流水怎么操作的': 50%→18% (正确区分)
- '如何打印玩家流水' vs '我想知道怎么打印玩家的流水记录': 75%→12% (正确区分)
2026-08-30 17:56:40 +08:00
youpaishidifu a302c7a889 fix: 修复急停后GUI开关状态不更新+EasyOCR不恢复+无法重启 (Task #1640)
gui.py:
- _on_emergency_stop: 急停后立即通知 OCR 管理器 set_monitor_active(False)
- _update_stop_ui: 用 deselect() 替代 _variable.set(False),更可靠地更新开关视觉状态
- _update_stop_ui: 添加20秒安全超时,强制重置 _stop_in_progress(防止 stop() 挂起导致永远无法重启)
- _toggle_monitor: 添加安全检查,monitor 已停止但 _stop_in_progress=True 时强制重置

monitor.py:
- _emergency_stop: 设置 _stopping=True 防止 stop() 重复执行清理(join已死线程+重复杀EasyOCR)
- _emergency_stop: 完成后重置 _stopping=False,确保后续 start() 正常执行

根因分析:
1. GUI开关不更新:CTkSwitch._variable.set(False) 在 customtkinter 中不可靠,改用 deselect()
2. 急停后无法重启:stop() 中 _release_memory() 可能挂起(torch.cuda/EmptyWorkingSet),
   导致 _stop_in_progress 永远不重置,_toggle_monitor 拒绝重启
3. EasyOCR不恢复:急停后未通知 OCR 管理器,引擎状态不一致,description:提交修改}
2026-08-30 17:04:16 +08:00
youpaishidifu d52c4ef2f5 fix: 修复消息入库后被查重跳过的问题
monitor.py:
- 修改 _is_similar_to_history 函数:添加 exclude_self 参数
- exclude_self=True 时排除自身刚入库的记录,防止'入库→查重→跳过'死循环
- 修改 _poll 中的调用:使用 exclude_self=True 排除自身
- record_user_message 中的调用保持 exclude_self=False(默认值)

问题分析:
消息在 _process_ocr_output 中被入库(record_user_message),
然后在 _poll 中被查重(_is_similar_to_history),
发现与刚入库的消息相似(100%),所以被跳过。

解决方案:
在 _poll 中使用 exclude_self=True,
排除自身刚入库的记录,防止死循环。
2026-08-30 16:32:35 +08:00
youpaishidifu 778d269e50 fix: 修复消息去重失效问题:添加数据库查重逻辑 (Task #1639)\n\nmonitor.py:\n- 添加 _clean_text_for_dedup 函数:清理文本只保留中文字符\n- 添加 _is_similar_to_history 函数:检查消息是否与历史消息相似\n- 修改 record_user_message 函数:入库前进行数据库查重,清理后计算相似度,重复率≥50%就跳过\n- 在轮询逻辑中添加数据库查重:在候选消息构建时检查,与历史消息相似则跳过\n- 修复用户报告的问题:1条消息产生4条记录,去重失效 2026-08-30 15:38:32 +08:00
youpaishidifu 0552df5287 fix: 修复停止按钮死循环+EasyOCR预热误触发+历史消息时间戳过滤错误 (Task #1638)
gui.py:
- 添加 _stop_in_progress 标志防止停止/启动死循环
- _toggle_monitor 检查 _stop_in_progress 标志防止重入
- _update_stop_ui 和 _stop_monitor_async 中正确设置和重置标志

monitor.py:
- 添加 _easyocr_warmup_generation 代际计数器防止死循环中旧预热线程错误初始化 EasyOCR
- 预热线程检查代际匹配防止跨 start/stop 周期的旧线程执行
- 移除 has_past 分支中的 skip_future_check=True,修复历史消息误判为新鲜的bug
  根因:skip_future_check 让未来时戳(如14:09看到21:15)通过检查,
  但OCR只能看到已发送消息,未来时戳必然来自过去日期
2026-08-30 14:44:05 +08:00
youpaishidifu 52013d28c1 修复停止按钮死循环和消息落库问题 2026-08-30 14:03:53 +08:00
youpaishidifu 96f07353ba feat: monitor→GUI日志回调,EasyOCR子进程初始化状态可在GUI日志中查看
- MessageMonitor 新增 _log_callback / set_log_callback / _gui_log
- _delayed_easyocr_start 启动时输出「🔧 EasyOCR 子进程初始化中...」
- _handshake_easyocr_subprocess 成功/超时/失败时输出对应状态
- _start_easyocr_proc_locked 启动失败时输出错误
- start() 中 _HAS_EASYOCR=False 或 broken 时输出警告
- gui.py 在 _log_queue 创建后调用 monitor.set_log_callback(self._log)
2026-08-30 12:26:59 +08:00
youpaishidifu d2a4b4c0ea fix(msgbot): 修复内存未释放——延迟easyocr/torch导入+修正SetProcessWorkingSetSize参数+添加_heapmin(Task #1625) 2026-08-29 23:35:31 +08:00
youpaishidifu d3bb961c90 fix(msgbot): 修复OCR时间戳过滤器误丢含问号的新查询——旧消息时间戳拖累新消息丢弃(Task #1624) 2026-08-29 23:14:54 +08:00
youpaishidifu 781a578412 fix(msgbot): 修复OCR空列表IndexError并增强stop内存释放至最低占用
Task #1622: 行合并循环在 merged_lines 为空时无条件访问 merged_lines[-1]
抛 IndexError,被最外层 except 记为 [qq] OCR失败: list index out of range。
增加 `if merged_lines else False` 守卫,首行非@结尾/不含问号/非bot回复时
不再越界。

Task #1623: 原 _release_memory 仅 SetProcessWorkingSetSize(-1,-1) 不逼出常驻
页,且未释放 winrt Windows OCR 引擎、未清 GPU 缓存,导致 bot 运行后暂停
内存仍高达~600MB。增强为 EmptyWorkingSet 强制归还物理内存 +
torch.cuda.empty_cache/synchronize + 释放 self._ocr_engine 引用,与 GUI 侧
_force_system_memory_cleanup 范式一致,使运行后暂停与刚启动待机内存一致。
2026-08-29 21:55:59 +08:00
youpaishidifu 6b30101806 fix(msgbot): 强化OCR逗号断行合并——前一行以逗号结尾时忽略下一行短句/问号特征强制合并
- EasyOCR常在中文逗号处拆行,导致"兑换码插件导入错误,怎么处置?"被分成两段
- 修复1:前一行以逗号结尾时,即使下一行含问号,也合并(逗号是停顿,不是消息边界)
- 修复2:前一行以逗号结尾时,忽略下一行短句/名字特征强制合并
- 原因:逗号是用户日常发言的停顿或语句分割,不应作为消息边界
EOF
)
2026-08-29 21:26:20 +08:00
youpaishidifu 4a7544c989 fix(msgbot): bot表格日期剥离——只有年月日无时间→表格内容不用于丢弃判断
- 检测每个日期后是否紧跟时间(年月日+时:分 → 真消息;只有年月日 → bot表格)
- 若所有日期均无时间→判定为bot表格日期→剥离后继续处理,不触发历史消息丢弃
- 场景:用户问"近期公告"→bot回复表格含"2026年8月3日"→OCR读到日期→原逻辑整条丢弃→用户新消息丢失
- 修复后:表格日期被剥离,用户消息正常进入下游处理
2026-08-29 18:24:51 +08:00
youpaishidifu c55c382358 fix(msgbot): re.search()返回值缺bool()包装导致|=类型错误
- 第7863行/7875行:`'@' in text and re.search(...)` 赋值为 re.Match 而非 bool
- 后续 `|= any(...)` 触发 re.Match |= bool → TypeError
- 修复:两处均加 bool() 包裹,与第7819行一致
2026-08-29 17:46:24 +08:00
youpaishidifu 19019f80d3 fix(msgbot): 描述性碎片拦截——以"拥有/提供/支持"等动词开头+无主语+无问词→碎片
- 新增 _descriptive_verbs 检查(len<=10 短文本分支内,核心名词豁免之前)
- 例:"拥有完善的领地系统"→描述性动词开头+无主语→碎片丢弃,不再触发错误 KB 回复
- "领地系统"、"登录配置"等无描述性动词前缀的合法短查询不受影响
2026-08-29 16:16:50 +08:00
youpaishidifu e0da52ead8 fix(msgbot): 修复历史消息漏放导致自言自语 + user_messages未入库
- 修复 _ocr_text_has_fresh_timestamp:无日期+时间戳全部过期(>300s) 时由误放行改为丢弃。
  原"OCR时间戳不准确"假设会让QQ窗口中12:08/12:24等历史老消息被当作新消息,触发自言自语。
- 在"无日期+新鲜时间戳"与"无日期+无时间戳中文"两条放行路径补上 record_user_message,
  修复 user_messages 表长期为空、跨轮去重失效的问题。
2026-08-29 15:09:33 +08:00
youpaishidifu c3f0fa0882 feat: 停止信号优先 + DB环形缓冲区 (Task #1617 + #1618)
Task #1617 停止信号优先机制:
- 新增 threading.Event (_stop_event) 作为主停止信号
- 新增 _interruptible_sleep() 包装 Event.wait(timeout)
- 所有关键 time.sleep() 替换为 _interruptible_sleep()
- _poll 检查点同时检测 _stop_event.is_set() 和 _running
- stop()/_emergency_stop() 先 set() 唤醒阻塞线程
- start() 清除残留 stop_event

Task #1618 DB落库修复 + 环形缓冲区:
- user_messages/bot_messages 每平台最多10条 FIFO
- 物理重启时不清空这两张表(仅清空 ocr_staging/keyword_scores)
- 新增 SQLite 临时文件到 .gitignore

其他:
- 删除 _ocr_blue_test.py / _ocr_crop_test.py 调试文件
2026-08-29 13:17:58 +08:00
youpaishidifu 96388d18f9 修复Bot自言自语拦截:不再仅依赖recent_replies,同时检查_replied_texts
根因:Bot自言自语拦截条件为recent_replies不为空,但物理重启后
DB被清空→recent_replies为空→拦截逻辑完全不执行。

修复:构建_self_check_sources列表,合并recent_replies和_replied_texts。
_replied_texts在物理重启时保留(Task #1616),确保拦截逻辑始终有效。
2026-08-29 12:20:07 +08:00
youpaishidifu f0f2c39d71 修复重启后Bot自言自语:物理重启时不清空_replied_texts去重集
根因:_force_clear_all_residual_data(clear_db=True)在物理重启时
同时清空_replied_texts和DB,导致QQ窗口中旧bot回复的OCR捕获
无法被任何查重机制拦截。

修复:_replied_texts代表QQ窗口中可能仍可见的bot历史回复,
物理重启时保留该集合,仅清空_seen_messages和其他状态。
_replied_texts在__init__阶段从DB加载后跨重启持久。
2026-08-29 10:21:08 +08:00
youpaishidifu c34ed371eb 修订时间戳新鲜度评分逻辑:≥5分直接放行,<5分查DB决定是否补分到5 2026-08-28 20:10:16 +08:00
youpaishidifu cb48663d87 Task #1611 v2: 修复过去日期分支pass导致return False的bug 2026-08-28 18:07:40 +08:00
youpaishidifu 279370271c Task #1611: 修复过去日期+未来时间戳被误丢弃
问题:OCR识别到过去日期(2026/8/25),但时间戳是今天的(17:45:35, 18:17:27),
被误判为未来时间戳丢弃,导致用户新消息丢失。

根因:过去日期分支调用_is_timestamp_old时未传skip_future_check=True,
导致时间戳比系统时间晚时被拦截。

修复:过去日期分支增加skip_future_check=True参数,
当日期识别错误但时间戳正确时,信任时间戳判断新鲜度。

场景:OCR把今天日期误读成过去日期,但时间戳正确
例:2026/8/28 → 误读成 2026/8/25,但时间戳17:45:35正确
2026-08-28 17:32:36 +08:00
youpaishidifu 9093458f9c Task #1610 修复:未来时间戳容忍偏差扩大到300s
根因:_TS_FUTURE_TOLERANCE_S=15秒太严格,OCR读到16:18:39的消息在16:18:58被处理时,
被误判为"未来时间戳"(差19s),导致消息被丢弃。

修复:将容忍偏差从15秒扩大到300秒(与max_age持平)
- 300秒以内的时间戳偏差全部视为有效(含OCR延迟/队列积压)
- 300秒以外的才判定为"未来时间"直接丢弃

效果:16:18:39的消息在16:18:58被正常识别为新鲜时间戳(19s<300s)
2026-08-28 16:54:45 +08:00
youpaishidifu 4404fb40f7 Task #1609 修复:同轮择优逻辑优先处理最新消息而非最旧消息
根因:OCR读到两条消息(17:45和18:17),质量分评估未考虑时间戳新鲜度,
导致旧消息因关键词'插件'加分更高被选中

修复:在质量分评估中加入时间戳新鲜度奖励(≤300秒+5分,≤600秒+3分,≤1800秒+1分),
并修改排序逻辑:先按质量分降序,再按时间戳差值升序(越新鲜越好)

效果:当多条消息质量分相近时,优先处理最新消息
2026-08-25 18:27:52 +08:00
youpaishidifu 2726863405 Task #1608 修复:过去日期文本中含新鲜时间戳时被误丢弃
根因:OCR一次读到的文本同时含历史内容(公告表格)和新消息
例:'2026年8月3日 | 升级服务器...' + '17:45:35 登录插件在哪儿下载'
当前逻辑有过去日期→全量丢弃,误伤新消息

修复:检查是否有新鲜时间戳(≤300s),有则放行(新消息特征),无则丢弃(纯历史消息)

触发场景:用户在新消息中@bot时,OCR同时读到了上一条bot回复的历史公告表格
2026-08-25 17:55:03 +08:00
youpaishidifu c78c5a1636 Task #1607 修复:纯下载意图匹配错误 + OCR错误年份降级
1. auto_reply.py: '哪儿下载?'等无核心词查询不应直接放行,
   改为全文回退检查(beibao.md全文不含'登录'等插件词→拒绝)
   修复 '在哪儿下载?' 误答背包插件问题

2. monitor.py: OCR错误年份(12026年)时增加本地时间戳辅助判断,
   时间戳新鲜(≤300s)则放行,否则丢弃
   修复历史消息中带今天时间戳时因OCR年份错误被全量丢弃
2026-08-25 17:41:32 +08:00
youpaishidifu eac9ece77f Task #1606 修复:OCR识别错误日期(如12026年8月38日)导致查重失效
Bug: EasyOCR把2026年8月3日识别成12026年8月38日→年份12026超范围被跳过→dates=[]→
过滤器1放行给下游→基线轮次选中近期公告触发二次回复,无查重日志。

Fix:
1. 年份解析前增加1900~2100范围检查,异常年份直接跳过不加入dates
2. 新增_ocr_fakedate_detected标志:无有效日期但检测到OCR年份异常(如12026)→丢弃
   防止历史消息特征被漏过无日期放行路径
3. 防御场景:未来日期(如2030年)、过去日期OCR噪声(年份畸形的历史记录)
2026-08-25 16:40:20 +08:00
youpaishidifu 12f269acaf 修复下载类查询匹配错误:相关性检查阶段应用同义词映射(Task #1604) 2026-08-25 15:44:48 +08:00
youpaishidifu 35171d193b 修复OCR噪声过滤器误丢合法简短查询(Task #1603) 2026-08-25 11:55:28 +08:00
youpaishidifu ce6ff1a830 fix(Task#1602): 过去日期时间戳放行bug导致md表格残留漏网
- _ocr_text_has_fresh_timestamp 中 has_past=True 时不应放行
- 根因:OCR抓取历史md表格(含旧时间戳如10:20:26),'新鲜时间戳'检查误放行
- 修复:有过去日期→直接丢弃(与has_today逻辑一致),不检查时间戳
- 前置修复:Task#1601 CUDA子进程探针(gui.py _probe_cuda_safety)
- commit eef3e08 已推 git.ypshidifu.cn
2026-08-25 10:42:15 +08:00
youpaishidifu eef3e08f8f fix(Task#1601): gui.py CUDA子进程安全探针,防止access violation崩溃
- 新增_probe_cuda_safety()静态方法:子进程做CUDA显存分配(torch.zeros(1,device='cuda'))
- 子进程崩溃(returncode=0xC0000005 ACCESS_VIOLATION)只杀子进程,主进程存活
- _check_memory_for_gpu()内存检查通过后调用探针,探针失败→降级CPU模式
- 验证:本机GTX1650+torch2.5.1+cu121探针returncode=3221225477,探针正确拦截
- monitor.py已有子进程隔离(_ensure_easyocr_subprocess),无需修改
2026-08-25 10:12:41 +08:00
youpaishidifu bdb4e5c168 fix(Task#1600): _is_noise_text新增Markdown表格管道残留检测
QQ渲染的md表格(|日期|内容|...)被OCR抓取后,管道符结构未被is_noise_text识别,
导致表格碎片通过预分割管道进入KB搜索触发误回复。

修复:在过滤器2中新增管道残留检测:
- 模式A: 以|开头 + 2+管道符 → 整行表格片段
- 模式B: 3+管道符 + 含CJK → 截断表格片段
- 豁免: 含疑问词(?) → 可能是用户讨论表格语法
2026-08-24 22:54:59 +08:00
youpaishidifu 5952b8672c 修复_is_noise_text中|运算符类型错误
re.search返回re.Match|None与bool的|=报unsupported operand type(s),
三处_has_user_msg_feature赋值处re.search外加bool()包装。
2026-08-24 22:32:20 +08:00
youpaishidifu 08ddc5a89a 修复预分割配置碎片漏网导致用户消息被丢弃
新增_is_config_fragment检测bot配置面板碎片(≥2配置键或空值截断标签),
在_split_and_denoise_segments逐段循环接入拦截,并对合并结果做二次净化逐行
恢复用户消息,解决单key碎片合并后凑够阈值被整体判噪声丢弃的问题(如"近期公告")。
2026-08-24 22:16:36 +08:00
youpaishidifu 1b36d92909 fix: Task #1595 修复UI时间戳误检导致消息误丢弃
问题:OCR抓取配置面板+用户消息+UI时间戳时,_is_noise_text因检测到多条key:value而丢弃整段文本,包括其中的用户消息

修复:在噪声检测中添加用户消息特征豁免
- 包含@提及(如@利)→ 不丢弃
- 包含疑问词(吗呢多少怎么如何哪什么几)→ 不丢弃
- 包含明确查询意图(查/问/看+插件/功能/命令等)→ 不丢弃

应用场景:
- 配置面板显示+用户提问混排
- UI时间戳被OCR抓取粘连到文本末尾
- 避免误杀真实用户消息
2026-08-24 18:03:09 +08:00
youpaishidifu ab598087ad Task #1592: 粗暴检测配置文件格式并丢弃
- 在_is_noise_text方法开头实现配置文件格式检测
- 支持JSON格式、key:value对、等号分隔键值对、YAML/INI格式
- 无问号/疑问词时直接丢弃,不进入后续KB搜索
- 移除Task #1591在len<=10分支内的重复检测逻辑
2026-08-24 17:29:04 +08:00
youpaishidifu 5e1ece6076 扩展配置文件格式检测,支持多条key:value拼接格式(如'图标: potato 标题:自杀'),忽略大小写/标点差异 2026-08-24 16:40:56 +08:00
youpaishidifu 3c118d3665 fix: 手动停止卡死+配置文件内容误触发自动回复
问题1(Task #1590):手动停止导致GUI卡死
- 根因:gui.py line 791 self.monitor.stop()在GUI主线程执行,线程join卡住时GUI冻结
- 修复:改为后台线程执行(复用_stop_monitor_async)

问题2(Task #1591):配置文件内容"图标: shield"误触发自动回复
- 根因:_core_nouns含"图标"→残片过滤器放行→KB搜索命中sdf1_login→触发回复
- 修复:在_is_noise_text中增加配置文件格式检测(key: value格式,无问号/疑问词时拦截)

验证:正则^[\u4e00-\u9fff]{2,10}\s*[::]\s*\S+$正确匹配配置文件格式,
正常查询(如"图标怎么设置")不会被误拦。

Closes #1590 #1591
2026-08-24 16:26:29 +08:00
youpaishidifu 06d58ee1c1 fix: 基线消息不再写入跨轮去重记录,消除自我阻塞
根因:基线处理调用_add_to_recent_user_queries(item)将消息写入跨轮去重记录,
导致后续每轮OCR检测到相同消息时被自身匹配(100% Jaccard相似度)跳过。

修复:
- 移除基线处理中的_add_to_recent_user_queries调用(line 9321)
- if ts in seen: continue 处增加debug日志便于排查静默跳过

验证:剩余_add_to_recent_user_queries调用仅在消息被实际回复后触发,
不影响Task #1581双回复防护。

Closes #1589
2026-08-24 15:36:06 +08:00
youpaishidifu f1fa31b3bb OCR残片过滤器放行核心名词查询:防止'近期公告'等被误丢 2026-08-24 14:39:48 +08:00
youpaishidifu a32400223a OCR时间戳拼接预处理:拆分日期+时间粘连,防止污染 2026-08-24 14:21:18 +08:00
youpaishidifu f74e59845e 修复OCR时间戳拼接污染:过去日期+新鲜时间戳放行给DB查重 2026-08-24 13:48:09 +08:00
youpaishidifu b83556f37f 修复OCR时间戳丢弃策略:无年月日消息放行给DB查重
根因:QQ当天消息不显示日期,历史消息才显示"年/月/日 时:分"。
原逻辑对无时间戳消息放行,但对有时间戳无日期的消息过期就丢弃,
导致当天消息"12:36:05"被错误丢弃。

修复:_ocr_text_has_fresh_timestamp方法重写日期检查逻辑:
1. 有清晰年月日(四位年+月+日)→ 丢弃历史消息
2. 有不清晰年月日 → 用本地时间辅助判断时间戳是否过期
3. 无年月日 → 放行给下游DB查重(当天消息不带日期)

调用方简化:_ocr_text_has_fresh_timestamp返回False时直接丢弃。
2026-08-24 12:59:42 +08:00