摘要:大语言模型(LLM)本质上是一个“无状态”的概率预测函数,每一次 API 调用完成后,模型就会彻底清空上下文,不保留任何记忆。然而在 ChatGPT、Claude 或 DeepSeek 中,我们却能与 AI 进行数十轮流畅的对话,AI 还能清晰记得第一轮提到的个人偏好。

AI 是如何做到“不失忆”的?答案是:大模型本身没有记忆,是外部软件工程架构赋予了它记忆的“幻觉”

本文将从大模型的“无状态”本质切入,系统拆解多轮对话记忆的五大工程演进范式(全量拼接、滑动窗口、摘要压缩、向量检索记忆、MemGPT/Letta 分层存储架构),结合 Prompt Caching 优化与意图重写机制,并提供一套生产级的 Python 对话记忆管理器代码实战,帮助开发者彻底攻克多轮对话中的上下文管理难题。

前言:一个充满戏剧性的工程“假象”

在刚接触大模型开发时,许多开发者都会被一个现象所“欺骗”:

你在 Web 界面上对 AI 说:“我叫小明,是一名 Python 工程师。”

过了 20 轮对话后,你问 AI:“我叫什么名字?我擅长什么语言?”

AI 毫不犹豫地回答:“你叫小明,擅长 Python。”

这看起来就像 AI 拥有一个能够持续学习和记录的“大脑”。然而,从底层技术事实来看,大语言模型(LLM)本身是绝对“无状态(Stateless)”的

当请求结束、Token 生成完毕的那一瞬间,部署在 GPU 显存中的模型权重不会发生任何改变,上一次推理生成的中间变量也会被立即清空。下一次调用 API 时,大模型对你依然一无所知。

那么,多轮对话中那无缝衔接的上下文记忆,到底是从哪里来的?

知名 AI 专家 Andrej Karpathy 给过一个非常精准的类比

  • LLM 模型权重(Weights):相当于计算机的 ROM(只读存储器),在训练完成后就固定不变。

  • 上下文窗口(Context Window):相当于计算机的 RAM(内存/工作记忆),决定了模型此刻能同时推理处理的数据上限。

  • 外部存储(向量库/数据库/历史日志):相当于计算机的 Disk(硬盘),用于持久化存储所有历史对话。

所谓的“多轮对话记忆”,并不是改变了大模型的权重,而是外部工程系统在每一次发起请求时,将历史对话记录从“硬盘”拉取出来,经过精心清洗、压缩与组装后,重新填满大模型的“内存”(Context Window),并再次喂给大模型

一、 为什么大模型本质上是没有记忆的?

要搞懂如何构建记忆系统,首先需要理解大模型的推理机制与“工作内存”的物理边界。

1.1 函数映射机制:无状态的概率推理

从数学与代码的角度来看,大模型可以简化为一个纯粹的函数:

Output_Tokens = Model_Inference(Input_Tokens, Model_Weights)

在这个公式中:

  1. Model_Weights(模型权重)是固定的数值矩阵。

  2. Input_Tokens(输入的提示词)是唯一的变量。

  3. Output_Tokens(生成的回答)完全由输入的 Token 序列与权重决定。

每次调用 API(例如执行一次 chat.completions.create),服务器都是在独立的容器或显存块中运行该函数。推理结束后,中间生成的 KV Cache(键值缓存)会被销毁或释放。大模型没有任何原生的全局变量或数据库来记录“上一次谁和我说话”

[第一轮对话]
用户发送: "我叫小明" 
  ───> [LLM 推理] ───> 产生回答: "你好,小明!"
  ───> (显存清空,对话状态消失)

[第二轮对话 - 如果直接只发送新问题]
用户发送: "我叫什么?" 
  ───> [LLM 推理] ───> 产生回答: "抱歉,我不知道你的名字。" (因为输入里没有任何关于小明的信息)

1.2 上下文窗口(Context Window)与“中间丢失”困境

既然记忆完全依赖于每次请求时传入的 Input_Tokens,那么只要把所有历史对话记录全塞进 Input_Tokens 不就行了吗?

