系列:「学AI,懂这些Python就够了」—— 面向AI智能体开发者的Python速成指南

标签:Python JSON YAML 文件操作 数据持久化 AI Agent

难度:⭐⭐☆☆☆


前言

一个没有"记忆"的智能体,每次对话都像第一次见面——这太糟糕了。

让智能体拥有记忆能力,核心就在于数据持久化:把对话历史存下来、把配置读进去、把知识库索引到向量数据库……这一切都离不开文件操作。

在AI智能体开发中,你打交道最多的三种数据格式是:

  • JSON:API数据交换的标准语言
  • YAML:人类可读的配置文件格式
  • 文件读写:日志、缓存、数据持久化的基础

本文是 「学AI,懂这些Python就够了」 系列的第四篇,带你掌握AI开发中所有文件操作相关的核心技能。


1. JSON操作:AI开发的通用语言

JSON 是AI领域的事实标准——LLM API的请求和响应都是JSON格式,前后端通信用JSON,配置文件也越来越多地使用JSON。

1.1 基础序列化与反序列化

import json

# ========= 序列化:Python对象 → JSON字符串 =========
data = {
    "model": "gpt-4",
    "messages": [
        {"role": "system", "content": "你是一个AI助手"},
        {"role": "user", "content": "介绍一下Python"},
    ],
    "temperature": 0.7,
    "max_tokens": 2048,
    "stream": False,
    "tools": None,  # None → null
}

# 基本序列化
json_str = json.dumps(data)
print(json_str)  # 压缩格式

# 美化输出(加上 indent)
json_str = json.dumps(data, indent=2, ensure_ascii=False)
print(json_str)
"""
{
  "model": "gpt-4",
  "messages": [
    {
      "role": "system",
      "content": "你是一个AI助手"
    },
    ...
  ],
  "temperature": 0.7,
  ...
}
"""

# ========= 反序列化:JSON字符串 → Python对象 =========
response_json = '{"id": "chatcmpl-123", "choices": [{"index": 0}]}'
response = json.loads(response_json)
print(response["id"])  # "chatcmpl-123"

1.2 JSON 文件读写

# ========= 写入JSON文件 =========
chat_history = [
    {"role": "system", "content": "你是AI助手"},
    {"role": "user", "content": "你好"},
    {"role": "assistant", "content": "你好!有什么可以帮你?"},
]

with open("chat_history.json", "w", encoding="utf-8") as f:
    json.dump(chat_history, f, ensure_ascii=False, indent=2)

# ========= 读取JSON文件 =========
with open("chat_history.json", "r", encoding="utf-8") as f:
    loaded_history = json.load(f)

print(f"加载了 {len(loaded_history)} 条对话记录")

⚠️ 重要:处理中文时一定要加 ensure_ascii=False,否则中文会被编码为 \uXXXX 格式。

1.3 中文处理对比

data = {"message": "你好,世界!"}

# ❌ 不指定 ensure_ascii(默认True)
print(json.dumps(data))
# {"message": "你好,世界!"}  ← 完全不可读

# ✅ 指定 ensure_ascii=False
print(json.dumps(data, ensure_ascii=False))
# {"message": "你好,世界!"}  ← 清晰可读

1.4 处理自定义类型

import json
from datetime import datetime
from dataclasses import dataclass

# 问题:datetime对象无法直接序列化
# data = {"timestamp": datetime.now()}
# json.dumps(data)  # TypeError! Object of type datetime is not JSON serializable

# 解决方案1:使用 default 参数
def json_encoder(obj):
    """自定义编码器"""
    if isinstance(obj, datetime):
        return obj.isoformat()
    if hasattr(obj, '__dict__'):
        return obj.__dict__
    raise TypeError(f"无法序列化类型: {type(obj)}")

data = {
    "timestamp": datetime.now(),
    "value": "test",
}
json_str = json.dumps(data, default=json_encoder, ensure_ascii=False)
print(json_str)

# 解决方案2:继承 JSONEncoder(更优雅)
class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return {"__type__": "datetime", "value": obj.isoformat()}
        return super().default(obj)

json_str = json.dumps(data, cls=CustomEncoder, ensure_ascii=False)

1.5 自定义解码器

def json_decoder(obj):
    """反向转换:JSON → Python自定义类型"""
    if "__type__" in obj:
        if obj["__type__"] == "datetime":
            return datetime.fromisoformat(obj["value"])
    return obj

