-
Notifications
You must be signed in to change notification settings - Fork 229
Expand file tree
/
Copy pathtest_reme_light.py
More file actions
196 lines (164 loc) · 8.29 KB
/
test_reme_light.py
File metadata and controls
196 lines (164 loc) · 8.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
"""测试 ReMeLight
演示 ReMeLight 的完整功能,并使用 AsMsgHandler 跟踪每步 Token 变化:
1. compact_tool_result - 压缩超长工具输出
2. compact_memory - 生成压缩摘要
3. summary_memory - 生成完整摘要并写入文件
4. pre_reasoning_hook - 推理前预处理钩子
5. memory_search - 语义搜索记忆
6. ReMeInMemoryMemory.estimate_tokens - 估算 Token 使用
7. ReMeInMemoryMemory.get_history_str - 获取格式化历史记录
"""
import asyncio
import logging
from test_utils import build_sample_messages, get_msg_handler
from reme.reme_light import ReMeLight
def print_token_change(_step_name: str, before: int, after: int):
"""打印 Token 变化统计。"""
change = after - before
change_pct = (change / before * 100) if before > 0 else 0
print(f" 📊 Token 统计: {before:,} → {after:,} (变化: {change:+,}, {change_pct:+.1f}%)")
# ==================== 主测试流程 ====================
async def main():
"""测试 ReMeLight 的完整功能,并跟踪每步 Token 变化。"""
# 初始化 AsMsgHandler 用于 Token 统计
msg_handler = get_msg_handler()
# 初始化 ReMeLight
reme = ReMeLight(
default_as_llm_config={"model_name": "qwen3.5-35b-a3b"},
# default_embedding_model_config={"model_name": "text-embedding-v4"},
default_file_store_config={"fts_enabled": True, "vector_enabled": False},
enable_load_env=True,
)
logging.getLogger("reme").setLevel(logging.WARNING)
await reme.start()
print("=" * 70)
print("ReMeLight 已启动")
print("=" * 70)
# 构建模拟对话历史(包含超长 tool_result,确保超过 128K token)
original_messages = build_sample_messages(include_large_tool_result=True)
initial_tokens = await msg_handler.count_msgs_token(original_messages)
print(f"\n[原始消息]: {len(original_messages)} 条, {initial_tokens:,} tokens")
print(f" 目标阈值: 128K = {128 * 1024:,} tokens")
print(f" 超出阈值: {initial_tokens > 128 * 1024}")
# ==================== 1. compact_tool_result ====================
print("\n" + "=" * 70)
print("[步骤 1] compact_tool_result - 压缩超长工具输出")
print("=" * 70)
# 重新获取原始消息
messages = build_sample_messages(include_large_tool_result=True)
tokens_before = await msg_handler.count_msgs_token(messages)
messages_after_step1 = await reme.compact_tool_result(messages)
tokens_after = await msg_handler.count_msgs_token(messages_after_step1)
print(f" 消息数量: {len(messages)} → {len(messages_after_step1)}")
print_token_change("compact_tool_result", tokens_before, tokens_after)
# ==================== 2. compact_memory ====================
print("\n" + "=" * 70)
print("[步骤 2] compact_memory - 生成结构化压缩摘要")
print("=" * 70)
# 重新获取原始消息
messages = build_sample_messages(include_large_tool_result=True)
tokens_before = await msg_handler.count_msgs_token(messages)
compact_summary = await reme.compact_memory(
messages=messages,
previous_summary="",
)
summary_tokens = await msg_handler.count_str_token(compact_summary)
print(f" 输入消息 tokens: {tokens_before:,}")
print(f" 压缩摘要长度: {len(compact_summary)} 字符, {summary_tokens:,} tokens")
print(f" 压缩比: {summary_tokens / tokens_before * 100:.1f}%" if tokens_before > 0 else " 压缩比: N/A")
print(f" 摘要预览: {compact_summary[:200]}..." if len(compact_summary) > 200 else f" 摘要: {compact_summary}")
# ==================== 3. summary_memory ====================
print("\n" + "=" * 70)
print("[步骤 3] summary_memory - 生成完整摘要并写入文件")
print("=" * 70)
# 重新获取原始消息
messages = build_sample_messages(include_large_tool_result=True)
tokens_before = await msg_handler.count_msgs_token(messages)
summary_result = await reme.summary_memory(messages=messages)
print(f" 输入消息 tokens: {tokens_before:,}")
print(f" 摘要结果长度: {len(summary_result)} 字符")
print(f" 摘要预览: {summary_result[:200]}..." if len(summary_result) > 200 else f" 摘要: {summary_result}")
# ==================== 4. pre_reasoning_hook ====================
print("\n" + "=" * 70)
print("[步骤 4] pre_reasoning_hook - 推理前预处理")
print("=" * 70)
# 重新获取原始消息
messages = build_sample_messages(include_large_tool_result=True)
tokens_before = await msg_handler.count_msgs_token(messages)
processed_messages, compressed_summary = await reme.pre_reasoning_hook(
messages=messages,
system_prompt="你是一个有帮助的 AI 助手。",
compressed_summary="",
max_input_length=128000,
compact_ratio=0.7,
memory_compact_reserve=10000,
enable_tool_result_compact=True,
tool_result_compact_keep_n=3,
)
tokens_after = await msg_handler.count_msgs_token(processed_messages)
compressed_summary_tokens = await msg_handler.count_str_token(compressed_summary)
print(f" 消息数量: {len(messages)} → {len(processed_messages)}")
print_token_change("pre_reasoning_hook", tokens_before, tokens_after)
print(f" 压缩摘要: {len(compressed_summary)} 字符, {compressed_summary_tokens:,} tokens")
print(f" 总上下文: {tokens_after + compressed_summary_tokens:,} tokens")
# ==================== 5. memory_search ====================
print("\n" + "=" * 70)
print("[步骤 5] memory_search - 语义搜索记忆")
print("=" * 70)
search_result = await reme.memory_search(query="Python 版本偏好", max_results=5)
if search_result.content:
print(f" 搜索结果: {search_result.content}")
else:
print(" 未找到相关记忆")
# ==================== 6 & 7. ReMeInMemoryMemory ====================
print("\n" + "=" * 70)
print("[步骤 6] ReMeInMemoryMemory - 会话内存管理")
print("=" * 70)
# 重新获取原始消息
messages = build_sample_messages(include_large_tool_result=True)
memory = reme.get_in_memory_memory()
for msg in messages:
await memory.add(msg)
print(f" 已添加 {len(messages)} 条原始消息到内存")
# 6.1 estimate_tokens
print("\n[6.1] estimate_tokens - 估算 Token 使用:")
token_stats = await memory.estimate_tokens(max_input_length=128000)
print(f" - 总消息数: {token_stats['total_messages']}")
print(f" - 消息 Token 数: {token_stats['messages_tokens']:,}")
print(f" - 压缩摘要 Token 数: {token_stats['compressed_summary_tokens']:,}")
print(f" - 预估总 Token 数: {token_stats['estimated_tokens']:,}")
print(f" - 最大输入长度: {token_stats['max_input_length']:,}")
print(f" - 上下文使用率: {token_stats['context_usage_ratio']:.2f}%")
# 6.2 get_history_str
print("\n[6.2] get_history_str - 格式化历史记录:")
history_str = await memory.get_history_str(max_input_length=128000)
print(history_str[:1000] + "..." if len(history_str) > 1000 else history_str)
# ==================== 等待后台任务完成 ====================
print("\n" + "=" * 70)
print("[步骤 7] 等待后台任务完成")
print("=" * 70)
await_result = await reme.await_summary_tasks()
print(f" 后台任务完成,结果长度: {len(await_result)} 字符")
# ==================== 总结 ====================
print("\n" + "=" * 70)
print("📊 Token 变化总结")
print("=" * 70)
print(f" 原始消息: {initial_tokens:,} tokens")
print(f" Step 1 compact_tool_result 后: {(await msg_handler.count_msgs_token(messages_after_step1)):,} tokens")
print(f" Step 2 compact_memory 摘要: {summary_tokens:,} tokens")
print(
f" Step 4 pre_reasoning_hook 后: {tokens_after:,} tokens + 摘要 {compressed_summary_tokens:,} "
f"tokens = {tokens_after + compressed_summary_tokens:,} tokens",
)
print(
f" 最大节省: {initial_tokens - tokens_after:,} "
f"tokens ({(initial_tokens - tokens_after) / initial_tokens * 100:.1f}%)",
)
print(f" 目标阈值: {128 * 1024:,} tokens")
# 关闭 ReMeLight
await reme.close()
print("\n" + "=" * 70)
print("ReMeLight 已关闭")
print("=" * 70)
if __name__ == "__main__":
asyncio.run(main())