在早期(如 GPT-3.5 时代,上下文窗口仅 4K Tokens),这种做法很快就会触顶报错。虽然如今模型的上下文窗口已经扩展到 128K、1M 乃至更长,但盲目塞入全量历史文本会带来三大致命问题

  1. 费用爆炸:大模型 API 是按照输入 Token 数量计费的。如果在第 50 轮对话时把前 49 轮几万字的文本全部重新发一遍,单次调用的成本将暴涨数十倍。

  2. 推理延迟(TTFT)激增:首字延迟(Time To First Token)与输入的 Token 长度成正比,过长的上下文会导致用户等待白屏时间过长。

  3. “中间丢失”现象(Lost in the Middle):研究与实践表明,基于 Transformer 架构的模型(尤其是受旋转位置编码 RoPE 衰减影响)对上下文头部(开头)尾部(最新对话)的信息关注度最高,而存放在中间位置的历史细节极容易被模型“忽视”。

因此,多轮对话记忆工程的核心,就是在有限且昂贵的上下文窗口中,用最低的 Token 成本,保留最关键的语义上下文

二、 多轮对话记忆的五大工程演进范式

在真实的工业级 AI 应用(如 LangChain、LlamaIndex、Dify、Mem0)中,多轮对话的记忆管理经历了从简单粗暴到复杂精细的架构演进。

                         ┌─────────────────────────────────────────┐
                         │       多轮对话记忆架构演进路线           │
                         └────────────────────┬────────────────────┘
                                              │
       ┌──────────────────────┬───────────────┴──────────────┬──────────────────────┐
       ▼                      ▼                              ▼                      ▼
┌──────────────┐       ┌──────────────┐               ┌──────────────┐       ┌──────────────┐
│  全量历史拼接 │       │   滑动窗口   │               │   摘要压缩   │       │ 向量/图谱检索│
│ Full History │       │Sliding Window│               │ Summarization│       │Vector / Graph│
└──────────────┘       └──────────────┘               └──────────────┘       └──────────────┘
                                                                                    │
                                                                                    ▼
                                                                             ┌──────────────┐
                                                                             │  分层虚拟存储 │
                                                                             │MemGPT / Letta│
                                                                             └──────────────┘

2.1 范式一:全量历史拼接(Full History Buffer)

这是最基础的记忆实现方式。客户端或后端系统建立一个数组,记录每一次的交互:

messages = [
    {"role": "system", "content": "你是一个助手。"},
    {"role": "user", "content": "我叫小明。"},
    {"role": "assistant", "content": "你好小明!"},
    {"role": "user", "content": "我喜欢吃苹果。"},
    {"role": "assistant", "content": "记住啦,你喜欢吃苹果。"}
]

在发起第 3 轮提问时,程序将整个 messages 数组打包发送给大模型。

  • 优点:代码实现极简,信息零丢失,能完美保留每一轮的细节与语气。

  • 缺点:Token 消耗随对话轮数成线性(甚至二次方)增长;一旦超过模型的上下文上限,程序直接抛出异常崩溃。

  • 适用场景:交互轮数极少(< 5 轮)的简单任务或测试 Demo。

2.2 范式二:滑动窗口(Sliding Window Buffer)

为了防止 Token 爆炸,工程师引入了固定大小的“滑动窗口”策略——只保留最新的 N 轮对话,丢弃较早的历史记录

原始对话历史: [Turn 1] [Turn 2] [Turn 3] [Turn 4] [Turn 5] [Turn 6]
                          │<───────── 设定窗口大小 K = 4 ─────────>│
发送给 LLM:                [Turn 3] [Turn 4] [Turn 5] [Turn 6]
  • 实现策略:可以基于对话轮数(Message Count),也可以基于Token 阈值(Token Budget)(例如限制历史记录最多占用 2000 Tokens)。

  • 优点:成本可控,请求延迟稳定,永远能精准捕捉用户最新的意图。

  • 缺点:存在典型的“硬性断崖式遗忘”。如果用户在第 1 轮说了“我对花生过敏”,而第 10 轮系统滑动窗口挤掉了第 1 轮,AI 就会在推荐菜谱时给出包含花生的食品,造成严重事故。

2.3 范式三:摘要递归压缩(Conversation Summary Memory)

为了兼顾“长久记忆”与“低 Token 消耗”,摘要压缩范式应运而生。

工作原理:当历史对话累积到一定长度(如触发阈值)时,后台异步调用一个轻量级大模型(如 GPT-4o-mini 或 Qwen-7B),将较早的对话压缩成一段高度精炼的“历史摘要(Summary)”,再将这份摘要作为背景信息拼接到 Prompt 中。

