昨天的结构化任务 Agent 可以处理 JSON,但程序一旦退出,变量里的结果就消失了。今天要让数据写入磁盘:即使关掉程序、重新开机,也能再次读取。
这就是最简单的“长期记忆”。它还不是向量数据库,却已经具备 Agent 记忆系统最核心的动作:读取旧记录、加入新记录、保存更新后的状态。
今天完成 4 件事
1|理解文件为何能持久保存
2|掌握读写模式和编码
3|学会读取与保存 JSON 文件
4|完成本地记忆 Agent
memory = ["学习了 JSON"]
print(memory)变量保存在程序当前使用的内存中。程序结束,内存状态不会自动写入硬盘。下一次运行时,memory 会重新从代码中的初始值开始。
文件不同。只要成功写入磁盘,下次程序就能沿着路径重新找到它。因此可以先把文件理解成 Agent 的本地记事本。
with open("study_note.txt", "w", encoding="utf-8") as file:
file.write("今天学习文件读写")
with open("study_note.txt", "r", encoding="utf-8") as file:
content = file.read()
print(content)第一段以 w 模式打开文件并写入文字,第二段以 r 模式读取全部内容。
open 是内置函数;file 是我们起的变量名,可以改;write() 和 read() 是文件对象的方法;encoding="utf-8" 明确中文编码。
with 代码块结束时会自动关闭文件。初学阶段建议始终采用这种写法,避免忘记调用 close()。
with open("study_log.txt", "a", encoding="utf-8") as file:
file.write("完成第13天练习\n")每运行一次,a 都会在文件末尾追加一行。末尾的 \n 表示换行,否则多次记录会挤在同一行。
• r:只读;文件不存在时触发 FileNotFoundError;
• w:写入;文件已存在时先清空原内容;
• a:追加;保留旧内容,把新内容加到末尾。
如果要保存“当前完整状态”,w 很合适;如果要逐条写运行日志,通常选择 a。
import json
memory = [
{"topic": "JSON", "done": True},
{"topic": "文件读写", "done": False}
]
with open("memory.json", "w", encoding="utf-8") as file:
json.dump(memory, file, ensure_ascii=False, indent=2)
with open("memory.json", "r", encoding="utf-8") as file:
loaded_memory = json.load(file)
print(loaded_memory)昨天学的是 dumps() 和 loads(),名称末尾有 s,处理的是字符串。今天的 dump() 和 load() 直接配合文件对象使用。
新建 day13_memory_agent.py:
import json
from pathlib import Path
MEMORY_FILE = Path("study_memory.json")
def load_memory():
if not MEMORY_FILE.exists():
return []
try:
with MEMORY_FILE.open("r", encoding="utf-8") as file:
return json.load(file)
except json.JSONDecodeError:
print("记忆文件格式损坏,本次从空记录开始。")
return []
def save_memory(memory):
with MEMORY_FILE.open("w", encoding="utf-8") as file:
json.dump(memory, file, ensure_ascii=False, indent=2)
def show_memory(memory):
if not memory:
print("还没有学习记录。")
return
print("\n历史学习记录:")
for number, record in enumerate(memory, start=1):
print(f"{number}. {record['topic']}|{record['minutes']} 分钟")
def run_agent():
memory = load_memory()
show_memory(memory)
topic = input("\n今天学习了什么?").strip()
minutes_text = input("学习了多少分钟?").strip()
try:
minutes = int(minutes_text)
if minutes <= 0:
print("分钟数必须大于 0。")
return
except ValueError:
print("分钟数必须是整数。")
return
memory.append({
"topic": topic,
"minutes": minutes
})
save_memory(memory)
print("记录已保存,下次启动仍然可以读取。")
run_agent()在终端运行两次:
python day13_memory_agent.py第一次输入一条学习记录,程序会创建 study_memory.json。关闭后再次运行,开头会先显示上次的记录。此时循环体是否执行,取决于列表里是否有数据:如果 memory 为空,函数提前 return;如果有记录,for 会逐条执行。
项目里 MEMORY_FILE 是常量名,按习惯用大写;Path.exists() 检查文件是否存在;memory.append() 只更新内存中的列表;真正让结果长期保留的是后面的 save_memory(memory)。
• 路径找不到且直接用 r 打开,会触发 FileNotFoundError;
• JSON 文件内容损坏,会在 json.load() 时触发 JSONDecodeError;
• 变量名误写会触发 NameError,与磁盘文件本身无关;
• 使用 w 覆盖旧数据通常没有语法错误,却可能是严重的逻辑错误。
路径也是初学者的高频困惑。相对路径 study_memory.json 会保存到“运行命令时的当前文件夹”。如果找不到文件,先确认终端当前目录,而不是立刻怀疑代码没执行。
真实 Agent 会保存对话摘要、用户偏好、任务进度和工具结果。文件是最简单的存储层:数据量小时透明、可检查、容易调试。以后换成数据库,读取—更新—保存的思路仍然成立。
记忆并不等于“把所有内容都永久保存”。好的 Agent 还需要决定保存什么、保存多久、怎样保护隐私。今天先掌握技术闭环,后面再学习筛选和检索。
• 普通变量随程序结束而消失,文件可以持久保存;
• with open() 能在代码块结束时自动关闭文件;
• r 读取、w 覆盖写入、a 追加写入;
• 完整项目已经能读取旧记忆、添加记录并写回 JSON 文件。
下一篇,我们学习类与对象:把工具、记忆和行为装进同一个 Agent 骨架。
完成练习后,欢迎留言:第 13 天完成。