Skip to content

第2章 大模型应用基础

2.1 问题场景

很多人能调用模型接口,却做不出稳定应用:同一问题回答忽好忽坏,风格漂移、格式不稳、成本不可控,而且很难解释结果差异。 本章的目标不是教你“再写一些提示词(prompt)技巧”,而是建立最小可控的模型应用认知,把模型调用从“能跑”推进到“可复现、可解释、可迭代”。

很多前端工程师在这一阶段最容易踩的坑包括:

  • 把提示词当成玄学,不做版本管理和对照实验。
  • 一次给模型太多任务,希望它“一次性全部做好”。
  • 只看主观感觉,不留固定样本和结果记录。
  • 结果结构不稳定,前端后续无法可靠展示或消费。

前端迁移提示

这一章其实非常适合前端工程师入门,因为你已经熟悉很多“控制输入、约束输出”的思维:

  • API 调用参数控制 -> 模型参数和上下文控制。
  • 表单校验 -> 输出 schema 与结构化结果校验。
  • 状态管理与数据流 -> 输入模板、上下文和结果结构的稳定组织。
  • 组件契约 -> 提示词模板与输出结构契约。

最小项目目标

本章建议先完成一个“固定任务 + 固定模板 + 固定评测样本”的最小闭环,例如:

  • FAQ 摘要生成。
  • 制度问答摘要。
  • 会议纪要要点提炼。

参考入口:

2.2 核心原理

这一章最关键的,不是“学会调一个模型接口”,而是理解影响大模型应用稳定性的几个核心变量,并把它们固化成工程资产。

一、输入决定上限:提示词、上下文、约束条件共同决定输出

同一个模型、同一个问题,结果会随着以下因素变化:

  • 系统指令。
  • 用户输入写法。
  • 示例样本。
  • 输出格式要求。
  • 附加上下文。

因此,模型应用的第一原则不是“换更强模型”,而是先把输入结构做稳定。

二、参数影响稳定性、成本与风格

大模型参数不是调味料,而是稳定性和成本的一部分。 尤其需要理解:

  • 温度:影响随机性和输出一致性。
  • 最大输出长度:影响成本和啰嗦程度。
  • 是否要求结构化输出:影响前端可消费性。

如果你不记录这些参数和模板版本,后面几乎无法复盘“为什么这个版本效果变了”。

三、任务要可拆分:复杂需求不要一口吃掉

一个最常见错误是:

  • 既要分类。
  • 又要摘要。
  • 又要提取字段。
  • 还要生成建议。

这会让输出变得不稳定。 更稳妥的方式是先做一个单任务样本闭环,把输入、输出和验证标准固定住。

四、结构化输出:让系统真正可消费

模型输出不应该只是一段自由文本。 为了让前端、工作流和后续评测稳定工作,建议尽早定义结构化输出。 例如一个最小结果样本可以像这样:

json
{
  "task_name": "faq_summary",
  "model": "example-llm",
  "temperature": 0.2,
  "max_tokens": 400,
  "output_schema": {
    "summary": "string",
    "risk_level": "low|medium|high"
  }
}

你可以直接参考:

  • docs/examples/assets/samples/chapter-02-model-baseline.json

五、样本回归:模型应用必须有固定样本集

如果没有固定样本集,你就没法回答:

  • 新模板和旧模板哪个更稳。
  • 温度怎么影响输出。
  • 结构化输出是否更稳定。

这也是为什么第 2 章会和第 8 章评测体系天然衔接。

2.3 快速上手:5 分钟完成第一次模型调用

前面讲了原理,现在动手。这一节的目标是让你在 5 分钟内跑通第一个大模型调用,建立最直观的感受。

一、环境准备

你已经是前端开发者,大概率本地已经有 Node.js。确认一下版本:

bash
node -v  # 需要 18+

创建一个练习项目:

bash
mkdir llm-playground && cd llm-playground
npm init -y
npm install openai tsx typescript