[系统请求 Prompt 组装结构]

┌─────────────────────────────────────────────────────────┐
│ System Prompt: 你是一个专业助手。                        │
├─────────────────────────────────────────────────────────┤
│ Summary (历史摘要):                                     │
│ 用户叫小明,对花生严重过敏。之前讨论了关于 Python 的学习路线│
├─────────────────────────────────────────────────────────┤
│ Recent Messages (最新窗口对话):                         │
│ User: 那你推荐我晚饭吃什么?                             │
└─────────────────────────────────────────────────────────┘

更新逻辑:每次触发压缩时,采用增量递归摘要(Incremental Summarization)

新摘要 = LLM_Summarize(旧摘要, 被挤出滑动窗口的新对话)

  • 优点:大幅节省 Token,理论上支持无限轮数的长期对话。

  • 缺点

    • 信息抽象损耗:摘要过程必然伴随着细节的丢失(例如压缩模型可能记录了“用户讨论了订单问题”,但删掉了具体的“订单号 883921”)。

    • 复合误差(Compounding Errors):对摘要进行二次摘要(Summary of Summary),经历 5~10 次迭代后,原始信息可能发生严重的语义漂移。

2.4 范式四:语义检索与向量记忆(Semantic / Vector Memory)

在伴侣型 AI、个人数字分身或复杂的长流程 Agent 场景中,仅靠摘要是不够的。我们需要像人类大脑的“情节记忆(Episodic Memory)”一样,实现按需提取(Recall on Demand)

工作原理

  1. 持久化存储:每一轮对话(或按段落提取出的实体和事实)都被转换为向量(Embedding),存储在外部向量数据库(如 Qdrant、Milvus、Mem0)或图数据库中。

  2. 意图匹配与检索:当用户提出新问题时,系统不直接把全部历史塞给大模型,而是先用当前问题在向量库中查找语义最相关的几条历史记录。

  3. 动态注入:将检索出来的历史片段嵌入到当前的 Prompt 中。

用户提问: "我上个月提到的那本关于心理学的书叫什么来着?"
  │
  ▼
[向量数据库检索] ──> 命中第 42 轮历史记录: "用户提到最近在读《被讨厌的勇气》"
  │
  ▼
[组装最终 Prompt]:
System: 基于以下拉取到的记忆回答用户。
Memory: [第 42 轮]: 用户正在阅读《被讨厌的勇气》。
User: 我上个月提到的那本关于心理学的书叫什么来着?
  │
  ▼
LLM 回答: "你上个月提到的心理学书籍是《被讨厌的勇气》。"
  • 优点:突破上下文窗口限制,精准唤醒很久以前的特定细节,Token 占用极低。

  • 缺点:增加了向量检索的开销,且非常依赖检索算法的准确率(如果检索没命中,AI 依然会回答“不记得”)。

2.5 范式五:操作系统级分层记忆架构(MemGPT / Letta 模式)

2023 年底,UC 伯克利团队提出了著名的 MemGPT(现演进为 Letta 框架),将操作系统(OS)的虚拟内存管理(Virtual Memory Management)理念引入到了大模型记忆架构中。

┌─────────────────────────────────────────────────────────┐
│              MemGPT / Letta 分层记忆架构                │
├─────────────────────────────────────────────────────────┤
│                                                         │
│   ┌─────────────────────────────────────────────────┐   │
│   │ 工作内存 (Working Context / RAM) - 有限可读写   │   │
│   │  - Core Memory: 存储用户信息、角色设定 (随时修改)│   │
│   │  - FIFO Queue: 最近发生的对话队列               │   │
│   └────────────────────────┬────────────────────────┘   │
│                            │                            │
│                     通过 Function Calling               │
│                     自主决定读写/换入换出                │
│                            │                            │
│   ┌────────────────────────▼────────────────────────┐   │
│   │ 外部存储 (Archival & Recall Memory / Disk)      │   │
│   │  - Recall Memory: 全量历史对话日志              │   │
│   │  - Archival Memory: 大规模海量知识库与事实片段   │   │
│   └─────────────────────────────────────────────────┘   │
│                                                         │
└─────────────────────────────────────────────────────────┘

