【从 0 到 1 动手造 Agent】03、给 Agent 装上操作系统——MemGPT/Letta 内存分层与自我演化

前两章我们拿到两把钥匙:Swarm 给了我们一个自由的 ReAct 循环,LangGraph 给了我们一个确定性的图。 但合上书,一个更尖刻的问题浮上来------如果对话进行到第 100 轮,上下文窗口爆了,你的 Agent 还记得我是谁、说过什么吗?
把 LLM 当 CPU,把 Context 当 RAM------不够用时,就给它装一块"磁盘"。 这就是 MemGPT(今天的 Letta)给出的答案,也是本篇的主角。


1. 前言:前两章留下的问题

先回顾一下我们走到哪了:

  • 第 01 篇(Swarm) :ReAct 循环 + 交接。核心是 417 行代码里的那个 while 循环。它证明了 Agent 的骨架简单到令人发指,但也留下了四个短板------其中第一个就是上下文无解
  • 第 02 篇(LangGraph):确定性图状态机。150 行代码把"控制流"从代码里拎出来,变成显式的图 + State + reducer。它把"流程怎么走"锁死了,但**"记忆装在哪"这个问题,它只是用 Checkpointer 存了一个快照**。

两章合起来,恰好暴露出整个行业最扎眼的一个问题:

模型记不住东西。

不是"记性差",是物理上装不下。一个 128k 上下文窗口,塞进 100 轮对话的 tool 返回、中间思考、冗余日志,早就爆了。工业界最常见的解法是"截断最老的"或"把历史丢给向量库"------但这两招都很粗糙:截断 = 用户说过的话永远消失;向量库 = 模型根本不知道你丢给它的是谁的话。

那么问题来了:在真实的世界里,"记不住就装不下"这个问题,操作系统是怎么解决的?

答案是------内存分层

  • 速度快的装不下(RAM),容量大的够不着(磁盘);
  • CPU 只跟 RAM 打交道,磁盘由操作系统换页(paging)按需调度;
  • 装不下的时候,操作系统明确地告诉进程:"内存压力高,请你自己清理"。

MemGPT 论文(MemGPT: Towards LLMs as Operating Systems , Packer et al., 2023)干的事,就是把这一整套计算机体系结构,原封不动地搬给了大模型。它现在的开源继任者叫 Letta。本篇我们就把它最本质的两件事讲透、写透、跑透:

  1. 类 OS 的内存分层------RAM(In-Context)与 Disk(Out-of-Context);
  2. 自我修改内存(Self-Editing Memory)------模型自己调用工具,改写自己的 System Prompt。

2. 概念蒸馏:类 OS 的三级内存分层

2.1 一张图看懂 MemGPT 的内存观

MemGPT 把所有 Agent 状态分成两层、共四块"存储"。先记住这张图:

四个区域,两句话:

存储 位置 谁看得见 怎么读写
Core Memory(系统级内存条) 每次都编译进 System Prompt 模型直接读;改它用工具 core_memory_append / core_memory_replace
Working Context(工作区) 对话消息的 FIFO 队列 模型直接读 追加 / 满了自动换页
Recall Storage(回忆磁盘) 数据库,不在上下文 模型不知道里面有啥 conversation_search 按 id 精确取
Archival Storage(档案磁盘) 数据库 + 向量索引 同上 archival_memory_insert / archival_memory_search

2.2 两个必须嚼碎的概念

① 自我修改内存(Self-Editing Memory)

记忆的写入者,不是用户,是模型自己。

传统 Agent:你的信息写死在 prompt 里,想改得改代码。MemGPT 把"写记忆"变成模型的一个工具 :模型读完 System Prompt,发现"哦,这个用户偏好我没记",就调用 core_memory_append,把这句话物理写进 Core Memory 块------下一轮 System Prompt 重新编译,新记忆就进去了。

这就实现了"动态自我进化":不用改一行部署代码,模型自己在运行时决定"该记什么、该忘什么、该改什么"。

