如何为 Python AI 代理添加记忆

发布: (2026年3月15日 GMT+8 05:01)
5 分钟阅读
原文: Dev.to

Source: Dev.to

你的 AI 代理在回应的瞬间会忘记所有内容。对它进行后续提问时,它没有任何上下文。没有记忆,每次交互都从头开始。

下面介绍如何在不到 40 行 Python 代码中解决这个问题——不使用 LangChain,也不依赖任何框架,只使用标准库和 OpenAI SDK。

代码

import json
import os
from pathlib import Path
from openai import OpenAI

MEMORY_FILE = "agent_memory.json"
client = OpenAI()  # uses OPENAI_API_KEY env var

def load_memory() -> list[dict]:
    """Load conversation history from disk."""
    if Path(MEMORY_FILE).exists():
        with open(MEMORY_FILE, "r") as f:
            return json.load(f)
    return []

def save_memory(messages: list[dict]) -> None:
    """Persist conversation history to disk."""
    with open(MEMORY_FILE, "w") as f:
        json.dump(messages, f, indent=2)

def chat(user_input: str, messages: list[dict]) -> str:
    """Send a message with full conversation history."""
    messages.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            *messages
        ],
    )

    reply = response.choices[0].message.content
    messages.append({"role": "assistant", "content": reply})
    save_memory(messages)
    return reply

if __name__ == "__main__":
    history = load_memory()
    print("Agent ready. Type 'quit' to exit.\n")

    while True:
        user_input = input("You: ").strip()
        if user_input.lower() == "quit":
            break
        print(f"Agent: {chat(user_input, history)}\n")

将其保存为 agent.py,设置 OPENAI_API_KEY,然后运行:

pip install openai
export OPENAI_API_KEY="sk-..."
python agent.py

工作原理

  • load_memory() 检查本地 JSON 文件并加载之前的对话。如果文件不存在,则以空列表重新开始。这是你的代理的长期记忆——它在重启后仍然存在。
  • save_memory() 在每次交互后将完整的消息列表写入磁盘。格式完全匹配 OpenAI 的消息模式,因此无需翻译步骤。
  • chat() 将用户的消息追加到历史记录中,将整个对话发送给模型,然后追加模型的回复。模型能够看到所有之前的回合,从而自然地引用早前的上下文。
  • API 调用中的 *messages 展开操作会在系统提示之后展开你的历史记录,使系统指令与对话流程分离。

你将看到

You: My name is Sarah and I'm building a CLI tool in Rust.
Agent: Nice to meet you, Sarah! A CLI tool in Rust is a great
       choice. What does it do?

You: What language am I using?
Agent: You're using Rust for your CLI tool.

# Restart the script...

You: What's my name?
Agent: Your name is Sarah!

代理会跨消息以及跨会话记住信息,因为 JSON 文件会持久化。

当出现以下情况时

  • 令牌溢出。 每条消息都会发送给模型。大约 50 次交互后,你会超出上下文窗口。
    解决方案: 在 API 调用前将 messages 修剪为最近的 N 条,或对旧消息进行摘要。

  • 没有语义搜索。 代理线性记住所有内容,但无法按主题搜索记忆。为此你需要添加嵌入存储——但那是另一个教程。

对于大多数原型和个人工具,这种平面文件方法出奇地好用。你可以获得持久的、上下文相关的对话,而无需除 OpenAI SDK 之外的任何依赖。

下一步

  • 添加 max_history 参数以限制令牌使用。
  • 为每条消息存储时间戳,以实现时间感知的回忆。
  • 将记忆划分为短期(RAM)和长期(磁盘)层。

查看 AI Agent Quick Tips 系列中的其他文章,了解更多模式,例如 retry logicstructured outputshuman approval gates

需要开箱即用的记忆、工具和编排的代理吗?Nebula 处理基础设施,让您专注于逻辑。

0 浏览
Back to Blog

相关文章

阅读更多 »