json_str = '{"__type__": "datetime", "value": "2026-04-11T10:30:00"}'
result = json.loads(json_str, object_hook=json_decoder)
print(type(result))  # <class 'datetime.datetime'>

1.6 错误处理

def safe_json_loads(json_str: str, default=None):
    """安全地解析JSON,失败时返回默认值"""
    try:
        return json.loads(json_str)
    except json.JSONDecodeError as e:
        print(f"JSON解析错误 (位置 {e.pos}): {e.msg}")
        return default

def safe_json_load(filepath: str, default=None):
    """安全地从文件加载JSON"""
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        print(f"文件不存在: {filepath}")
        return default
    except json.JSONDecodeError as e:
        print(f"JSON格式错误: {e}")
        return default

1.7 实战:JSON配置管理器

import json
from pathlib import Path
from typing import Any, Optional

class JSONConfig:
    """基于JSON文件的配置管理器 —— AI Agent的配置持久化"""

    def __init__(self, filepath: str):
        self.filepath = Path(filepath)
        self._data: dict = {}
        self._load()

    def _load(self):
        """从文件加载配置"""
        if self.filepath.exists():
            self._data = safe_json_load(str(self.filepath), default={})

    def save(self):
        """保存配置到文件"""
        self.filepath.parent.mkdir(parents=True, exist_ok=True)
        with open(self.filepath, "w", encoding="utf-8") as f:
            json.dump(self._data, f, ensure_ascii=False, indent=2)

    def get(self, key: str, default: Any = None) -> Any:
        """获取配置项(支持点号分隔的嵌套键)"""
        keys = key.split(".")
        value = self._data
        for k in keys:
            if isinstance(value, dict):
                value = value.get(k)
                if value is None:
                    return default
            else:
                return default
        return value

    def set(self, key: str, value: Any):
        """设置配置项(支持点号分隔的嵌套键)"""
        keys = key.split(".")
        data = self._data
        for k in keys[:-1]:
            if k not in data:
                data[k] = {}
            data = data[k]
        data[keys[-1]] = value

    def update(self, updates: dict):
        """批量更新配置"""
        self._data.update(updates)

    def __repr__(self):
        return f"JSONConfig({self.filepath}, keys={list(self._data.keys())})"

# 使用示例
config = JSONConfig("./agent_data/config.json")
config.set("model.name", "gpt-4")
config.set("model.temperature", 0.7)
config.set("memory.max_messages", 20)
config.save()

print(config.get("model.name"))       # "gpt-4"
print(config.get("model.unknown", 0)) # 0 (默认值)

2. YAML操作:人类友好的配置格式

2.1 YAML vs JSON:一眼看出的区别

# YAML —— 人类友好,带注释
agent:
  name: "客服助手"
  model: "gpt-4"
  temperature: 0.7          # 低温度,保证回答的稳定性
  tools:                    # 注册的工具列表
    - name: "search_kb"
      description: "搜索知识库"
    - name: "query_db"
      description: "查询数据库"
  memory:
    type: "buffer"
    max_messages: 20

对比等价的JSON:

{
  "agent": {
    "name": "客服助手",
    "model": "gpt-4",
    "temperature": 0.7,
    "tools": [
      {"name": "search_kb", "description": "搜索知识库"},
      {"name": "query_db", "description": "查询数据库"}
    ],
    "memory": {"type": "buffer", "max_messages": 20}
  }
}

结论:YAML更紧凑、可读性更好、支持注释,是配置文件的理想选择。

2.2 基础操作

import yaml

# ========= 解析YAML =========
yaml_str = """
agents:
  - name: analyzer
    role: 数据分析师
    tools: [python, sql]
  - name: writer
    role: 文案撰写者
    tools: [search, translate]
"""

# ⚠️ 永远用 safe_load,不要用 load!(有安全风险)
data = yaml.safe_load(yaml_str)
print(data["agents"][0]["name"])  # "analyzer"

# ========= 序列化为YAML =========
config = {
    "model": "gpt-4",
    "parameters": {
        "temperature": 0.7,
        "top_p": 0.9,
    },
    "description": "我的AI智能体配置",
}

yaml_output = yaml.dump(
    config,
    allow_unicode=True,        # 保留中文
    default_flow_style=False,  # 使用块风格(不要内联)
    sort_keys=False,           # 保持插入顺序
)
print(yaml_output)

2.3 YAML文件读写