国内开发者提示:如果无法访问 OpenAI API,可以使用兼容 OpenAI 接口格式的国产模型服务:

  • DeepSeekhttps://api.deepseek.com
  • 通义千问https://dashscope.aliyuncs.com/compatible-mode/v1
  • 智谱 GLMhttps://open.bigmodel.cn/api/paas/v4

这些服务都兼容 openai SDK,只需修改 baseURLapiKey。 计费、免费额度和活动政策请以各服务商官方页面为准。

配置 API Key(以环境变量方式,不要硬编码到代码里):

bash
export OPENAI_API_KEY="sk-your-key-here"
# 如果用 DeepSeek:
# export OPENAI_API_KEY="sk-your-deepseek-key"

二、第一个调用:Hello LLM

创建 call-llm.ts

typescript
// call-llm.ts
import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  // 如果用 DeepSeek,取消下面这行注释:
  // baseURL: 'https://api.deepseek.com',
})

async function main() {
  const response = await client.chat.completions.create({
    model: 'gpt-4o-mini', // DeepSeek 用 'deepseek-chat'
    messages: [
      { role: 'system', content: '你是一个前端技术助手' },
      { role: 'user', content: '用 3 句话解释什么是 React Server Components' },
    ],
    temperature: 0.7,
  })

  console.log(response.choices[0].message.content)
}

main()

运行:

bash
npx tsx call-llm.ts

如果一切正常,你会看到模型返回的回答。恭喜,你已经完成了第一次大模型调用。

回看这段代码,对前端开发者来说其实没有任何新概念——它就是一个异步 API 调用,只是返回的不是 JSON 数据,而是自然语言。

三、结构化输出:让模型返回 JSON

实际项目中,前端需要稳定的数据结构来渲染 UI,不能靠解析自由文本。response_format 参数可以要求模型返回合法 JSON:

typescript
// structured-output.ts
import OpenAI from 'openai'

const client = new OpenAI()

async function extractTechStack(description: string) {
  const response = await client.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      {
        role: 'system',
        content: `从用户描述中提取技术栈信息,返回 JSON 格式:
{"frameworks": string[], "languages": string[], "tools": string[], "level": "junior"|"mid"|"senior"}`,
      },
      { role: 'user', content: description },
    ],
    response_format: { type: 'json_object' },
    temperature: 0,
  })

  return JSON.parse(response.choices[0].message.content!)
}

extractTechStack(
  '我用 React 和 TypeScript 做了 2 年前端,最近在学 Next.js 和 Tailwind'
).then(result => console.log(JSON.stringify(result, null, 2)))

注意这里 temperature 设为 0——结构化提取任务需要确定性输出,不需要"创意"。

四、使用 Vercel AI SDK(更贴近前端生态)

如果你更习惯前端生态的工具链,Vercel 的 AI SDK 提供了更简洁的 API:

bash
npm install ai @ai-sdk/openai
typescript
// ai-sdk-demo.ts
import { generateText } from 'ai'
import { openai } from '@ai-sdk/openai'

async function main() {
  const { text } = await generateText({
    model: openai('gpt-4o-mini'),
    prompt: '用 React 组件的比喻来解释 AI Agent 的概念',
  })

  console.log(text)
}

main()

AI SDK 的优势在后续章节会更明显:它原生支持流式输出(Streaming)、工具调用(Tool Use)和前端组件集成,非常适合构建 AI 驱动的 Web 应用。

五、温度参数对比实验

温度(temperature)是你最先需要理解的参数。跑一下这个实验,直观感受它的影响:

typescript
// temperature-compare.ts
import OpenAI from 'openai'

const client = new OpenAI()

async function compareTemperatures() {
  const prompt = '给一个 React 状态管理库起一个名字,只回复名字本身'
  const temperatures = [0, 0.7, 1.5]

  for (const temp of temperatures) {
    console.log(`\n--- temperature: ${temp} ---`)
    for (let i = 0; i < 3; i++) {
      const response = await client.chat.completions.create({
        model: 'gpt-4o-mini',
        messages: [{ role: 'user', content: prompt }],
        temperature: temp,
      })
      console.log(`  第 ${i + 1} 次: ${response.choices[0].message.content}`)
    }
  }
}

