""" Step 04 练习题:Memory 实战 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🎯 练习目标: 1. 理解三层记忆的协作方式 2. 实现一个 Token 估算器 3. 体验摘要压缩的副作用 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ """ # ═══════════════════════════════════════════════════════════════════════════════ # 练习 1:Token 估算 # ═══════════════════════════════════════════════════════════════════════════════ """ 任务: 在 ShortTermMemory 上加一个 estimate_tokens() 方法,粗略估计当前占用的 token 数。 要求: 1. 简单规则:1 个中文字符 ≈ 1.5 token,1 个英文单词 ≈ 1.3 token 2. 对所有消息求和 3. 返回 int(向上取整) 提示: - 正则分中英文:re.findall(r'[\u4e00-\u9fff]', text) 取汉字,剩下按空格分词 - import math; math.ceil(...) """ # ═══════════════════════════════════════════════════════════════════════════════ # 练习 2:基于 Token 阈值的自动压缩 # ═══════════════════════════════════════════════════════════════════════════════ """ 任务: 给 ShortTermMemory 加一个 maybe_compress(max_tokens: int) 方法: 当 estimate_tokens() 超过 max_tokens 时,把较早的对话压缩成一行摘要, 保留最近的 5 条。 要求: 1. 触发时调用 summarize_older(keep_recent=5) 2. 把摘要作为一个新的 Message(role="system", content=summary) 放回 messages 头部 3. 删除被摘要覆盖的旧消息(避免 token 没降反升) """ # ═══════════════════════════════════════════════════════════════════════════════ # 练习 3:把 MemorySystem 接到 SimpleAgent # ═══════════════════════════════════════════════════════════════════════════════ """ 任务: 让 SimpleAgent 在 process() 时把每一轮对话写入 MemorySystem, 并在下次决策前把 memory.get_context() 注入到 state['context'] 中。 要求: 1. SimpleAgent.__init__ 里 new 一个 MemorySystem 2. process() 末尾:self.memory.add_message('user' / 'assistant', ...) 3. process() 开头:self.state['context'] = self.memory.get_context() 提示: - 直接修改 step_03/concept.py 是允许的(学习项目不是发布包) - 可以通过 Monkey-patching 避免破坏 step_03 原有行为 """ def test_exercises(): from step_04_memory.concept import MemorySystem mem = MemorySystem() mem.add_message("user", "帮我生成销售月报") mem.add_message("assistant", "好的,请告诉我字段") print("上下文片段:") print(mem.get_context()[:200]) if __name__ == "__main__": test_exercises()