要解决什么
一个只发送当前问题的模型脚本,既不能自动找回上轮对话,也不会因为模型说要调用计算器就真正执行函数。这个学习项目把 HTTP、数据库、工具和循环放到同一条请求链上,验证最小的“提问—执行—保存—追问”过程。
它是为后续智能体客服积累工程基础的练习,不把计算器的成功泛化为客服知识库、权限体系或企业级可靠性已经完成。
模块与数据流
- 接收请求:FastAPI 校验 conversation_id 与 message。
- 恢复上下文:memory.py 从 MySQL 按顺序读取历史,加入当前问题。
- 执行 Agent:agent.py 请求模型、查找工具、执行计算并回传结果,直到得到最终文本或达到上限。
- 保存与回应:路由仅保存当前 user 与最终 assistant,再返回 JSON。
| 模块 | 职责 |
|---|---|
| config.py / db.py | 读取配置、建立数据库连接。 |
| memory.py | 创建会话、按序读取与保存消息。 |
| tools.py | 计算器函数、工具说明与注册表。 |
| agent.py | 模型与工具的循环;本阶段不直接查询 MySQL。 |
| main.py | HTTP 请求与响应,协调 Memory 和 Agent。 |
课堂使用 Qwen 兼容接口、FastAPI 与 PyMySQL。旧环境版本只属于历史学习记录,不作为新项目安装推荐。
已有验证记录
以下为个人笔记中的实操结果转写,不是实时 Demo,也不是本次发布时重新运行的日志。
1. 计算请求得到结果
最终 Agent 版本的请求结构示例(POST /chat)
{
"conversation_id": "agent001",
"message": "请使用计算器,先计算12乘以8,再把结果除以4。"
}原截图的“计算机”在这里规范为“计算器”;请求字段保持最终整合版的 message。记录中的 HTTP 响应为 200,回答展示 96、24.0 与最终结果 24.0。
2. 终端证实工具执行后再次调用了模型
模块化成功日志显示:Step 1 中模型一次提出两个计算器调用,程序顺序执行,得到 96 与 24.0;Step 2 模型返回最终回答。第二个调用的参数在首个工具结果返回前已给出,因此这里不声称验证了通用依赖调度或工具并发。
3. 首轮数据库只新增两条可见消息
首次计算后的查询结果只有 user 与 assistant 两行,没有独立 tool 记录。助手正文中的计算步骤属于最终回答,不等于结构化 Trace。后续追问成功保存后,消息数量会继续增加。
4. 同会话追问仍能回答 24.0
同一个 agent001 再问“刚才最终算出来是多少?”,记录中的回答仍是 24.0。结合数据库记录与读取代码,说明这条应用链使用了 MySQL Chat History,而不只是依赖一句“模型说它记得”。
最值得记录的排错:一次“达到最大步数”的提示实际由 return 缩进错误引起,日志中没有 Step 2 是关键证据。详见 Agent Loop 排错笔记。
当前边界:原型跑通,不等于生产就绪
- 最终整合后的完整重启恢复过程,未在现有记录中单独展示,需要复测。
- 没有用户鉴权和会话归属校验;不能直接面向陌生用户开放。
- 一轮两条消息分别提交,未完成原子写入、幂等与并发顺序控制。
- 没有独立持久化的 Agent Trace、长期记忆提炼或完整参数校验。
- max_steps 不是超时;课堂版超限提示仍可能以普通文本返回 200。
- RAG、Streaming、复杂外部工具、Linux / Docker 部署与企业级客服尚未完成。
下一步验收清单
下面是待做事项,不是已通过的测试。先补证据,再扩展能力。
- 跨重启恢复:用新会话完成一问一答,确认数据库有记录;重启应用后追问,保留独立日志。
- 确定性失败测试:分别构造未知工具、非法参数和轮次耗尽,确认返回状态可区分,不只检查 HTTP 200。
- 保存一致性:设计同事务写入一轮消息,并测试中途失败时的恢复行为。
- 公开前的安全边界:加入用户身份、会话归属检查和超时限制,审查日志中是否包含敏感信息。
- 走向客服场景:在上述基础上明确知识来源、检索验证与人工兜底,再做最小客服原型。
资料来源
《个人Agent学习笔记_MySQL_Memory到Agent整合_第35至53课》第 17—22、25 节。资料整理于 2026-09-11,范围截至第 53 课。原笔记已区分实测结果、课堂代码与补充说明,本页延续这一边界。
试着做一个小练习
用独立测试会话记录输入、工具执行、数据库新增行与后续追问,不用 HTTP 200 单独代表任务成功。