② 内存换页(Memory Paging)

Working Context 装不下了,最老的对话不是被删掉,而是被压到磁盘(Recall Storage)。

换页还伴随着一个关键动作:当 Working Context 或 Core Memory 接近阈值时,系统往 System Prompt 里注入一条显式的告警------

makefile 复制代码
SystemAlert: Memory pressure high. ...

为什么要有这条告警?因为模型对"上下文快满了"这件事毫无知觉 ------它只看得见窗口里的内容,看不见窗口的边界。系统必须像操作系统的信号一样,主动把压力通知给它,它才会想起来去调工具压缩记忆。这是"让模型管理自己的内存"的前提:先让压力对模型可见。


3. 剥离杂音:工业级 Letta 库里真正重要的 5% 代码

3.1 为什么不要一上来就啃全栈

现在的 Letta 是一个全栈系统:REST API、Web 前端、CLI、Postgres/SQLite 的 ORM、沙箱、多租户、审计、SSE 流式......这些加起来几万行。如果按照老规矩 clone 下来逐行读,大概两周后就会在第 800 行左右的 alembic 迁移脚本里阵亡。

大框架 90% 的代码是工程设施,真正决定它"长什么样"的,只有一小撮设计思想。

对 MemGPT/Letta 来说,这一小撮只落在三个文件里(直接切换到官方 archive 初版分支)。剥掉所有 REST 路由、DB 访问、SSE 推送,剩下的骨架就这么细:

bash 复制代码
letta/
├── schemas/block.py                    ← ★ 记忆块:label / value / limit
├── schemas/memory.py                   ← ★ 记忆容器:compile() 把记忆编译进 System Prompt
├── functions/function_sets/base.py     ← ★ 记忆工具:core_memory_append 等(自我修改的入口)
└── agents/letta_agent_v2.py            ← ★ 事件循环:step / _step / heartbeat

3.2 真正的 5%,逐段看

记忆块(schemas/block.py)------记忆的最小单元。 注意那个 limit,它是"内存"二字的物理含义:

python 复制代码
class Block(BaseBlock):
    value: str              # 内容
    limit: int              # 字符上限(默认 CORE_MEMORY_BLOCK_CHAR_LIMIT = 100000)
    label: str              # 名字,如 "human" / "persona"
    read_only: bool         # 只读块:模型的工具改不了

记忆编译(schemas/memory.py:688)------把数据拼回 System Prompt。 这是"记忆 → 上下文"的唯一桥梁:

python 复制代码
def compile(self, ...) -> str:
    s = StringIO()
    self._render_memory_blocks_standard(s)   # 每个 block 渲染成 XML,带 chars_current / chars_limit
    ...
    return s.getvalue()

记忆工具(functions/function_sets/base.py:246)------自我修改的唯一入口。 看清楚一件事:core_memory_append 里没有任何"魔法",它就是字符串拼接 + 写回对象:

python 复制代码
def core_memory_append(agent_state, label: str, content: str) -> str:
    current_value = str(agent_state.memory.get_block(label).value)
    new_value = current_value + "\n" + str(content)
    agent_state.memory.update_block_value(label=label, value=new_value)
    return new_value

这三段加起来不到 30 行。MemGPT 的全部原创性,就在这 30 行里。 剩下的一切------消息打包、DB 落库、heartbeat 规则、流式------都是工程。

3.3 一个必须点破的隐喻:Agent-as-a-Service State

真实 Letta 里,那个被工具改写的对象叫 AgentStateschemas/agent.py),它持有 memorymessage_idstoolsllm_config 等等------一个 Agent 的全部状态就是一个可持久化的数据结构 。这也是为什么 Letta 敢叫"Agent-as-a-Service":Agent 不是一段运行中的进程,而是一份可以被序列化、落库、恢复的状态