compareTemperatures()

你会观察到:

  • temperature = 0:三次输出几乎相同——适合需要确定性结果的场景(提取、分类、格式化)。
  • temperature = 0.7:有变化但合理——适合生成类任务(写文案、回答问题)。
  • temperature = 1.5:差异很大,可能出现奇怪结果——一般不推荐用于生产。

六、前端开发者备忘

把这几个类比记住,后续章节会反复用到:

前端概念大模型对应概念说明
fetch(url, options)client.chat.completions.create(params)模型 API 就是一个远程接口调用
表单校验 schemaresponse_format + prompt 约束结构化输出 ≈ 给模型写 API 契约
Math.round() vs Math.random()temperature: 0 vs temperature: 1确定性输出 vs 随机性输出
聊天记录数组messages 数组顺序很重要,上下文影响输出
组件 Props 接口提示词模板的变量槽位模板化 = 可复用、可测试

关键认知:模型调用本身没有什么"魔法",它就是你熟悉的客户端-服务端交互模式。真正的工程挑战在于如何让输入可控、输出稳定、结果可验证——这正是后续章节要解决的问题。

2.4 实操步骤

推荐做法不是先做复杂智能体,而是先把“单任务、固定模板、固定样本、固定结果结构”做成一个最小应用基线。

步骤 1:先选一个单任务场景

推荐选择:

  • 输入相对稳定。
  • 输出可以明确结构。
  • 成功标准容易判断。

例如:

  • FAQ 摘要。
  • 政策摘要。
  • 风险点提取。

步骤 2:固定输入模板

建议至少明确:

  • 角色是什么。
  • 任务目标是什么。
  • 不能做什么。
  • 输出格式是什么。

你可以直接参考:

步骤 3:设定一组参数基线

建议最少记录:

  • 模型名。
  • 温度。
  • 最大输出长度。
  • 提示词模板版本。
  • 样本集名称。

参考入口:

  • docs/examples/assets/samples/chapter-02-model-baseline.json

步骤 4:准备固定样本集

建议至少准备 20 条固定样本,覆盖:

  • 正常样本。
  • 边界样本。
  • 容易格式漂移的样本。

步骤 5:做对照实验

例如至少对比:

  • 温度 0.2 vs 0.7。
  • 有无结构化输出要求。
  • 不同提示词模板版本。

步骤 6:固化最佳配置

不是追求“某一次最好”,而是找出最稳定、最适合业务使用的组合。

步骤 7:同步准备前端展示与证据材料

建议至少保留:

  • 参数基线样本:docs/examples/assets/samples/chapter-02-model-baseline.json
  • 截图清单:docs/examples/assets/screenshots/README.md
  • 章节片段索引
  • 模板库

2.5 常见坑

坑 1:把提示词当玄学

如果不做版本管理和对照实验,后面很难复盘有效因素。

坑 2:一次塞入过多要求

任务越复杂、要求越多,输出越容易漂移。

坑 3:只看主观“感觉好”

没有固定样本集和结构化结果,就很难稳定迭代。

坑 4:参数不记录

模型名、温度、长度限制这些参数如果不记录,后面几乎无法复现结果。

坑 5:结果结构不稳定

前端很难可靠展示,后续评测和工作流也很难接入。

坑 6:过早追求复杂智能体

在基础调用和结构化输出没打稳之前,越复杂越容易失控。

2.6 验证方式

这一章做完后,不应只看“接口能不能返回结果”,而要看这个调用方式是否已经形成一个最小可复现基线。

一、样本集是否固定

  • 是否已有固定样本集。
  • 是否覆盖了正常和边界样本。

二、结果是否稳定

  • 相同配置下关键任务结果稳定率是否达到目标。
  • 输出结构是否始终一致。