核心突破将记忆的管理权彻底交还给 LLM 自己

在 MemGPT 架构中,大模型不仅仅是被动接收文本,系统为其提供了专门的工具函数(Function Calling):

  • core_memory_append:大模型发现用户提到了关键信息(如“我改名叫张伟了”),自主调用函数更新 Core Memory。

  • archival_memory_insert:将不常用但重要的信息写入硬盘存储。

  • archival_memory_search:当大模型发现当前信息不够时,自己发起搜索查询外部记忆。

这种架构让 AI 具备了像人类一样主动记录、主动修改、主动检索的真正“长期记忆能力”。

三、 现代大模型记忆系统的两大工程利器

除了上述记忆选择与压缩范式外,现代生产级 AI 系统能做到低延迟、低成本的多轮对话,还依赖于以下两大关键工程技术:

3.1 Prompt Caching(提示词缓存):拯救成本与延迟

在 2024~2026 年的生产实践中,各大模型 API 供应商(如 OpenAI、Anthropic、DeepSeek、火山引擎)纷纷推出了 Prompt Caching(提示词缓存) 机制。

为什么 Prompt Caching 是多轮对话的救星?

在多轮对话中,每一次请求发送给大模型的 Prompt 头部(如复杂的 System Prompt、角色设定、前 20 轮相同的对话历史)几乎是完全重合的。

请求 1: [System Prompt] [Turn 1] [Turn 2] -> 生成 Turn 2 Answer
请求 2: [System Prompt] [Turn 1] [Turn 2] [Turn 3] -> 生成 Turn 3 Answer
        └───────────────────────────────┘
                     完全相同的前缀!
  • 传统模式:服务端每次都要对前缀文本重新执行昂贵的 Matrix 计算与 Prefill 过程。

  • Prompt Caching 模式:大模型服务端自动识别并缓存重复前缀的 KV Cache(键值缓存)。当请求命中缓存时:

    • 价格降低 50% ~ 90%

    • 首字延迟(TTFT)降低 80% 以上

针对 Prompt Caching 的工程设计原则

为了确保多轮对话能够稳定命中服务端缓存,客户端在组装 Prompt 时必须遵循 “静态内容在前,动态内容在后” 的原则:

[最佳 Prompt 结构,保障最高 Cache 命中率]

1. [静态] 复杂的 System Prompt (固定不变)
2. [静态] 业务知识库 / 角色定义 (固定不变)
3. [准静态] 按照时间顺序排列的历史对话 (前缀保持不变,尾部追加)
4. [动态] 用户当前刚刚发送的新问题 (放在最末尾)

3.2 意图重写与指代消解(Query Rewriting)

多轮对话中存在一个极高频的痛点:用户的输入往往包含大量的代词和省略语

  • 第 1 轮:用户:“请问特斯拉 Model Y 多少钱?” -> AI:“Model Y 售价约为 25 万元起。”

  • 第 2 轮:用户:“它的续航是多少?”

  • 第 3 轮:用户:“那和 Model 3 相比呢?”

如果系统直接将第 2 轮用户的原话“它的续航是多少?”发送给外部向量库或 RAG 检索器,检索系统会完全懵圈——“它”到底是谁?

解决方案:大模型前置 Query 重写(Query Reframing)

在进入记忆检索或知识库前,系统先调用一个极快的轻量级模型,结合历史上下文将用户带指代的问题重写为一个独立的、语义完整的问题

[原始对话历史] + 用户输入: "它的续航是多少?"
       │
       ▼
[轻量重写模块 (Query Rewriter)]
       │
       ▼
[重写后的独立问题]: "特斯拉 Model Y 的续航里程是多少?"
       │
       ▼
再拿这个独立问题去检索向量库 / 匹配记忆

四、 生产级多轮对话记忆管理器代码实战

下面提供一份基于 Python 的生产级多轮对话记忆管理器(Memory Manager)完整实现。

该模块整合了:

  1. Tiktoken 准确 Token 统计

  2. 滑动窗口与 Token 预算控制

  3. 异步增量摘要压缩

  4. 针对 Prompt Caching 优化的消息队列输出

Python 代码实现

import asyncio
import logging
from typing import List, Dict, Any, Optional
import tiktoken
from openai import AsyncOpenAI

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger("MemoryManager")