我们的最小复刻不需要 AgentState 那么大的结构,只需要它的灵魂:一个能自我修改的 CoreMemory 对象。


4. 最小复刻:用 Java 25+ 手写 MemGPT 核心

概念清楚了,动手。全套复刻(Java 25+ / Groovy 各一份)只有四个组件,零依赖 ,约 300 行核心代码。没有一行是"AI 魔法"------全是集合、队列、字符串拼接。代码在 harness/letta/

bash 复制代码
java_letta/src/letta/
├── MemoryBlock.java            # 记忆块:label / value / limit / readOnly
├── CoreMemory.java             # 内存条:compileToPrompt() 编译进 System Prompt
├── MemoryTools.java            # 工具箱:core_memory_append / core_memory_replace
├── MockLlm.java                # 假 LLM:真的去读编译出的 <CORE_MEMORY> 做决策
└── MemGptAgentController.java  # 事件循环 + FIFO + 换页 + SystemAlert

4.1 组件一:MemoryBlock 与 CoreMemory(内存结构)

记忆块和真实 Letta 的 Block 一一对应------labelvaluelimitread_only,外加 append / replace 两个带护栏的写操作:

java 复制代码
public class MemoryBlock {
    private final String label;
    private String value;
    private final int limit;
    private final boolean readOnly;

    /** 追加一行记忆。limit 是硬边界 ------ 超出就拒绝。 */
    public void append(String content) {
        checkWritable();
        if (value.length() + content.length() > limit) {
            throw new IllegalStateException("Block limit exceeded: [" + label + "] "
                    + value.length() + " + " + content.length() + " > " + limit);
        }
        value = value.isBlank() ? content : value + "\n" + content;
    }

    /** 渲染成模型可见的 XML 节点 ------ 带上 chars_current / chars_limit 元数据。 */
    public String toPromptNode() {
        return "  <" + label + " chars_current=" + charsUsed() + " chars_limit=" + limit + ">\n"
                + "    " + value + "\n"
                + "  </" + label + ">";
    }
}

然后 CoreMemory 把若干块装进一张有序表,对外只暴露一个最关键的方法:

java 复制代码
/**
 * ★ 编译为 System Prompt 中的 <CORE_MEMORY> 节点。
 * 对应 Letta 的 Memory.compile()。每一次推理前调用一次,
 * 记忆被工具改写后,下一次调用自然产出不同的文本 ------ 自我编辑闭环就此完成。
 */
public String compileToPrompt() {
    StringBuilder sb = new StringBuilder("<CORE_MEMORY>\n");
    for (MemoryBlock block : blocks.values()) {
        sb.append(block.toPromptNode()).append('\n');
    }
    sb.append("</CORE_MEMORY>");
    return sb.toString();
}

▍Highlight:compileToPrompt() 是整个"自我编辑"的轴心。 记忆是数据,Prompt 是它的渲染产物 。模型改的不是"prompt 字符串",而是背后的 CoreMemory 对象;下一轮推理前,compileToPrompt() 重新渲染,System Prompt 就自动带上了新记忆。你不需要任何"把修改写回 prompt"的代码------因为 prompt 从来不是源头,它只是投影。

4.2 组件二:MemoryTools(自我修改工具箱)

模型不能直接碰 CoreMemory,它只能"申请调用"工具------工具才是唯一能改写内存的通道。这和真实 Letta 的 core_memory_append 逐行对应:

java 复制代码
public final class MemoryTools {

    public static final String APPEND = "core_memory_append";
    public static final String REPLACE = "core_memory_replace";
    public static final String SEND_MESSAGE = "send_message";

    /** 追加记忆到某个 block 末尾。返回最新值,让模型"看到"改动生效。 */
    public static String core_memory_append(CoreMemory memory, String label, String content) {
        memory.append(label, content);                        // ① 物理改写内存对象
        return "OK: 已追加到 memory block [" + label + "] → " + content;
    }
}

