← 文章 / AI技术
龙虾哥AI工程化实战 1小时前 · 2026-09-09 22:41:40 · 2 阅读

小白转行AI大模型系列(四)让大模型记住你是谁——多轮对话的记忆真相

大家好,我是龙虾哥。

上一课我们让 Qwen 开口说话了。但如果你真去试一下,会发现一个尴尬的事:

你:"我叫小明"
模型:"你好小明!"
你:"我叫什么?"
模型:"抱歉,我不知道您的名字……"

居然和我们平时用的大模型APP不一样!这一课我们就聊透这件事,然后手写一个能记住你是谁的终端聊天机器人。

先捅破窗户纸:大模型根本没有记忆

这是本课最重要的一个认知,先说结论:

模型本身是无状态的。所谓"记忆",全是客户端在维护一份聊天历史,每轮把历史全部重新发一遍。

还是以上面的对话为例,当你问豆包"我叫什么?"的时候,模型的输入实际是:

[

  {"role": "user",      "content": "我叫小明"},

  {"role": "assistant", "content": "你好小明!"},

  {"role": "user",      "content": "我叫什么?"},

]

模型每次都是"从零开始读完所有历史",然后接着写下一句。它不是记得你说过什么,而是每次都重新"复习"了一遍你们聊过的全部内容——像极了考试前通宵背书的学生。

理解了这个,你就理解了三件事:

  1.    为什么聊得越久响应越慢、越费钱?——历史记录越来越长,每轮都全量重发,token 数蹭蹭涨
  2.    为什么 ChatGPT 上下文有长度限制?——历史记录塞不下就记不住,上下文长度就是"记忆容量"
  3.    为什么多轮对话要做"历史裁剪"?——不能无限塞,要主动压缩、遗忘

手写一个 LLM SDK:所有实验的基石

直接裸调 API 太啰嗦,我们先把调用逻辑封装成一个类(src/llm_client.py),后面 RAG、Agent的实验全都复用它:

from openai import OpenAI
class LLMClient:

    def __init__(self, base_url="http://localhost:8000/v1", model="qwen2.5-7b"):

        self.client = OpenAI(base_url=base_url, api_key="EMPTY")

        self.model = model
    def chat(self, messages, temperature=0.7, max_tokens=512):

        """非流式调用,一次性返回完整回复"""

        resp = self.client.chat.completions.create(

            model=self.model,

            messages=messages,

            temperature=temperature,

            max_tokens=max_tokens,

        )
        return resp.choices[0].message.content

    def stream(self, messages, temperature=0.7, max_tokens=512):

        """流式调用,逐字生成(yield 生成器)"""

        resp = self.client.chat.completions.create(

            model=self.model,

            messages=messages,

            temperature=temperature,

            max_tokens=max_tokens,

            stream=True,

        )

        for chunk in resp:

            if chunk.choices[0].delta.content:

                yield chunk.choices[0].delta.content

两个方法,chat 一次性返回,stream 逐字往外吐——你在 ChatGPT 里看到的那种"打字机效果",就是这么实现的。顺带说一句,temperature 你先理解成"模型的发挥风格":数值高敢编敢浪,数值低稳重求实,具体原理后面推理优化课细讲。

多轮对话:核心就一个 while 循环

有了 SDK,聊天机器人本体就 30 行(src/terminal_chat.py):

from llm_client import LLMClient

class TerminalChat:
    def __init__(self):
        self.llm = LLMClient()

# messages 是整个多轮对话的"记忆核心"
        self.messages = []
    def add_system_prompt(self, prompt):

        """设定角色(对应 Prompt 工程练习)"""

        self.messages.append({"role": "system", "content": prompt})

    def run(self):
        print("终端多轮对话已启动(输入 quit 退出)")
        while True:
            user_input = input("\n你: ")
            if user_input.lower() == "quit":
                break
# 1. 将用户问题加入历史

            self.messages.append({"role": "user", "content": user_input})
# 2. 流式获取回复
            print("助手: ", end="", flush=True)
            full_response = ""
            for chunk in self.llm.stream(self.messages):
                print(chunk, end="", flush=True)
                full_response += chunk

            print()

# 3. 将模型回复加入历史(关键步骤!)

            self.messages.append({"role": "assistant", "content": full_response})

if __name__ == "__main__":
    bot = TerminalChat()
    bot.run()

跑起来测一下(记得先把上一课的 vLLM 服务开着):

你: 我叫小明,我喜欢吃苹果

助手: 小明你好!苹果是个不错的选择……

你: 我喜欢吃什么水果?

助手: 你喜欢吃苹果。

你: 我叫什么名字?

助手: 你叫小明。

记忆验证通过。整个机制的灵魂就在注释里标的那三步 append:用户的话进历史 → 发全文给模型 → 模型的回复也进历史。

这里大家最容易漏的是第 3 步。有同学可能发现了:不把模型的回复 append 进去行不行?行,程序不报错,但模型就"忘了"自己说过什么——你问"你刚才说什么",它会一脸懵。因为它看到的剧本里,压根没有自己上一句台词。对话剧本要双方台词都记,少一边都不行。

玩点进阶的:Prompt 工程三连

同一个模型,提示词一改,表现判若两模。留三个练习给大家(都在实验手册里):

1,角色设定:取消 add_system_prompt 那行的注释,改成"你是一位资深 Python 架构师,回答要简洁专业",重启对比回答风格——system prompt 是给模型的"人设说明书"

2,结构化输出:直接输入"请用 JSON 格式介绍你自己,包含 name 和 version 字段",看它能不能吐出合法 JSON——这是所有 Agent 和系统对接的基础

3,Few-shot 引导:输入"翻译成英文:\n猫 -> cat\n狗 -> dog\n苹果 -> ",不用任何解释,模型会照着前两个例子自动补全——给例子比讲道理管用,这是 Prompt 工程的第一定律

小结 + 下集预告

这一课你收获三件事:

  1.    大模型没有记忆——所谓多轮对话,就是客户端维护 messages 列表,每轮全量重发
  2.    三步 append 循环:用户进历史 → 发全文 → 模型回复也进历史,一步都不能少
  3.    Prompt 三连:人设、结构化、few-shot,同一模型三种人格

但也留了一个新问题:靠塞历史实现的记忆,容量永远装不下一个公司的全部资料。假如我要做一个"只回答公司内部资料"的助手呢?把 10 万字文档塞进上下文?token 账单会教你做人。

下一课上真正的杀手锏:RAG——给大模型外挂一个大脑。先检索、再回答,资料不全就老实承认,这是我们课程里第一个"企业级"技术。

模型会记事了,接下来教它查资料。关注龙虾哥,别掉队,评论区见。


本课配套开源仓(全部实验代码 + 操作手册,免费拿走):

  • GitCode:https://gitcode.com/LXG_AI/LXG_LLM_INFER_COURSE

评论 (0)