class ProductionMemoryManager:
    def __init__(
        self,
        system_prompt: str,
        max_total_tokens: int = 4000,
        summary_trigger_tokens: int = 2500,
        model_name: str = "gpt-4o-mini"
    ):
        self.system_prompt = system_prompt
        self.max_total_tokens = max_total_tokens
        self.summary_trigger_tokens = summary_trigger_tokens
        self.model_name = model_name
        
        # 初始化 Tokenizer
        try:
            self.encoder = tiktoken.encoding_for_model(model_name)
        except KeyError:
            self.encoder = tiktoken.get_encoding("cl100k_base")

        # 内部状态存储
        self.summary: str = ""  # 当前历史摘要
        self.recent_messages: List[Dict[str, str]] = []  # 最近的对话消息队列
        
        # OpenAI 异步客户端(用于生成摘要)
        self.client = AsyncOpenAI()

    def _count_tokens(self, text: str) -> int:
        """精确计算文本的 Token 数量"""
        if not text:
            return 0
        return len(self.encoder.encode(text))

    def _count_message_tokens(self, message: Dict[str, str]) -> int:
        """计算单条 Message 占用的 Token 数(包含元数据开销)"""
        # 每条消息包含 role, content,元数据额外消耗约 4 个 Token
        return self._count_tokens(message.get("content", "")) + 4

    def add_user_message(self, content: str):
        """添加用户消息"""
        self.recent_messages.append({"role": "user", "content": content})

    def add_assistant_message(self, content: str):
        """添加 AI 助手消息"""
        self.recent_messages.append({"role": "assistant", "content": content})

    def get_total_token_usage(self) -> int:
        """计算当前完整上下文的总 Token 消耗"""
        tokens = self._count_tokens(self.system_prompt) + 10
        if self.summary:
            tokens += self._count_tokens(self.summary) + 10
        for msg in self.recent_messages:
            tokens += self._count_message_tokens(msg)
        return tokens

    async def _generate_summary_async(self, old_summary: str, messages_to_summarize: List[Dict[str, str]]) -> str:
        """调用轻量级模型异步增量生成摘要"""
        conversation_text = ""
        for msg in messages_to_summarize:
            conversation_text += f"{msg['role']}: {msg['content']}\n"

        prompt = f"""你是一个高效的对话上下文压缩助手。请根据【旧摘要】与【新对话记录】,更新并输出一份高度精炼的【新摘要】。

【旧摘要】:
{old_summary if old_summary else "无"}

【新增对话记录】:
{conversation_text}

【要求】:
1. 保持客观,用第三人称记录。
2. 严格保留核心事实信息(如:用户姓名、偏好、提出的具体需求、关键数字/单号)。
3. 剔除无意义的寒暄与客套话。
4. 控制输出在 200 字以内。

输出新摘要:"""

        try:
            response = await self.client.chat.completions.create(
                model=self.model_name,
                messages=[{"role": "user", "content": prompt}],
                temperature=0.1,
                max_tokens=300
            )
            new_summary = response.choices[0].message.content.strip()
            logger.info(f"成功更新对话摘要: {new_summary}")
            return new_summary
        except Exception as e:
            logger.error(f"摘要生成失败: {e}")
            return old_summary

    async def optimize_memory_if_needed(self):
        """检查并执行动态记忆裁剪与摘要压缩"""
        current_tokens = self.get_total_token_usage()
        
        # 如果当前 Token 消耗未达到阈值,无需触发优化
        if current_tokens < self.summary_trigger_tokens or len(self.recent_messages) <= 2:
            return

        logger.info(f"当前 Token 数 ({current_tokens}) 触发摘要阈值 ({self.summary_trigger_tokens}),开始优化记忆...")

        # 取出最旧的一半消息进行摘要压缩,留出最新的消息
        num_to_summarize = len(self.recent_messages) // 2
        messages_to_summarize = self.recent_messages[:num_to_summarize]
        self.recent_messages = self.recent_messages[num_to_summarize:]

        # 异步更新摘要
        self.summary = await self._generate_summary_async(self.summary, messages_to_summarize)

    def get_messages_for_llm(self) -> List[Dict[str, str]]:
        """
        组装最终发送给大模型的完整消息队列
        遵循“静态前缀在前,动态内容在后”原则,最大化缓存命中率
        """
        payload = []

        # 1. 静态 System Prompt
        payload.append({"role": "system", "content": self.system_prompt})

        # 2. 动态生成的历史摘要(若存在)
        if self.summary:
            payload.append({
                "role": "system", 
                "content": f"【此前对话的背景历史摘要】: {self.summary}"
            })

        # 3. 最新窗口的自然对话列表
        payload.extend(self.recent_messages)

        return payload