对照真实 Python 源码你会发现:行为一模一样 ------current_value + "\n" + content,然后 update_block_value。我们的"update"就是那行 memory.append(label, content),它直接改的是 MemoryBlock.value 那个字符串字段。

4.3 组件三:MemGptAgentController(事件循环 + 换页)

控制器是唯一有"动作"的地方。一轮推理做四件事:

java 复制代码
public Message run(String userInput) {
    round++;
    push(userInput);                              // ① 用户消息进 Working Context(RAM 的 FIFO)
    for (int step = 1; step <= MAX_INNER_STEPS; step++) {
        lastSystemPrompt = buildSystemPrompt();   // ② System Prompt = 模板 + 编译后的 CoreMemory(+ 压力告警)
        ToolCall call = llm.respond(lastSystemPrompt, new ArrayList<>(workingContext)); // ③ 模拟 LLM
        System.out.println("  [llm] 决策 → " + call.describe());
        Message result = dispatch(call);          // ④ 截获并执行工具
        if (result.role().startsWith("assistant")) {
            return result;                        // 模型对用户说话了 → 本轮结束
        }
        // 记忆工具改完记忆 → heartbeat,让模型再想一步(真实 Letta 的 request_heartbeat)
    }
    throw new IllegalStateException("超过 " + MAX_INNER_STEPS + " 步仍未对用户说话");
}

工具截获 + 物理改写 就发生在 dispatch 里:

java 复制代码
private Message dispatch(ToolCall call) {
    return switch (call.name()) {
        case MemoryTools.APPEND, MemoryTools.REPLACE -> {
            String result = MemoryTools.APPEND.equals(call.name())
                    ? MemoryTools.core_memory_append(coreMemory, call.arg("label"), call.arg("content"))
                    : MemoryTools.core_memory_replace(coreMemory, call.arg("label"),
                            call.arg("old_value"), call.arg("new_value"));
            System.out.println("  [tool] " + call.name() + " 执行成功");
            Message toolMsg = Message.tool(call.name(), result);
            push(call, toolMsg);                  // 工具结果进上下文
            yield toolMsg;                        // 记忆工具不结束本轮 → 循环继续(heartbeat)
        }
        case MemoryTools.SEND_MESSAGE -> {
            Message reply = Message.assistant(call.arg("message"));
            push(reply);
            return reply;                         // 对用户说话 = 本轮结束
        }
        default -> throw new IllegalStateException("未知工具: " + call.name());
    };
}

内存换页是 Working Context 的 FIFO 逻辑------塞不下就压最老的:

java 复制代码
private void push(Message message) {
    while (queueTokens() + message.tokens() > contextBudget) {
        pageOut();                                // 超预算 → 换页
    }
    workingContext.addLast(message);
}

/** ★ 内存换页:把 RAM 最老的消息弹出,压进 Recall Storage(Disk)。 */
private void pageOut() {
    Message oldest = workingContext.pollFirst();
    recallStorage.add(oldest);
    System.out.println("  [paging] Working Context 超预算," + oldest.tokens()
            + "t 的最老消息已换页到 Recall Storage(Disk): " + oldest.content());
}

内存压力告警在组装 System Prompt 时触发:

java 复制代码
private String pressureAlert() {
    if (coreMemory.totalChars() >= memoryThreshold) {
        return "你的核心记忆已接近字符上限,请用 core_memory_replace 压缩或清洗旧记忆。";
    }
    if (queueTokens() >= contextBudget * 0.8) {
        return "Working Context 已接近 token 上限,请用工具压缩历史。";
    }
    return null;
}

只要这个函数返回非空,buildSystemPrompt() 就会在末尾追加一行 SystemAlert: Memory pressure high. ...模型在下一轮推理时,真的会读到这条告警。

4.4 组件四:假 LLM(读的真是编译后的 Prompt)

MockLlm 是本篇的关键道具------它的决策规则真的去读 compileToPrompt() 编译出的 System Prompt,而不是偷偷翻一个旁路变量:

java 复制代码
public final class MockLlm implements LLM {

    @Override
    public ToolCall respond(String systemPrompt, List<Message> workingContext) {
        String lastUser = lastUserText(workingContext);
        String human = extractBlock(systemPrompt, "human");   // ← 从 <CORE_MEMORY> 里抠出 human 块

        // 规则 1:发现一个新偏好 → 自我编辑记忆
        if (lastUser.contains("JDK 25") && !human.contains("JDK 25")) {
            return ToolCall.of(MemoryTools.APPEND, "label", "human",
                    "content", "User project updated to JDK 25");
        }
        // 规则 2:被问起记忆 → 从 <CORE_MEMORY> 读回,原样回答
        if (lastUser.contains("还记得") || lastUser.contains("记得我") || lastUser.contains("上次说")) {
            return ToolCall.of(MemoryTools.SEND_MESSAGE,
                    "message", human.isBlank() ? "我没有相关记忆。" : "你之前说过:" + human);
        }
        // 规则 3:闲聊 → 复述
        return ToolCall.of(MemoryTools.SEND_MESSAGE, "message", "收到:" + lastUser);
    }
}

这条"读"的动作,就是 RAM 的本质。 真实大模型"读到记忆"靠的是注意力机制看到 prompt 里的 <CORE_MEMORY>;我们的假 LLM 靠 extractBlock 解析同一段文本。殊途同归:记忆必须真的待在上下文里,才能被"读"到。 而"读到之后决定改写它"------这就是自我编辑内存的完整闭环。

4.5 同一个核心,Groovy 版有多短?

Java 版表达"一切显式";Groovy 版抹掉仪式感,闭包即 LLM、map 即参数表。同一个 MockLlm,Groovy 版短了四成:

groovy 复制代码
class MockLlm implements LLM {
    ToolCall respond(String systemPrompt, List<Message> ctx) {
        String lastUser = ctx.reverse().find { it.role == 'user' }?.content ?: ''
        String human = extractBlock(systemPrompt, 'human')
        if (lastUser.contains('JDK 25') && !human.contains('JDK 25')) {
            return new ToolCall(name: MemoryTools.APPEND, args: [label: 'human', content: 'User project updated to JDK 25'])
        }
        if (lastUser.contains('还记得') || lastUser.contains('记得我') || lastUser.contains('上次说')) {
            return new ToolCall(name: MemoryTools.SEND, args: [message: human ? "你之前说过:${human}" : '我没有相关记忆。'])
        }
        new ToolCall(name: MemoryTools.SEND, args: [message: "收到:${lastUser}"])
    }
}

注意 Groovy 版怎么把配置"DSL 化"------一个 map 构造器,一行配完 Agent:

groovy 复制代码
MemGptAgentController agent = new MemGptAgentController(coreMemory: memory, llm: new MockLlm(), contextBudget: 400, memoryThreshold: 120)

同样的四件事:Java 要写 300 行,Groovy 150 行。 这就是为什么工业上爱用动态语言搭框架原型,但生产底座往往回归强类型。

运行清单:

示例 Groovy Java
自我编辑记忆(10 轮) ./run.sh examples/01_memgpt_demo.groovy ./run.sh letta.examples.MemGptDemo
内存换页 + 压力告警 ./run.sh examples/02_memory_pressure.groovy ./run.sh letta.examples.MemoryPressureDemo
断言测试 ./run.sh test/TestMemGpt.groovy ./run.sh letta.test.TestMemGpt

5. 运行验证:看见 Agent 自己修改了它的 System Prompt

跑 Java 版主演示,./run.sh letta.examples.MemGptDemo。下面这段是真实控制台输出

第 1 轮:用户抛出一个新偏好。

ini 复制代码
== MemGptDemo:让 Agent 自己记住你的偏好 ==

