A01第 1 / 1 课时未开始内容版本 1.0.0 · 核验于 2026-10-26

模型与应用的关系

模型与应用的关系 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。

学习目标

读完本课,你能画出一次 AI 聊天请求从界面到模型的完整链路,说清每一环在做什么;并能回答一个关键问题:模型的回答和普通函数的返回值,差别到底在哪。

问题场景

在聊天产品里问「37 × 89 等于多少」,它答 3293,对了。换个问法再问一次,又对了。你以为这是个计算器。直到某天它答了 3283——而你的 JS 里 37 * 89 永远是 3293。同一个问题,为什么计算器从不出错,模型却会?

核心解释

一次聊天请求要经过三层,各干各的活:

浏览器界面            应用服务端                    模型服务
┌───────────┐       ┌────────────────────┐       ┌───────────┐
│ 收集输入    │ POST  │ 校验参数、鉴权       │ POST  │ 读取上下文  │
│ 渲染消息流  │ ────→ │ 组装上下文、持密钥    │ ────→ │ 逐段生成    │
│ 渲染错误态  │ ←──── │ 保存记录、转发增量    │ ←──── │ 返回文本    │
└───────────┘       └────────────────────┘       └───────────┘
  • 界面只负责收集输入和展示结果,不碰密钥、不做业务判断(N05 讲过这条服务端边界)。
  • 应用服务端是一切软件工程发生的地方:校验、鉴权、组装上下文、存数据库、控制预算。本站的 app/api/ai/chat/route.ts 就是这一层。
  • 模型服务只做一件事:根据输入的文本序列,生成下一段文本。

关键区别在最后一环。程序执行是确定的:1 + 1 在任何机器上都是 2,同样输入永远同样输出,可以直接写进 if 分支。模型生成是概率性的:它在预测「接下来最可能出现什么内容」,同一个问题两次回答可能措辞不同、结论不同,甚至算错数。

所以工程上的铁律是:模型的输出是「待核验的文本」,不是「函数返回值」。可以展示给用户、可以存进历史,但拿它做程序决策(入库、扣款、执行命令)之前,必须先经过你自己代码的校验——A09 课专门讲怎么校验。

示例拆解

用同一个问题对比两种路径:

// 路径一:普通函数——确定性执行
function multiply(a: number, b: number): number {
  return a * b; // 37 * 89 永远是 3293
}

// 路径二:调用模型——生成一段文本
async function askModel(question: string): Promise<string> {
  const res = await fetch("/api/ai/chat", {
    method: "POST",
    body: JSON.stringify({ message: question }),
  });
  // 返回的是文本,不是数值:它可能对,也可能错
  return res.text();
}

要点:

  • multiply 的结果可以放心参与运算;askModel 的结果连「是不是数字」都不保证。
  • 业务需要准确计算时,正确做法是让程序算,或者让模型调用你提供的计算工具(A15 课展开),而不是指望模型心算。
  • 本站助手也遵循这个原则:模型文本原样渲染,但「引用了哪些课程」这类结构化信息走单独的 refs 事件,由服务端生成,不经模型转述。

动手任务

纯概念课,做三个判断/解释任务:

  1. 把这些职责分配到三层:禁用发送按钮、限制消息长度、决定回答内容、保存聊天记录、把密钥发给模型服务。说出分配理由。
  2. 用一句人话解释:为什么「模型说走不通」不能直接写成 if (modelReply === "走不通") { ... }?
  3. 打开本站学习助手随便问一句,在浏览器 Network 面板找到 /api/ai/chat 请求:它的响应是一口气到达,还是一段一段到达?(这个现象 A10 课已经拆过了。)

常见错误

  • 把模型当数据库或计算器用:要求它精确记住一百轮前的每个字,或指望它心算大数。模型每次看到的只是重新发过去的上下文,算术靠生成不靠执行。
  • 在前端直接调模型服务:密钥进了浏览器就等于公开,任何打开控制台的人都能拿到。调用必须经过自己的服务端(A03 课展开)。
  • 把模型输出直接当程序逻辑:不校验就 JSON.parse、不校验就入库。输出是概率生成的文本,格式和内容都不保证。
  • 职责塞错层:把「过滤敏感词」「限制频率」交给模型自觉,而不是写在服务端代码里。凡是要保证执行的要求,都放在代码里。

检查与复盘

自查清单:

  • 能不看笔记画出「界面 → 应用服务端 → 模型服务」链路,并说出每层一件职责
  • 能解释模型输出和函数返回值的本质区别(概率生成 vs 确定执行)
  • 给定一个新功能,能判断它该放哪一层、哪些必须留在代码里

参考资料

  • OpenAI 文档:Text generation —— 官方对「文本生成」能力的定位,理解模型能做什么、不能做什么
  • MDN:HTTP 概述 —— 链路中每一段都是普通 HTTP 请求
  • 下一课 A02 讲这些文本和历史对话是怎么被计量、装进上下文窗口的。
检查题共 2 题,提交后立即显示解析
答案由服务端判定;答错的题会自动进入复习计划。
Q1单选简单

关于「模型的回答」和普通函数返回值的区别,下列说法正确的是?

Q2故障定位中等

bug 现场:业务代码让模型判断工单能否自动处理,写法如下。测试发现模型有时回「走不通」、有时回「此路无法通行」、有时回一段解释,showFallback 几乎从不触发。原因与正确修法是?

const reply = await askModel("这个工单能自动处理吗?");
if (reply === "走不通") {
  showFallback();
}

读完这一课了?

标记完成后,工作台会安排接下来的学习。

Command Palette

Search for a command to run...