# ==================== 运行测试 ====================
async def main():
    # 初始化记忆管理器,设置较小的阈值以便触发摘要测试
    memory = ProductionMemoryManager(
        system_prompt="你是一位专业、贴心的理财顾问助手。",
        max_total_tokens=1000,
        summary_trigger_tokens=200,  # 降低阈值方便演示
        model_name="gpt-4o-mini"
    )

    # 模拟多轮密集对话
    print("--- 第一轮对话 ---")
    memory.add_user_message("你好,我叫张伟,今年 32 岁,准备投资 50 万元。")
    memory.add_assistant_message("你好张伟!很高兴为你服务。请问你的投资偏好是稳健型还是激进型?")

    print("--- 第二轮对话 ---")
    memory.add_user_message("我偏向稳健型,希望每年收益率在 5% 左右,千万不能亏损本金。另外我有两个孩子。")
    memory.add_assistant_message("明白了,针对有两个孩子的家庭且追求保本的需求,建议建立稳健的债基与定期理财组合。")

    print(f"当前总 Token 消耗: {memory.get_total_token_usage()}")

    # 触发检查与自动优化
    await memory.optimize_memory_if_needed()

    print("\n--- 优化后拼装给大模型的最终 Payload ---")
    final_payload = memory.get_messages_for_llm()
    for idx, msg in enumerate(final_payload):
        print(f"[{idx}] {msg['role'].upper()}: {msg['content']}")

if __name__ == "__main__":
    # 真实运行前需配置 OPENAI_API_KEY 环境变量
    asyncio.run(main())

五、 不同业务场景下的记忆架构选型矩阵

在企业级 AI 产品落地时,绝不能“一刀切”地使用某种单一架构。应该根据业务场景的对话轮数、容错率与预算进行精准选型:

业务场景类型 典型代表 最佳记忆架构组合 选型核心理由
任务型客服 / 简单 FAQ 快递查询、机票退改签 滑动窗口 + 意图重写 (Query Rewrite) 对话轮数通常少于 10 轮,注重时效与低延迟,无需长期记忆。
编程助手 / IDE Plugin GitHub Copilot, Cursor 系统 Prompt 固定 + 文件 AST 上下文 + 局部滑动窗口 代码依赖极为精准,不能接受摘要抽取的细节损耗,必须保留精准代码行。
伴侣型 AI / 角色扮演 Character.ai, 虚拟恋人 向量语义检索 (Mem0) + 动态知识图谱 + 增量摘要 对话可能持续几个月甚至数年,极度依赖对用户习惯、纪念日等细节的“闪回唤醒”。
自主 Agent 智能体 AutoGPT, Devin, 自动化运维 MemGPT / Letta 分层架构 (系统自主 Function 读写) 任务链条极长,Agent 需要自主规划并清空短期缓存,将中间运行结果持久化存储。

六、 总结与未来展望

回到本文开头的那个悖论:大模型本身没有记忆,为何能够聊得热火朝天?

答案是:大模型负责“思考”,而软件工程架构负责“记忆”

作为一个 AI 开发者,理解大模型的无状态本质是迈向高级架构师的必经之路:

  1. 不要寄希望于模型权重去记住用户的上下文,每一次对话都是一次全新的函数调用。

  2. 记忆管理的本质,是在 Token 预算、推理成本、首字延迟与语义完整性之间寻找完美平衡

  3. 从简单的滑动窗口,演进到增量摘要向量检索,再到Prompt Caching 缓存优化以及 MemGPT 分层记忆,外部架构的不断进化正一步步将大模型从一个“无状态的文本计算器”,打造成为真正具备持久记忆能力的“数字智能体”。

在未来,随着原生支持百万级超长上下文且 KV Cache 成本极低的新一代模型普及,记忆管理的形态还将继续进化,但“利用软件工程补充模型物理极限”的核心哲学,将始终贯穿 AI 系统设计的始终。

更多推荐