───── 初始 System Prompt(human 块是空的)─────
<CORE_MEMORY> 尚未编译

[user] 我最近把项目环境升级到了 JDK 25。

────── 第 1 轮 ──────
  [llm] 决策 → core_memory_append(label=human, content=User project updated to JDK 25)
  [tool] core_memory_append 执行成功
  [memory] OK: 已追加到 memory block [human] → User project updated to JDK 25
  [heartbeat] 记忆已改写,继续下一思考步
  [llm] 决策 → send_message(message=收到:我最近把项目环境升级到了 JDK 25。)
  [assistant] 收到:我最近把项目环境升级到了 JDK 25。

注意那条 [heartbeat]记忆工具执行完,本轮不结束------系统把控制权交回模型,让它再想一步。模型第二次读到的 prompt 已经带上了新记忆,于是它决定对用户说话。

第一轮结束后,System Prompt 被重新编译------human 块里躺着模型自己写进去的那句话:

xml 复制代码
───── 第 1 轮结束后的 System Prompt(记忆被物理改写)─────
你是运行在 MemGPT 操作系统上的 Agent。
下面的 <CORE_MEMORY> 是你的常驻内存(RAM),你可以用 core_memory_append / core_memory_replace 修改它:

<CORE_MEMORY>
  <persona chars_current=16 chars_limit=2000>
    你是忠实记录用户偏好的个人助理。
  </persona>
  <human chars_current=30 chars_limit=2000>
    User project updated to JDK 25
  </human>
</CORE_MEMORY>

human 块的 chars_current 从 0 变成了 30。记忆的写入者不是用户,是模型自己------它调用 core_memory_append,物理改写了自己的内存条。**

第 2~9 轮:普通闲聊,模型每轮只是复述一句,不再重复写记忆。

第 10 轮:灵魂拷问------"还记得吗?"

css 复制代码
[user] 你还记得我上次说的项目环境吗?

────── 第 10 轮 ──────
  [llm] 决策 → send_message(message=你之前说过:User project updated to JDK 25)
  [assistant] 你之前说过:User project updated to JDK 25
  ✅ 第 10 轮:Agent 依然精准记得 JDK 25

没有任何外部数据库。 十轮对话、八个插曲之后,它依然记得------因为那行记忆不是"被存到了某处",而是每一轮都物理待在 System Prompt 里 。这就是"常驻上下文(In-Context)"的全部真相:不是记性好,是没被换出去过。


再看内存压力场景,./run.sh letta.examples.MemoryPressureDemoPart A 是换页: 上下文窗口只有 40 token,消息一多,最老的就 [paging] 压进 Recall Storage:

ini 复制代码
────── 第 3 轮 ──────
  [paging] Working Context 超预算,14t 的最老消息已换页到 Recall Storage(Disk): 第一条闲聊:今天天气不错。
  [system] ⚠ SystemAlert: Memory pressure high 已注入 System Prompt
  [llm] 决策 → send_message(message=收到。)

---- 换页结果 ----
Working Context 里还剩 5 条消息
Recall Storage(Disk)收到 11 条被换页的历史:
    - user: 第一条闲聊:今天天气不错。
    - assistant: 收到。
    ...
    - user: 第六条闲聊:周末约了朋友。

Part B 是"模型读到告警 → 自我压缩": human 块已经 52 字符、逼近 60 的上限。系统注入告警,模型读到后调用 core_memory_replace 把整块压缩成一行:

ini 复制代码
────── 第 1 轮 ──────
  [system] ⚠ SystemAlert: Memory pressure high 已注入 System Prompt
  [llm] 决策 → core_memory_replace(label=human, old_value=用户偏好:咖啡不加糖;喜欢夜间编程;主要用 Java 开发后端;最近在研究 Agent 框架;住在杭州。, new_value=用户:Java 后端工程师,深夜编程,研究 Agent。)
  [tool] core_memory_replace 执行成功
  [memory] OK: 已替换 memory block [human] 中的旧文本
  [heartbeat] 记忆已改写,继续下一思考步
  [llm] 决策 → send_message(message=收到。)

