改变存储方式,保留读写接口
内存版本用 dict.get 和 list.append;MySQL 版本用 SELECT、INSERT 与事务提交。调用方依然通过 get_messages 和 add_message 读写历史。这是我第一次在具体项目中理解“接口稳定,底层实现可替换”。
| 对象 | 记录什么 |
|---|---|
| conversations | 有哪些会话,以及会话标识。 |
| messages | 某段会话中每条消息的 role 与 content。 |
课堂实际建了这两张表,没有实现 users 表,也没有声明数据库外键。字段名相同只是逻辑关联,不能当作已建立强制约束。
让 SQL 结果成为有序上下文
查询需要同时明确取哪个会话、按什么顺序返回,再把数据库行转换成消息列表。参数应交给驱动处理,不把用户输入直接拼进 SQL。
读历史的核心片段:依赖项目已有 cursor 与会话参数
cursor.execute(
"SELECT role, content FROM messages "
"WHERE conversation_id = %s ORDER BY id ASC",
(conversation_id,),
)
rows = cursor.fetchall()
messages = [{"role": role, "content": content} for role, content in rows]单元素 tuple 末尾的逗号不可省略。驱动的参数绑定及显式提交示例见 PyMySQL 官方示例。
先拿到回答,再保存,不等于事务已完整
当前学习实现会先得到模型回答,再分别保存 user 和 assistant。这样减少了模型调用失败留下半轮记录的情况,但两次 add_message 各自提交,第二次写入失败时,第一次仍可能已经成功。
- ensure_conversation 用于确保会话存在,不负责消息去重。
- 先查后插还存在并发创建同一会话的竞争。
- 整轮原子写入、幂等和并发顺序控制都是后续工作,不标记为已完成。
已记录的结果与一个排错经验
- Python 已能连接 MySQL,读取查询结果。
- 消息能转换为 list + dict;新会话和对应消息均能在表中查到。
- 持久化 Chatbot 能保存名字相关历史,并在同会话追问中回答。
中文在终端显示异常时,我学到要区分“写入失败”“存储内容损坏”和“显示编码不匹配”。先用另一条读取路径核对同一记录,不因乱码直接删除数据。
没有补写重启验收原笔记记录了数据库读写和后续追问,但没有完整展示最终 Agent 停止、重启后的独立日志。跨重启恢复仍需要单独复测。
持久化历史,不是完整长期记忆
Chat History 是原始交流记录;Long-term Memory 还需要提炼有用信息、更新与检索。两者都可以存数据库,不能按“RAM 或 MySQL”直接区分。当前完成的是持久化聊天历史链路。
- 下一步:用新测试会话单独验证跨重启恢复,不删除旧记录。
- 补齐一轮对话的事务边界和失败状态。
- 在面向真实用户前加入身份认证与会话归属检查。
来源
本页依据个人笔记整理:《个人Agent学习笔记_MySQL_Memory到Agent整合_第35至53课》第 2—9、20—21、25 节(整理于 2026-09-11)。
试着做一个小练习
在独立测试会话中写入两条消息,读回并核对顺序;再记录一次失败写入的行为。