①大模型、Chatbot、Agent,一次把名字理清楚

Claude、Claude Code、ChatGPT、Codex……天天用 AI,却未必分得清这些名字。本篇带你从大模型、Chatbot 和 Agent 的三层关系讲起,理清模型与产品、聊天与执行任务之间的区别,为后续动手构建 Agent 打好基础。

outlier 13 分钟 4918 字 1 0
系列教程Agent从入门到放弃 第 2 / 2 章
  1. 01Agent 从入门到放弃:教程大纲
  2. 02①大模型、Chatbot、Agent,一次把名字理清楚
查看教程目录

开场:一次小型社死现场

前阵子和朋友吃饭,聊到 AI 编程。

朋友问:"你平时用 Claude 还是 Claude Code?"

我说:"Claude 啊。"

朋友又问:"那 Codex 是模型还是工具?跟 GPT-5 什么关系?ChatGPT 又是什么?"

我张了张嘴,发现自己用了两年 AI,居然一个都答不上来。那一刻,筷子上的那块肉都不香了。

后来我仔细研究了一圈,结论是:这事不全怪我,厂商自己就把名字用乱了。 同一个"Claude",有时候指模型,有时候指 App,有时候指命令行工具;"Codex"更离谱,它曾经是一个模型的名字,后来又变成了一个 Agent 产品的名字。

所以这个系列的第一篇,我们不写代码,先做一件看起来很简单、实际上很多人没做过的事:把名字理清楚。 地基不打牢,后面 39 篇越往上盖越歪。

读完本篇,你应该能回答这几个问题:

  • 大模型到底是个什么东西?它能做什么,不能做什么?
  • ChatGPT、Claude App 这类 Chatbot,和背后的模型是什么关系?
  • Agent 和 Chatbot 的本质区别是什么?
  • Claude、Claude Code、Codex、Cursor……这些名字各自属于哪一层?

一、先看全景:三层结构

先上结论。我们日常接触到的 AI 产品,基本可以拆成三层:

flowchart TB subgraph L3["第三层:Agent"] A1["模型 + 循环 + 工具 + 上下文管理
自己决定下一步做什么,直到任务完成"] end subgraph L2["第二层:应用 / Chatbot"] A2["模型 + 界面 + 会话管理 + 系统提示词
你说一句,它回一句"] end subgraph L1["第一层:大模型"] A3["一个无状态的函数
文本进,文本出"] end L3 -->|"建立在"| L2 L2 -->|"建立在"| L1 style L1 fill:#e3f2fd,stroke:#1565c0 style L2 fill:#e8f5e9,stroke:#2e7d32 style L3 fill:#fff3e0,stroke:#e65100

一句话版本:

  • 大模型是发动机;
  • Chatbot 是给发动机装上方向盘和座椅的车,你开一步它走一步;
  • Agent 是装了自动驾驶的车,你告诉它目的地,它自己决定怎么开。

当然,比喻总有不准的地方。下面一层一层拆开看。

二、第一层:大模型,一个无状态的函数

2.1 它的"函数签名"

如果用程序员的视角看,大模型本质上就是一个函数:

// 大模型的"函数签名"(示意)
// 输入:一串 token(可以先粗略理解为"字词片段")
// 输出:下一个 token 的概率分布
func LLM(context []Token) Distribution

它每次只做一件事:根据前面所有的文字,预测下一个字词最可能是什么。 然后把预测出的字词拼回输入,再预测下一个,如此循环,一段话就"吐"出来了。

flowchart LR I["输入:
今天天气"] --> M(("大模型")) M --> P["概率分布:
很 42%
不 25%
真 18%
……"] P --> S["采样选中:很"] S -->|"拼回输入,继续预测"| I2["今天天气很"] I2 --> M

至于 token 是什么、概率是怎么算出来的、为什么同一个问题每次回答不一样,这些我们放到原理篇(第 06 到 08 篇)细讲。这里只需要记住一点:它是一个"文字接龙"高手,而且是一个读过几乎整个互联网的接龙高手。

2.2 最重要的特性:无状态

这是新手最容易误解的地方。大模型本身没有记忆。 每一次调用,它都是一张白纸。

你可能会问:那我在网页上和 ChatGPT 聊天,它明明记得我上一句说了什么啊?

答案是:不是它记得,是应用每次都把聊天记录完整地重新发给它。

我们直接看 API 调用长什么样。假设你和模型聊了两轮,第二轮请求实际发出去的内容是这样的:

{
  "model": "<模型名>",
  "max_tokens": 1024,
  "messages": [
    { "role": "user",      "content": "我叫乔人尹,是个写代码的。" },
    { "role": "assistant", "content": "你好乔人尹!有什么可以帮你的?" },
    { "role": "user",      "content": "我叫什么名字?" }
  ]
}

看到了吗?第一轮的问答被原封不动地塞进了第二轮的请求里。模型之所以能回答"你叫乔人尹",是因为答案就写在它这次收到的输入里。

sequenceDiagram participant U as 你 participant App as 应用 participant M as 大模型 U->>App: 我叫乔人尹 App->>M: [第1句] M-->>App: 你好乔人尹 App-->>U: 你好乔人尹 Note over App: 应用把聊天记录存下来 U->>App: 我叫什么名字? App->>M: [第1句 + 第1句回复 + 第2句] Note over M: 模型看到的是完整历史
而不是"想起来" M-->>App: 你叫乔人尹 App-->>U: 你叫乔人尹

这个认知非常关键,后面整个"上下文工程"篇都建立在它之上:模型知道的一切,都在这次请求的输入里。输入里没有的,它就不知道。

2.3 裸模型能做什么,不能做什么

能做不能做
理解和生成各种语言的文字记住上一次调用的内容
写代码、改代码、解释代码读取你电脑上的文件
推理、总结、翻译、改写上网查资料
按指定格式输出(比如 JSON)执行任何命令
说出"我想调用某个工具"(下一篇细讲)知道现在几点、今天几号

最后一条特别有意思。你直接调 API 问一个裸模型"今天几号",它要么老实说不知道,要么根据训练数据瞎猜一个日期。但你在 Claude 或 ChatGPT 网页上问,它能答对。为什么?答案在下一节。

2.4 常见的模型名字

为了方便后面对号入座,这里列一些常见的模型家族(截至写作时,各家迭代很快,以官网为准):

  • Anthropic:Claude Opus、Claude Sonnet、Claude Haiku,从大到小、从贵到便宜;
  • OpenAI:GPT 系列,以及各种针对特定场景优化的变体;
  • Google:Gemini 系列;
  • 国内:DeepSeek、Qwen(通义千问)、Kimi、GLM 等。

这些名字,指的都是"发动机"本身。

三、第二层:Chatbot,给模型穿上衣服

3.1 应用到底多做了什么

ChatGPT、Claude App、DeepSeek App,这些我们天天打开的聊天界面,就是第二层。它们在模型外面包了一层"衣服":

flowchart LR U["你输入的一句话"] --> APP subgraph APP["应用层"] direction TB SP["系统提示词
你是一个有帮助的助手
今天是某年某月某日
回答要遵守某些规则……"] H["聊天历史"] MEM["记忆
跨会话保存的用户信息"] T["工具定义
搜索、代码执行、读文件……"] F["你上传的文件"] end APP -->|"全部拼成一次请求"| M(("大模型")) M --> R["回复"] R --> UI["界面渲染
Markdown、代码高亮、图表"]

现在可以回答上一节的问题了:网页版能答对"今天几号",是因为应用在系统提示词里偷偷写上了今天的日期。 模型还是那个模型,只是这次它的输入里有了答案。

同理:

  • 网页版"记得"你是谁 → 应用把你的信息存了起来,每次塞进上下文;
  • 网页版能联网 → 应用给模型配了一个搜索工具;
  • 网页版能读 PDF → 应用先把 PDF 解析成文字或图片,再塞进上下文。

3.2 为什么同一个模型,网页版和 API 表现不一样

很多人有过这种体验:网页上聊得好好的,换成 API 调用,感觉模型"变笨了",或者"性格变了"。

模型没变,变的是上下文。网页版有一段精心打磨过的系统提示词,往往很长,告诉模型该用什么语气、该怎么排版、什么时候该用工具;还配了一堆工具。你直接调 API 时,这些统统没有。

这也是为什么同一个模型,套在不同的应用里,体验能差出一大截。应用层的设计,本身就是一门手艺。

3.3 Chatbot 的工作方式

用代码来表达,一个最简单的 Chatbot 大概是这样:

var history []Message

func Chat(userInput string) string {
    history = append(history, Message{Role: "user", Content: userInput})

    // 一问一答,调用一次就结束
    resp := llm.Call(systemPrompt, history)

    history = append(history, resp)
    return resp.Text
}

注意这里的关键特征:你说一句,它调用一次模型,回一句,然后停下来等你。 节奏完全由你掌控。

四、第三层:Agent,给模型一个循环

4.1 Agent 的核心:一个 while 循环

如果说 Chatbot 是"你推一下它动一下",那 Agent 就是"你给个目标,它自己转起来"。

先看代码,你会发现差别其实小得惊人:

func RunAgent(task string) string {
    messages := []Message{{Role: "user", Content: task}}

    for step := 0; step < maxSteps; step++ {
        // 1. 让模型"想":下一步该干什么?
        resp := llm.Call(systemPrompt, tools, messages)
        messages = append(messages, resp)

        // 2. 模型说"我做完了",退出循环
        if resp.StopReason != "tool_use" {
            return resp.Text
        }

        // 3. 模型说"我要用工具",程序替它去执行
        results := executeTools(resp.ToolCalls) // 真正干活的是这一行
        messages = append(messages, results)

        // 4. 带着工具的执行结果,回到第 1 步继续想
    }
    return "步数用完了,放弃。" // 本系列的精神内核
}

和 Chatbot 相比,只多了两样东西:

  1. 一个循环:模型可以连续调用很多次,不用每次都等你开口;
  2. 一组工具:模型可以"要求"读文件、跑命令、查网页,由程序替它执行,再把结果喂回去。

用时序图看会更清楚:

sequenceDiagram participant U as 你 participant H as Harness
(Agent 程序) participant M as 大模型 participant T as 工具
(文件/终端/网络) U->>H: 帮我修复这个项目里失败的测试 loop 直到模型认为任务完成 H->>M: 任务 + 历史 + 工具列表 M-->>H: 我想调用 run_bash("go test ./...") H->>T: 执行 go test T-->>H: 2 个测试失败,报错信息…… H->>M: 把执行结果追加进上下文 M-->>H: 我想调用 read_file("order.go") H->>T: 读文件 T-->>H: 文件内容…… H->>M: 追加结果 M-->>H: 我想调用 edit_file(...) H->>T: 修改文件 T-->>H: 修改成功 end M-->>H: 测试已全部通过,我修改了以下内容…… H-->>U: 最终报告

这里有一个非常重要的认知,后面的文章会反复强调:模型从来不会真正"执行"任何东西。 它只会输出一段话,意思是"我想调用 run_bash,参数是 go test"。真正去执行命令、读文件的,是外面那层程序,业内通常叫它 harness(直译是"挽具",套在模型身上让它能干活的那套东西)。

所谓"AI 自己修好了 bug",其实是这个循环转了几十圈。

4.2 判断标准:谁决定下一步?

那么问题来了:现在的 Claude App 也能搜索、能跑代码,它算 Chatbot 还是 Agent?

答案是:这不是一个非黑即白的分类,而是一条光谱。 判断的关键只有一个问题:下一步做什么,是谁决定的?

flowchart LR A["裸模型
一问一答
没有工具"] --> B["Chatbot + 工具
偶尔调一次搜索
然后回答"] B --> C["Workflow
多步骤,但步骤
由程序员写死"] C --> D["Agent
多步骤,步骤
由模型自己决定"] A -.- N1["自主程度:低"] D -.- N2["自主程度:高"] style A fill:#e3f2fd style B fill:#e8f5e9 style C fill:#fff9c4 style D fill:#fff3e0
  • 裸模型:没有工具,也没有循环,什么都由你决定;
  • Chatbot + 工具:模型能决定"要不要搜一下",但通常一两步就结束,回到你手上;
  • Workflow:可以有很多步,但步骤顺序是程序员提前写死的。比如"先翻译,再总结,再发邮件",模型只负责每一步里的内容;
  • Agent:模型自己决定先做什么、后做什么、什么时候算完成。

所以,现在的 Claude App、ChatGPT 网页版,更准确的说法是"带有轻量 Agent 能力的 Chatbot";而 Claude Code、Codex 则是彻头彻尾的 Agent,一个任务可以自主跑几十上百步。

Workflow 和 Agent 的区别,第 04 篇会专门讲。剧透一下:大部分场景,你其实不需要 Agent。

4.3 Agent 的四个组成部分

把上面的内容收拢一下,一个 Agent 由四部分组成:

flowchart TB AG(("Agent")) AG --- M["大模型
负责思考和决策"] AG --- L["循环
让决策可以连续进行"] AG --- T["工具
让决策能落地成行动"] AG --- C["上下文管理
决定每一轮给模型看什么"] style AG fill:#ffe0b2,stroke:#e65100

前三个好理解,第四个"上下文管理"是最容易被忽视、也最见功力的部分。循环转几十圈之后,上下文里堆满了文件内容和命令输出,很快就会爆掉。哪些该留、哪些该删、哪些该压缩成摘要,这就是 Claude Code 这类产品真正的核心竞争力之一。第三部分的上下文工程篇和第 28 篇会详细展开。

五、对号入座:那些让人头大的名字

现在,终于可以回答开头朋友的问题了。

5.1 "Claude"一词三义

名字属于哪一层说明
Claude Opus / Sonnet / Haiku模型发动机本身,通过 API 调用
Claude(网页 / 桌面 / 手机 App)应用聊天界面,内置搜索、文件、记忆等工具,带轻量 Agent 能力
Claude CodeAgent跑在终端、IDE、桌面端的编码 Agent,底层调用 Claude 模型
Claude Agent SDK造 Agent 的框架把 Claude Code 背后的那套 harness 开放出来,让你造自己的 Agent

所以朋友问"你用 Claude 还是 Claude Code",正确的回答应该是:"网页上聊天用的是 Claude App,写代码用的是 Claude Code,它们背后跑的都是 Claude 的 Sonnet 或 Opus 模型。"

5.2 "Codex"的身世之谜

Codex 这个名字的历史更曲折:

flowchart LR Y1["2021
OpenAI 发布 Codex 模型
专门写代码的 GPT 变体
早期 GitHub Copilot 的发动机"] --> Y2["2023
初代 Codex 模型退役"] Y2 --> Y3["2025
Codex 名字复活
这次是一个编码 Agent 产品
命令行、IDE 插件、云端等形态
底层跑 GPT 系列及其编码优化版"] style Y1 fill:#e3f2fd,stroke:#1565c0 style Y3 fill:#fff3e0,stroke:#e65100

所以:"Codex 是模型还是工具?" 答:2021 年那个是模型,现在说的 Codex 是 Agent,它背后的发动机是 GPT 系列模型。至于有些模型名字里也带着 "codex" 字样,那是针对编码场景优化过的 GPT 变体……好了,我知道你想放弃了,坚持一下。

5.3 一张总表

flowchart LR subgraph Agent层 CC["Claude Code"] CX["Codex"] CU["Cursor Agent 模式"] GH["Copilot Agent 模式"] end subgraph 应用层 CA["Claude App"] CG["ChatGPT"] DA["DeepSeek App"] end subgraph 模型层 CM["Claude 系列"] GM["GPT 系列"] DM["DeepSeek 系列"] OM["Gemini 等其他模型"] end CC --> CM CA --> CM CX --> GM CG --> GM DA --> DM CU --> CM CU --> GM CU --> OM GH --> CM GH --> GM GH --> OM

几个值得注意的点:

  • Cursor、GitHub Copilot 这类工具不绑定模型,你可以在设置里切换背后的发动机。所以"Cursor 好用还是 Claude Code 好用"和"Claude 好用还是 GPT 好用"是两个不同维度的问题;
  • 同一个模型可以装进很多应用,所以"换了个应用"不等于"换了个模型";
  • DeepSeek 是最省事也最费解的一个:公司叫 DeepSeek,App 叫 DeepSeek,模型也叫 DeepSeek。一词三义,全靠上下文。

六、动手:亲手感受三层的区别

光看不练假把式。下面三个小实验,十分钟就能做完,做完之后你对三层的理解会扎实得多。

实验 1:裸调 API,感受"无状态"

准备一个 Anthropic 的 API Key(用 OpenAI 或 DeepSeek 的 API 也一样,格式略有不同),执行:

export MODEL="<填一个当前可用的模型名,以官方文档为准>"

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d "{
    \"model\": \"$MODEL\",
    \"max_tokens\": 256,
    \"messages\": [
      {\"role\": \"user\", \"content\": \"今天几号?我上一句话说了什么?\"}
    ]
  }"

观察:它不知道今天的日期,也不知道"上一句话"是什么。因为这次请求里,确实什么都没有。

然后试试把一段"假的历史"塞进 messages 里,比如伪造一条你说过"我叫张三"的记录,再问它你叫什么。你会发现它对伪造的历史深信不疑。它没有记忆,只有输入。

实验 2:在 Claude App 或 ChatGPT 里问同样的问题

问:"今天几号?"

观察:它能答对。现在你知道原因了:系统提示词里写着呢。

实验 3:在 Claude Code 或 Codex 里给一个模糊任务

找一个你自己的小项目,进入目录,启动 Claude Code 或 Codex,说一句:

看看这个项目是干什么的,然后告诉我怎么运行它。

观察:你只说了一句话,它却自己连续做了很多步:列目录、读 README、读配置文件、可能还会去看构建脚本……最后才给你答案。每一步调用了什么工具,界面上都看得到。

这就是那个 while 循环在转。

七、踩坑记录:五个常见误区

误区 1:"模型记住了我。"
记住你的是应用,不是模型。模型每次都是白纸,是应用把你的信息塞进了上下文。理解这一点之后,你就知道为什么"记忆"有时候会出错、会过时:应用存什么、什么时候塞进去,都是应用的设计决策。

误区 2:"换了个应用就是换了个模型。"
不一定。Cursor 里选 Claude,和 Claude Code 背后跑的可能是同一个模型。体验不同,差别在应用层:系统提示词、工具设计、上下文管理。

误区 3:"Agent 是一种更厉害的模型。"
Agent 不是模型,是一种架构。同一个模型,裸用是模型,套上界面是 Chatbot,再加上循环和工具就是 Agent。

误区 4:"网页版比 API 聪明,或者 API 比网页版聪明。"
模型能力是一样的,差的是上下文和工具。网页版有精心设计的系统提示词和一堆工具,API 默认什么都没有。觉得 API "变笨了",先检查自己给的上下文够不够。

误区 5:"Agent 一定比 Chatbot 好用。"
Agent 更强大,但也更慢、更贵、更不可预测。一个任务转几十圈,每圈都在花钱;转着转着还可能跑偏。问个简单问题,Chatbot 一步到位;只有需要多步探索、而且结果可以验证的任务,Agent 才真正值得。这个话题,第 04 篇和第 39 篇会详细聊。

八、动手作业

把你用过的所有 AI 产品列一张表,标出每个产品:

  1. 属于模型、应用还是 Agent?
  2. 如果是应用或 Agent,它背后跑的是哪个(或哪些)模型?
  3. 它有没有循环?下一步是谁决定的?

列完这张表,你就彻底告别了"Claude 和 Claude Code 傻傻分不清"的阶段。下次再有人在饭桌上问你,你可以从容地放下筷子,给他画一张三层结构图。

一句话总结

大模型是一个无状态的文字接龙函数;Chatbot 是给它加上界面和会话管理,你说一句它回一句;Agent 是再给它加上循环和工具,让它自己决定下一步,直到把事情做完。

flowchart LR M["大模型
会想"] -->|"+ 界面 + 会话管理"| C["Chatbot
会聊"] C -->|"+ 循环 + 工具"| A["Agent
会干活"] style M fill:#e3f2fd,stroke:#1565c0 style C fill:#e8f5e9,stroke:#2e7d32 style A fill:#fff3e0,stroke:#e65100

评论

还没有评论,来说点什么吧。

发表评论

Ctrl + Enter 快速提交
Enter 搜索Esc 关闭