三、参数是否可解释

  • 能否清楚说明为什么设置这个温度和输出长度。
  • 能否解释参数变化带来的影响。

四、前端是否可消费

从前端视角检查:

  • 输出字段是否稳定。
  • 是否便于直接展示或进入后续流程。

五、证据材料

  • 参数基线样本:docs/examples/assets/samples/chapter-02-model-baseline.json
  • 截图清单:docs/examples/assets/screenshots/README.md
  • 章节片段索引

2.7 面试表达

我做模型应用时,先把任务标准化,再通过固定样本和参数对照实验确定最稳定的提示词与参数组合。 这样可以把模型调用从“试运气”变成“可复现、可解释、可迭代”的工程过程。

实战案例:FAQ 摘要输出稳定性提升

  • 背景:同一类 FAQ 在不同时间生成风格和质量波动明显。
  • 动作:固定输入模板、参数和样本集,建立结构化输出约束,并对比不同温度和模板版本。
  • 结果:输出一致性显著提升,人工复核成本下降,后续也更容易接入评测和前端展示。

推荐答题框架

如果面试官问“你怎么让模型调用更稳定”,可以按下面顺序回答:

  1. 先讲固定任务和输入模板。
  2. 再讲参数记录和对照实验。
  3. 再讲结构化输出和样本回归。
  4. 最后讲它如何帮助前端展示、结果消费和后续工程化扩展。

2.8 练习任务

  1. 选一个单任务场景,并定义固定输入模板和输出格式。
  2. 用同一批样本测试 2 组温度参数并记录差异。
  3. 设计一份最小参数基线结构,至少记录模型、温度、长度和 prompt 版本。
  4. 基于 模板库 整理一份可复用的提示词模板,并记录版本号。
  5. 结合 docs/examples/assets/samples/chapter-02-model-baseline.json,整理出你的第一版模型调用基线。

2.9 验收清单

  • 任务完成率 >= 85%
  • 关键指标达标率 >= 90%
  • 异常场景通过率 >= 90%
  • 至少完成 1 组固定样本、1 份参数基线和 1 份结构化输出定义。
  • 至少保留 1 份模型基线样本、1 组截图占位清单和 1 份章节代码片段索引。
  • 至少能用 2 分钟讲清楚“为什么模型应用基础不是单次接口调用,而是输入、参数、结构与样本共同构成的最小工程基线”。

2.10 💡 本地模型替代 — Ollama 5 分钟跑通第一个本地模型

🏠 自托管替代方案

本章所有示例都使用 OpenAI API,但你可以用完全免费的本地模型获得相同体验。以下是最快的切换方式。

为什么要尝试本地模型

维度云端 API本地模型
费用按 token 计费完全免费
隐私数据发送到第三方数据不出本机
网络需要稳定网络离线可用
延迟取决于网络取决于硬件

3 步切换

Step 1:安装 Ollama

bash
# macOS / Linux
curl -fsSL https://ollama.com/install.sh | sh

# 或访问 https://ollama.com 下载安装包

Step 2:拉取模型

bash
ollama pull qwen3:8b

Step 3:修改代码

本章的 LLM 调用代码只需改两行即可切换到本地模型:

typescript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:11434/v1',  // 改这里:指向 Ollama
  apiKey: 'ollama',                       // 改这里:任意字符串即可
});

const response = await client.chat.completions.create({
  model: 'qwen3:8b',                     // 改这里:使用本地模型名
  messages: [{ role: 'user', content: '你好,请自我介绍' }],
});

console.log(response.choices[0].message.content);

🖥️ 前端迁移提示:这就像修改 axios.defaults.baseURL 从生产环境切到本地开发服务器——接口格式完全一样,只是服务端换了。

硬件要求

  • 最低:16GB 内存的 MacBook(Apple Silicon)或 8GB 显存的 GPU
  • 推荐:M2/M3/M4 Mac 或 RTX 3090/4090

深入阅读

想了解更多本地模型选型、量化方案和生产部署,请阅读 专题 11:自托管 AI Agent 全栈指南