# ========= 写入YAML文件 =========
agent_config = {
    "agent_name": "知识库助手",
    "llm": {
        "provider": "openai",
        "model": "gpt-4",
        "temperature": 0.3,
    },
    "retrieval": {
        "top_k": 5,
        "score_threshold": 0.7,
    },
    "prompts": {
        "system": "你是一个基于知识库回答问题的助手。\n请用中文回答,引用具体知识来源。",
        "greeting": "你好!我是知识库助手,有什么可以帮你的?",
    },
}

with open("agent_config.yaml", "w", encoding="utf-8") as f:
    yaml.dump(agent_config, f, allow_unicode=True, default_flow_style=False)

# ========= 读取YAML文件 =========
with open("agent_config.yaml", "r", encoding="utf-8") as f:
    config = yaml.safe_load(f)

print(config["llm"]["model"])  # "gpt-4"

2.4 YAML锚点与别名 —— 复用配置的利器

# 定义锚点 & 和引用 *
default_settings: &defaults         # 定义锚点
  model: gpt-4
  temperature: 0.7
  max_tokens: 2048

agent_1:
  <<: *defaults                      # 继承默认配置
  name: "Agent-1"
  temperature: 0.9                   # 覆盖个别参数

agent_2:
  <<: *defaults
  name: "Agent-2"
  model: gpt-3.5-turbo              # 换模型但保留其他参数
# Python中解析带锚点的YAML
yaml_str = """
defaults: &defaults
  model: gpt-4
  temperature: 0.7

agent_a:
  <<: *defaults
  name: Agent-A
"""

config = yaml.safe_load(yaml_str)
print(config["agent_a"])
# {'model': 'gpt-4', 'temperature': 0.7, 'name': 'Agent-A'}

2.5 多文档YAML

# ========= 读取多文档YAML =========
multi_yaml = """---
agent: ChatBot
model: gpt-4
---
agent: Analyzer
model: gpt-3.5-turbo
---
agent: Writer
model: claude-3
"""

documents = list(yaml.safe_load_all(multi_yaml))
for doc in documents:
    print(f"Agent: {doc['agent']}, Model: {doc['model']}")

# ========= 写入多文档YAML =========
docs = [
    {"agent": "ChatBot", "model": "gpt-4"},
    {"agent": "Analyzer", "model": "gpt-3.5-turbo"},
]

with open("multi_agents.yaml", "w", encoding="utf-8") as f:
    yaml.dump_all(docs, f, allow_unicode=True)

2.6 实战:YAML配置管理器

import yaml
from pathlib import Path
from typing import Any

class YAMLConfig:
    """基于YAML的配置管理器 —— 更友好的配置文件方案"""

    def __init__(self, filepath: str):
        self.filepath = Path(filepath)
        self._data: dict = {}
        self.load()

    def load(self):
        """从文件加载"""
        if self.filepath.exists():
            with open(self.filepath, "r", encoding="utf-8") as f:
                self._data = yaml.safe_load(f) or {}

    def save(self):
        """保存到文件"""
        self.filepath.parent.mkdir(parents=True, exist_ok=True)
        with open(self.filepath, "w", encoding="utf-8") as f:
            yaml.dump(
                self._data, f,
                allow_unicode=True,
                default_flow_style=False,
                sort_keys=False,
            )

    def get(self, key: str, default: Any = None) -> Any:
        """点号分隔的嵌套键取值"""
        keys = key.split(".")
        value = self._data
        for k in keys:
            if isinstance(value, dict):
                value = value.get(k)
            else:
                return default
        return value if value is not None else default

    def set(self, key: str, value: Any):
        """点号分隔的嵌套键设值"""
        keys = key.split(".")
        data = self._data
        for k in keys[:-1]:
            data = data.setdefault(k, {})
        data[keys[-1]] = value

# 使用示例
config = YAMLConfig("./agent_config.yaml")
config.set("agent.name", "客服助手")
config.set("agent.model", "gpt-4")
config.set("tools.search.enabled", True)
config.save()

3. 文件读写:一切持久化的基础

3.1 传统文件操作(open/read/write)

# ========= 基本文件写入 =========
with open("output.txt", "w", encoding="utf-8") as f:
    f.write("第一行内容\n")
    f.write("第二行内容\n")
    f.writelines(["第三行\n", "第四行\n"])