压缩后 System Prompt 里 SystemAlert 消失,human 块从 52 字符压到 35 字符------压力被模型自己排掉了。 这就是"换页 + 自我清洗"的完整演示:操作系统负责盯压力、发信号,模型负责动手清。


6. 小结

6.1 一条 Agent 架构演进的全景图

把这三章叠在一起看,一条清晰的进化线浮出来:

维度 01 · Swarm(ReAct) 02 · LangGraph(FSM) 03 · MemGPT/Letta(OS Memory)
核心抽象 一个 while 循环 + 交接 一张图 + State + reducer 内存分层 + 自我编辑工具
记忆 context_variables 自由字典 State(可落盘快照) Core / Recall / Archival 三级
谁控制循环 模型(tool_calls 图结构 + 条件边 模型(heartbeat)+ 规则
上下文爆了怎么办 无解,硬塞 Checkpointer / 压缩 换页 + SystemAlert 自我清洗
这一章递来的钥匙 循环 确定性 自我演化

一句话串起来:

**Swarm 证明了"循环"是 Agent 的最小骨架;
LangGraph 证明了"控制流"可以是显式的图;
MemGPT 则把目光从"流程"移向"状态"------Agent 最稀缺的资源不是代码,是上下文窗口里那几 KB 内存,而它必须学会自己管理它。**

6.2 真实 Letta 还做了什么

和上篇一样,列一下工业级 Letta 有、而没复刻的东西------如果真要在生产里用 MemGPT,缺的正是这几块

没做的设施 真实 Letta 里是什么 解决什么问题
精确 token 计数 tiktoken 按真实 token 数算窗口 我们的字符近似在长英文上会偏差
Archival 向量检索 记忆进向量库,archival_memory_search 语义召回 长期记忆不能靠字符串匹配
DB 持久化 消息、块、AgentState 全落库,可恢复、可审计 进程一挂,记忆全丢
工具即 docstring derive_openai_json_schema() 从源码注释生成 schema 我们手写了参数表
heartbeat 工具规则 Terminal / Child / RequiredBeforeExit 等规则体系 只靠模型自觉,循环可能失控
Prompt 缓存优化 记忆没变就不重建 System Prompt(diff 后跳过) 每轮重建会打爆 provider 缓存、烧钱

现在三把钥匙已经齐了:

  • 循环(Swarm)------让它能跑;
  • 确定性(LangGraph)------让它不乱跑;
  • 自我演化(MemGPT)------让它越跑越懂你。
相关推荐
伍树明16 分钟前
深入理解大模型Agent:从理论到年报ReAct Agent实战
人工智能
万物智能17 分钟前
OpenHarmony源码树解剖—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端
深入云栈18 分钟前
一文搞懂Netty 4.2六大核心概念:Channel/EventLoop/Selector/ByteBuf 如何关联
java·后端
Csvn19 分钟前
第 7 章 MCP 标准化工具接入
人工智能·aigc·agent
大模型码小白19 分钟前
Spring AI 框架中集成 MCP 的完整指南:从服务端到客户端的全流程实践
大数据·运维·数据库·人工智能·python·sql·spring
武子康21 分钟前
拆开 Pi Monorepo:改模型、循环、产品和 UI 时,代码应该放在哪一层
人工智能·llm·agent
hh95022 分钟前
Agent Plan × DeepSeek Harness:角色 Prompt 驱动的 Agent 分工优化与协作质量实验
java·前端·人工智能·prompt·adg·agent plan·adg成都社区
YHL22 分钟前
🐉 天龙八部 RAG 知识库实战:从零构建你的武侠 AI 助手
数据库·人工智能
阿基拉de_Akir22 分钟前
② 跨层禁止:机器如何拦截非法语义绑定
人工智能