168 lines
9.4 KiB
Python
168 lines
9.4 KiB
Python
"""Debug trace for verification 4 sequence"""
|
||
import sys
|
||
sys.path.insert(0, '/root/.openclaw/workspace/context-gatekeeper')
|
||
|
||
# Inline the make_pairs from test_100rounds_v2
|
||
redis_topics = [
|
||
("Redis 分布式锁和 RedLock 算法有什么区别?", "RedLock..."),
|
||
("Redis 集群环境下怎么做分布式锁?", "用 RedLock..."),
|
||
("Redis 惰性删除和定期删除有什么区别?", "惰性删除..."),
|
||
("Redis 的过期 key 对 RDB 快照有什么影响?", "过期key..."),
|
||
("Redis 主从复制断线后如何增量同步?", "PSYNC..."),
|
||
("Redis 的 Lua 脚本有什么应用场景?", "Lua脚本..."),
|
||
("Redis GeoHash 在附近的人功能里怎么用的?", "GeoHash..."),
|
||
("Redis 的大 key 问题怎么排查和处理?", "bigkey..."),
|
||
("缓存穿透、击穿、雪崩分别是什么?", "穿透..."),
|
||
("Redis Cluster 的槽迁移过程是怎样的?", "槽迁移..."),
|
||
("Redis 和 Memcached 的核心区别是什么?", "Memcached..."),
|
||
("Redis LRU 缓存淘汰策略怎么配置的?", "LRU..."),
|
||
("Redis Pipeline 和事务的区别是什么?", "Pipeline..."),
|
||
("Redis 慢查询日志怎么分析?", "SLOWLOG..."),
|
||
("Redis 的发布订阅有什么缺点?", "pubsub..."),
|
||
("Redis Cluster 为什么用 16384 个槽?", "16384..."),
|
||
("Redis 哨兵模式下主节点故障切换流程是什么?", "哨兵..."),
|
||
("Redis ZSet 的实现为什么用跳表而不是 B+树?", "跳表..."),
|
||
("Redis 内存碎片怎么产生的,怎么处理?", "碎片..."),
|
||
("Redis 数据类型和应用场景怎么对应?", "数据类型..."),
|
||
("Redis 加锁后服务挂了导致锁无法释放怎么办?", "锁释放..."),
|
||
("Redis 如何实现延迟队列?", "延迟队列..."),
|
||
("Redis 客户端分片怎么做,有什么优缺点?", "客户端分片..."),
|
||
("Redis Cluster 的最大限制是什么?", "最大限制..."),
|
||
("Redis 的 AOF 和 RDB 怎么配合使用?", "AOF RDB..."),
|
||
]
|
||
asyncio_topics = [
|
||
("asyncio.Task 的 cancel 方法怎么工作的?", "cancel..."),
|
||
("asyncio.gather 和 asyncio.wait 的返回结果有什么区别?", "gather..."),
|
||
("asyncio.create_task 和 ensure_future 的区别是什么?", "create_task..."),
|
||
("asyncio 的事件循环怎么启动和停止?", "事件循环..."),
|
||
("Python 异步上下文管理器的写法是什么?", "异步上下文..."),
|
||
("asyncio.sleep 和 time.sleep 的区别是什么?", "sleep..."),
|
||
("asyncio 的 Future 对象怎么获取结果?", "Future..."),
|
||
("asyncio 的 wait_for 和 shield 组合使用注意什么?", "shield..."),
|
||
("asyncio 服务怎么实现优雅关闭?", "优雅关闭..."),
|
||
("asyncio 的 run_in_executor 什么时候用?", "run_in_executor..."),
|
||
("Python 异步迭代器和异步生成器有什么区别?", "异步迭代..."),
|
||
("asyncio 怎么限制并发数?", "限制并发..."),
|
||
("asyncio 的 timeout 错误怎么捕获?", "timeout..."),
|
||
("Python 协程和普通函数的区别是什么?", "协程..."),
|
||
("asyncio 事件循环可以嵌套吗?", "嵌套..."),
|
||
("asyncio 异常怎么处理?", "异常处理..."),
|
||
("Python 异步 HTTP 请求用什么库?", "异步HTTP..."),
|
||
("asyncio 里有条件变量吗?", "条件变量..."),
|
||
("asyncio 如何实现心跳/keepalive?", "心跳..."),
|
||
("asyncio 的 callback 怎么转换为协程?", "callback..."),
|
||
("asyncio 的 wait 和 as_completed 有什么区别?", "as_completed..."),
|
||
("Python 异步编程里怎么避免回调地狱?", "回调地狱..."),
|
||
("asyncio 事件循环是怎么工作的?", "事件循环..."),
|
||
("asyncio.Task 和 concurrent.futures.Future 有什么关系?", "concurrent..."),
|
||
("asyncio 怎么检测任务是否完成?", "检测完成..."),
|
||
]
|
||
pg_topics = [
|
||
("PostgreSQL 的 MVCC 机制是怎么保证读不阻塞写的?", "MVCC..."),
|
||
("PostgreSQL 的 VACUUM 为什么要定期运行?", "VACUUM..."),
|
||
("PostgreSQL 的 EXPLAIN ANALYZE 怎么看执行计划?", "EXPLAIN..."),
|
||
("PostgreSQL B-tree 索引和 Hash 索引的区别是什么?", "B-tree..."),
|
||
("PostgreSQL 的 TOAST 机制是什么?", "TOAST..."),
|
||
("PostgreSQL 的 JSONB 和 JSON 类型的区别是什么?", "JSONB..."),
|
||
("PostgreSQL 的 CTE 和子查询的性能差异是什么?", "CTE..."),
|
||
("PostgreSQL 的数组类型怎么建索引?", "数组索引..."),
|
||
("PostgreSQL 的触发器能用于什么场景?", "触发器..."),
|
||
("PostgreSQL 的窗口函数和聚合函数的区别是什么?", "窗口函数..."),
|
||
("PostgreSQL 的逻辑复制和物理复制的适用场景是什么?", "逻辑复制..."),
|
||
("PostgreSQL 的行安全策略 RLS 怎么配置?", "RLS..."),
|
||
("PostgreSQL 的 COPY 和 INSERT 性能差多少?", "COPY..."),
|
||
("PostgreSQL 的 pg_stat_statements 怎么用于慢查询分析?", "pg_stat..."),
|
||
("PostgreSQL 的物化视图和普通视图的区别是什么?", "物化视图..."),
|
||
("PostgreSQL 的 JOIN 类型有哪些?", "JOIN..."),
|
||
("PostgreSQL 的索引失效有哪些情况?", "索引失效..."),
|
||
("PostgreSQL 的 NOTIFY 和 LISTEN 适合什么场景?", "NOTIFY..."),
|
||
("PostgreSQL 的查询优化器怎么选择执行计划的?", "优化器..."),
|
||
("PostgreSQL 的 WAL 段文件是什么?", "WAL..."),
|
||
("PostgreSQL 的 SERIAL 和 IDENTITY 的区别是什么?", "SERIAL..."),
|
||
("PostgreSQL 的全文搜索怎么配置中文分词?", "全文搜索..."),
|
||
("PostgreSQL 的分区表怎么提升查询性能?", "分区表..."),
|
||
("PostgreSQL 的连接池用什么方案?", "连接池..."),
|
||
("PostgreSQL 的 EXPLAIN 输出里 Seq Scan 是什么含义?", "Seq Scan..."),
|
||
]
|
||
git_topics = [
|
||
("Git 的 rebase 和 merge 的区别是什么?", "rebase..."),
|
||
("Git reset 的 --soft、--mixed、--hard 有什么区别?", "reset..."),
|
||
("Git stash 暂存区和工作目录的区别是什么?", "stash..."),
|
||
("Git cherry-pick 怎么把特定提交应用到当前分支?", "cherry-pick..."),
|
||
("Git 的 hook 怎么配置自动化任务?", "hook..."),
|
||
("Git 的 bisect 怎么用来快速定位 bug?", "bisect..."),
|
||
("Git 的 worktree 和 submodule 的区别是什么?", "worktree..."),
|
||
("Git 的 reflog 怎么用来恢复误删的提交?", "reflog..."),
|
||
("Git 的 sparse-checkout 怎么只检出部分目录?", "sparse-checkout..."),
|
||
("Git 的 bundle 命令在什么场景下用?", "bundle..."),
|
||
("Git 的 Interactive Rebase 怎么用?", "Interactive..."),
|
||
("Git 的 clean 命令怎么删除未跟踪文件?", "clean..."),
|
||
("Git 的 describe 命令输出版本号格式是什么?", "describe..."),
|
||
("Git 的 log 怎么配合 grep 过滤提交?", "log grep..."),
|
||
("Git 的 blame 显示每行最后修改者和时间怎么用的?", "blame..."),
|
||
("Git 的 fetch 和 pull 的区别是什么?", "fetch..."),
|
||
("Git 的 merge 冲突怎么规范解决?", "merge冲突..."),
|
||
("Git 的 revert 和 reset 的应用场景有什么区别?", "revert..."),
|
||
("Git 的 alias 怎么配置常用命令缩写?", "alias..."),
|
||
("Git 的 hook 能做什么自动化的事?", "hook自动化..."),
|
||
("Git 的 rev-parse 怎么获取仓库信息?", "rev-parse..."),
|
||
("Git 的 tag 和 branch 有什么区别?", "tag..."),
|
||
("Git 的 remote 怎么管理和使用多个远程仓库?", "remote..."),
|
||
("Git 的 grep 怎么在版本历史里搜索代码?", "grep..."),
|
||
("Git 的 show 和 log 的区别是什么?", "show..."),
|
||
]
|
||
|
||
from src.gatekeeper import ContextGatekeeper
|
||
|
||
gate = ContextGatekeeper(token_budget=4000)
|
||
for i in range(25):
|
||
gate.add_turn(redis_topics[i][0], redis_topics[i][1])
|
||
gate.add_turn(asyncio_topics[i][0], asyncio_topics[i][1])
|
||
gate.add_turn(pg_topics[i][0], pg_topics[i][1])
|
||
gate.add_turn(git_topics[i][0], git_topics[i][1])
|
||
|
||
print(f"After 100 rounds: active_topic={gate._active_topic[0][:3]}")
|
||
print()
|
||
|
||
# Simulate verification 4 sequence
|
||
tests = [
|
||
("第50轮问PG", "PostgreSQL 的 EXPLAIN ANALYZE 怎么看执行计划?"),
|
||
("第52轮问Git", "Git 的 rebase 和 merge 有什么区别?"),
|
||
("第60轮问Redis", "Redis 惰性删除和定期删除有什么区别?"),
|
||
]
|
||
|
||
for label, q in tests:
|
||
active_before = gate._active_topic[0][:3]
|
||
q_anchors, _ = gate.anchor_extractor.extract_with_deictic(q)
|
||
idf = gate.anchor_extractor._idf_cache
|
||
switched = gate.topic_gate.is_topic_switch(q, gate._active_topic)
|
||
high = {a for a in q_anchors if idf.get(a, 1) > 2}
|
||
|
||
# Count passing blocks in recent 15
|
||
recent = gate.blocks[-15:]
|
||
passing_turns = []
|
||
for b in recent:
|
||
fp = {a.lower() for a in b.topic_fingerprint}
|
||
if fp & high:
|
||
tp = {1:'T1',2:'T2',3:'T3',0:'T4'}[b.turn_id % 4]
|
||
passing_turns.append(f't{b.turn_id}({tp})')
|
||
|
||
sel = gate.select(q)
|
||
turns = [item['turn_id'] for item in sel]
|
||
tp_map = {1:'T1',2:'T2',3:'T3',0:'T4'}
|
||
t1=[i for i in turns if i%4==1]
|
||
t2=[i for i in turns if i%4==2]
|
||
t3=[i for i in turns if i%4==3]
|
||
t4=[i for i in turns if i%4==0]
|
||
|
||
active_after = gate._active_topic[0][:3]
|
||
|
||
print(f"--- {label}: {q[:30]}...")
|
||
print(f" before: active={active_before}")
|
||
print(f" switched={switched}, high={list(high)[:3]}...")
|
||
print(f" recent passing: {passing_turns[:5]}")
|
||
print(f" recalled: {turns}")
|
||
print(f" T1={t1} T2={t2} T3={t3} T4={t4}")
|
||
print(f" after: active={active_after}")
|
||
print()
|