# ========= 基本文件读取 =========
# 方式1:一次性读取全部
with open("output.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)

# 方式2:逐行读取(推荐用于大文件)
with open("output.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())

# 方式3:读取所有行到列表
with open("output.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
    print(f"共 {len(lines)} 行")

3.2 文件模式速查

模式 描述 文件不存在时
'r' 只读(默认) ❌ 报错
'w' 写入(覆盖已有内容) ✅ 新建
'a' 追加(在末尾添加) ✅ 新建
'x' 创建(存在则报错) ✅ 新建
'r+' 读写 ❌ 报错
'b' 二进制模式(可与上述组合) -
't' 文本模式(默认) -
# 二进制模式 —— 读取图片、音频等非文本文件
with open("image.png", "rb") as f:
    image_data = f.read()

# 追加模式 —— 写日志
with open("agent.log", "a", encoding="utf-8") as f:
    f.write(f"[{datetime.now()}] 用户输入了一条消息\n")

3.3 pathlib —— 现代化的文件路径操作

Python 3.4+ 推荐使用 pathlib.Path 替代 os.path。代码更简洁、更安全。

from pathlib import Path

# ========= 路径操作 =========
# 拼接路径
config_dir = Path("agent_data") / "configs" / "production"
# Windows: agent_data\configs\production
# Linux:   agent_data/configs/production

# 获取路径信息
file = Path("agent_data/chat_history.json")
print(file.name)        # "chat_history.json"
print(file.stem)        # "chat_history"    (不含后缀)
print(file.suffix)      # ".json"
print(file.parent)      # "agent_data"
print(file.absolute())  # 绝对路径

# ========= 读写文件(Path 简化版) =========
# 写入文本 —— 一行搞定!
Path("output.txt").write_text("Hello World", encoding="utf-8")

# 读取文本 —— 也是一行!
content = Path("output.txt").read_text(encoding="utf-8")

# 读写二进制
Path("data.bin").write_bytes(b"binary data")
data = Path("data.bin").read_bytes()

# ========= 目录操作 =========
# 创建目录(自动创建所有父目录)
Path("deep/nested/directory").mkdir(parents=True, exist_ok=True)

# 遍历目录
for file in Path("agent_data").iterdir():
    print(file.name)

# 递归查找文件
for json_file in Path("agent_data").rglob("*.json"):
    print(json_file)

# ========= 文件检查 =========
path = Path("agent_config.yaml")
if path.exists():
    print("文件存在")
if path.is_file():
    print("这是一个文件")
if path.is_dir():
    print("这是一个目录")

3.4 文件操作常用场景

import shutil
from pathlib import Path

# 复制文件
shutil.copy("source.txt", "destination.txt")
shutil.copy2("source.txt", "backup.txt")  # 保留元数据(修改时间等)

# 移动/重命名文件
shutil.move("old_name.txt", "new_name.txt")
Path("old_name.txt").rename("new_name.txt")

# 删除文件
Path("temp.txt").unlink()      # Path 方式
# os.remove("temp.txt")        # 传统方式

# 删除目录(递归删除!谨慎使用)
shutil.rmtree("old_agent_data")

# 获取文件信息
stat = Path("large_file.txt").stat()
print(f"大小: {stat.st_size} 字节")
print(f"修改时间: {stat.st_mtime}")
print(f"创建时间: {stat.st_ctime}")

3.5 CSV 文件读写

import csv

# ========= 写入CSV =========
# 场景:记录每次API调用的Token消耗
with open("token_usage.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["时间", "模型", "输入Token", "输出Token", "成本($)"])
    writer.writerow(["2026-04-11 10:30", "gpt-4", 150, 200, 0.0165])
    writer.writerow(["2026-04-11 10:31", "gpt-4", 200, 300, 0.0240])

# ========= 读取CSV =========
with open("token_usage.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    total_cost = 0
    for row in reader:
        total_cost += float(row["成本($)"])
    print(f"总成本: ${total_cost:.4f}")

3.6 临时文件

import tempfile

# 临时文件 —— 自动在程序结束时清理
with tempfile.NamedTemporaryFile(
    mode="w", suffix=".json", delete=True, encoding="utf-8"
) as tmp:
    tmp.write('{"status": "temporary"}')
    tmp.flush()
    print(f"临时文件路径: {tmp.name}")
    # 做一些处理...
# 离开with块后,文件自动删除

# 临时目录
with tempfile.TemporaryDirectory() as tmpdir:
    file = Path(tmpdir) / "temp.json"
    file.write_text('{"data": "temp"}', encoding="utf-8")
    # 在临时目录中工作...
# 离开with块后,整个目录自动删除

4. 实战:构建智能体的持久化层

4.1 对话历史管理器

import json
from pathlib import Path
from datetime import datetime
from typing import List, Dict, Optional

class ConversationStore:
    """对话历史持久化 —— 让智能体拥有"记忆力" """

    def __init__(self, storage_dir: str = "./conversations"):
        self.storage_dir = Path(storage_dir)
        self.storage_dir.mkdir(parents=True, exist_ok=True)

    def save_conversation(
        self, session_id: str, messages: List[Dict[str, str]]
    ):
        """保存对话历史"""
        filepath = self.storage_dir / f"{session_id}.json"
        data = {
            "session_id": session_id,
            "updated_at": datetime.now().isoformat(),
            "message_count": len(messages),
            "messages": messages,
        }
        filepath.write_text(
            json.dumps(data, ensure_ascii=False, indent=2),
            encoding="utf-8",
        )

    def load_conversation(
        self, session_id: str
    ) -> Optional[List[Dict[str, str]]]:
        """加载对话历史"""
        filepath = self.storage_dir / f"{session_id}.json"
        if not filepath.exists():
            return None
        data = json.loads(filepath.read_text(encoding="utf-8"))
        print(f"加载会话 {session_id}: {data['message_count']} 条消息")
        return data["messages"]

    def get_recent_messages(
        self, session_id: str, max_messages: int = 20
    ) -> List[Dict[str, str]]:
        """获取最近N条消息(Token窗口管理)"""
        messages = self.load_conversation(session_id) or []
        return messages[-max_messages:]

    def list_sessions(self) -> List[Dict]:
        """列出所有会话"""
        sessions = []
        for filepath in self.storage_dir.glob("*.json"):
            data = json.loads(filepath.read_text(encoding="utf-8"))
            sessions.append({
                "session_id": data["session_id"],
                "message_count": data["message_count"],
                "updated_at": data["updated_at"],
            })
        sessions.sort(key=lambda s: s["updated_at"], reverse=True)
        return sessions

    def delete_session(self, session_id: str):
        """删除会话"""
        filepath = self.storage_dir / f"{session_id}.json"
        if filepath.exists():
            filepath.unlink()

# 使用示例
store = ConversationStore("./agent_memory")
store.save_conversation("user_123", [
    {"role": "system", "content": "你是AI助手"},
    {"role": "user", "content": "你好"},
    {"role": "assistant", "content": "你好!有什么可以帮你的?"},
])

# 下次用户回来时恢复上下文
history = store.load_conversation("user_123")

4.2 简易日志系统

from pathlib import Path
from datetime import datetime
from enum import Enum

class LogLevel(str, Enum):
    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"

class SimpleLogger:
    """简易日志系统 —— 追踪智能体行为"""

    def __init__(
        self,
        log_dir: str = "./logs",
        max_file_size: int = 10 * 1024 * 1024,  # 10MB
        backup_count: int = 5,
    ):
        self.log_dir = Path(log_dir)
        self.log_dir.mkdir(parents=True, exist_ok=True)
        self.max_file_size = max_file_size
        self.backup_count = backup_count
        self._current_file = self._get_log_file()

    def _get_log_file(self) -> Path:
        """获取当前日志文件(自动轮转)"""
        log_file = self.log_dir / f"agent_{datetime.now():%Y%m%d}.log"
        if log_file.exists() and log_file.stat().st_size > self.max_file_size:
            # 文件过大,轮转
            for i in range(self.backup_count - 1, 0, -1):
                old = self.log_dir / f"agent_{datetime.now():%Y%m%d}.log.{i}"
                new = self.log_dir / f"agent_{datetime.now():%Y%m%d}.log.{i+1}"
                if old.exists():
                    old.rename(new)
            log_file.rename(str(log_file) + ".1")
        return log_file

    def log(self, level: LogLevel, message: str, **context):
        """写入日志"""
        timestamp = datetime.now().isoformat()
        context_str = " ".join(f"{k}={v}" for k, v in context.items())
        line = f"[{timestamp}] [{level.value}] {message}"
        if context_str:
            line += f" | {context_str}"
        line += "\n"

        with open(self._current_file, "a", encoding="utf-8") as f:
            f.write(line)

        # DEBUG级别也输出到控制台
        if level == LogLevel.ERROR:
            print(f"❌ {line.strip()}")

    def debug(self, msg: str, **ctx): self.log(LogLevel.DEBUG, msg, **ctx)
    def info(self, msg: str, **ctx): self.log(LogLevel.INFO, msg, **ctx)
    def warning(self, msg: str, **ctx): self.log(LogLevel.WARNING, msg, **ctx)
    def error(self, msg: str, **ctx): self.log(LogLevel.ERROR, msg, **ctx)

# 使用
logger = SimpleLogger()
logger.info("智能体启动", model="gpt-4", temperature=0.7)
logger.info("用户消息", session="user_123", tokens=150)
logger.warning("API调用延迟较高", latency=3.2)
logger.error("工具调用失败", tool="search", error="timeout")

5. 最佳实践

5.1 文件操作的最佳实践

# ✅ 1. 始终使用 with 语句(自动关闭文件)
with open("file.txt", "r", encoding="utf-8") as f:
    content = f.read()

# ✅ 2. 始终指定 encoding='utf-8'
with open("file.txt", "w", encoding="utf-8") as f:
    f.write(content)

# ✅ 3. 使用 pathlib.Path 而非字符串拼接
from pathlib import Path
file = Path("data") / "configs" / "agent.json"  # ✅
# file = "data" + "/" + "configs" + "/" + "agent.json"  # ❌

# ✅ 4. 处理大文件时逐行读取
with open("large_file.jsonl", "r", encoding="utf-8") as f:
    for line in f:
        process(json.loads(line))

# ✅ 5. 使用原子写入(避免写入一半时程序崩溃导致文件损坏)
import tempfile
import shutil

def atomic_write(filepath: str, content: str):
    """原子写入:先写临时文件,成功后再替换"""
    tmp_file = Path(filepath).with_suffix(".tmp")
    tmp_file.write_text(content, encoding="utf-8")
    shutil.move(str(tmp_file), filepath)  # 原子操作(同分区内)

5.2 JSON最佳实践

# ✅ 处理中文
json.dumps(data, ensure_ascii=False)

# ✅ 美化输出
json.dumps(data, ensure_ascii=False, indent=2)

# ✅ 始终处理错误
try:
    data = json.loads(user_input)
except json.JSONDecodeError as e:
    print(f"输入不是有效的JSON: {e}")

5.3 YAML最佳实践

# ✅ 始终使用 safe_load(安全!)
config = yaml.safe_load(yaml_str)  # ✅
# config = yaml.load(yaml_str)      # ❌ 危险!可能执行任意代码

# ✅ 保留中文
yaml.dump(data, allow_unicode=True)

# ✅ 块风格更易读
yaml.dump(data, default_flow_style=False)

5.4 目录结构建议

agent_data/
├── config/
│   ├── agent.yaml          # 智能体配置(YAML更友好)
│   └── tools.json          # 工具注册表
├── conversations/          # 对话历史
│   ├── user_001.json
│   └── user_002.json
├── cache/                  # 缓存数据
│   └── embeddings_cache/
├── logs/                   # 日志文件
│   └── agent_20260411.log
└── knowledge/              # 知识库文件
    ├── faq.txt
    └── product_docs.json

6. 总结与下一步

本篇核心知识

数据持久化三大件
├── JSON 操作
│   ├── dumps/loads:内存中序列化
│   ├── dump/load:文件读写
│   ├── ensure_ascii=False:保留中文
│   ├── default参数:自定义类型编码
│   └── JSONDecodeError:错误处理
├── YAML 操作
│   ├── safe_load:安全解析(必须!)
│   ├── dump:序列化
│   ├── 锚点&别名:配置复用
│   └── 适合人类编辑的配置文件
└── 文件操作
    ├── open/write/read:传统操作
    ├── pathlib.Path:现代化路径
    ├── shutil:复制、移动、删除
    ├── csv模块:表格数据
    └── tempfile:临时文件

快速自测

  • JSON: 能否正确处理中文(ensure_ascii=False)?
  • YAML: 是否一直使用 safe_load 而非 load
  • 文件: 是否习惯用 pathlib.Path 替代字符串路径?
  • 资源: 是否始终用 with 语句管理文件?
  • 编码: 是否每次打开文件都指定 encoding='utf-8'

下一步

掌握了数据持久化,你的智能体已经有了"记性"。最后一篇文章中,我们将学习Python环境管理——venv、conda、pip——让你的AI开发环境规范、可复现、可共享。

上一篇学AI,懂这些Python就够了(三):requests·httpx·pydantic·dataclasses —— AI开发者必装的4个Python库

下一篇学AI,懂这些Python就够了(五):venv·conda·pip —— 打造AI开发的可复现环境


本文是「学AI,懂这些Python就够了」系列的第4篇。数据持久化是智能体从"一次性对话"到"长期记忆"的桥梁——就像人需要记忆一样,智能体也需要把重要的东西存下来。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