Chat Completion 到底是什么

很多前端工程师第一次接触 LLM API 时,会看到一个词:Chat Completion。

这个名字容易让人误解。它听起来像“做一个聊天应用”,但在 API 语境里,它更准确的意思是:给模型一组对话消息,让模型补全下一条应该出现的 assistant 回复。

也就是说,Chat Completion 不是完整聊天产品,而是一种请求模型生成回答的接口形态。

从 Completion 到 Chat Completion

早期很多文本生成接口叫 Completion。你给模型一段文本,它继续往后写。

例如:

请把下面这句话翻译成英文:
前端工程师正在学习 LLM API。

模型要做的事情是接着这段输入生成后续内容。

Chat Completion 则把输入组织成更像对话的结构:

const messages = [
  { role: 'system', content: '你是一个耐心的技术讲师。' },
  { role: 'user', content: '用前端工程师能理解的方式解释 Chat Completion。' },
];

模型看到的不再只是一整段无角色文本,而是一组有角色的消息。它的目标是根据这些消息,生成下一条 assistant 消息。

这就是 Chat Completion 的核心。

Chat Completion 不等于聊天窗口

聊天窗口是产品界面。Chat Completion 是模型调用方式。

一个聊天产品通常包含很多能力:

  • 输入框。
  • 消息列表。
  • 发送按钮。
  • 历史记录。
  • 流式输出。
  • 停止生成。
  • 重试。
  • 会话标题。
  • 用户登录。
  • 权限控制。
  • 计费统计。
  • 错误提示。

Chat Completion 只解决其中一个问题:给定当前上下文,生成下一条模型回复。

如果用前端工程作类比,Chat Completion 更像一个异步函数:

async function getAssistantMessage(messages: Message[]) {
  return await llm.chat.completions.create({
    model: 'some-model',
    messages,
  });
}

它不会自动帮你维护 React state,不会自动把消息存进数据库,也不会自动知道用户上次说了什么。你想让它看见什么,就要在请求里传什么。

一次请求里发生了什么

一次典型的 Chat Completion 请求至少包含两类信息:

字段作用
model选择由哪个模型生成结果
messages提供当前对话上下文

messages 通常是一组按时间顺序排列的消息:

const messages = [
  { role: 'system', content: '你是一个前端技术助手。' },
  { role: 'user', content: '什么是 hydration?' },
  { role: 'assistant', content: 'Hydration 是指...' },
  { role: 'user', content: '它和 SSR 有什么关系?' },
];

模型会基于这组消息生成下一条回复。它并不是“连接到某个会话后继续说话”,而是每次请求都重新读取你传入的上下文。

这点非常重要:多轮对话不是模型自动记住的,而是应用层把历史消息再次传给模型。

前端工程师应该怎样理解 messages

前端做聊天界面时,通常会维护一个消息数组:

type Message = {
  id: string;
  role: 'system' | 'user' | 'assistant';
  content: string;
  createdAt: number;
};

UI 层需要的字段可能很多,比如 idcreatedAtstatuserrorattachments。但发给模型时,通常只需要模型能理解的部分:

const apiMessages = uiMessages.map((message) => ({
  role: message.role,
  content: message.content,
}));

这意味着你要区分两种消息:

  • UI 消息:用于渲染、交互、状态管理。
  • API 消息:用于传给模型生成结果。

不要把所有 UI 状态都塞进 prompt。模型不需要知道某条消息的 CSS class,也不需要知道前端 loading 状态。它只需要完成任务所必需的上下文。

Chat Completion 的工程本质

从工程视角看,Chat Completion 是一个“上下文输入,文本输出”的远程推理过程。

它和普通 HTTP API 有相似之处:

  • 都有请求参数。
  • 都有响应结果。
  • 都可能失败。
  • 都有延迟。
  • 都需要鉴权。
  • 都会产生成本。

但它也有明显不同:

  • 输出不完全确定。
  • 响应可能很长。
  • 延迟可能比普通接口更高。
  • 输入越长,成本越高。
  • 输出质量受上下文组织方式影响很大。
  • 同一个接口既可能回答问题,也可能生成代码、改写文案、抽取 JSON。

所以在前端应用里接入 Chat Completion,不只是写一个 fetch。你还要处理加载状态、流式渲染、错误恢复、取消请求、历史裁剪、敏感信息过滤和结果校验。

一个最小调用长什么样

不同平台和 SDK 的方法名会不同,但结构大体类似:

const response = await client.chat.completions.create({
  model: 'gpt-4.1-mini',
  messages: [
    {
      role: 'system',
      content: '你是一个帮助前端工程师学习 LLM 的老师。',
    },
    {
      role: 'user',
      content: '用三句话解释 Chat Completion。',
    },
  ],
});

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

这段代码里最值得注意的不是 SDK 方法名,而是 messages 的组织方式。

你不是把一个字符串扔给模型,而是在告诉模型:

  • 当前系统规则是什么。
  • 用户刚刚问了什么。
  • 如果有历史,前面发生过什么。
  • 现在需要生成下一条 assistant 消息。

多轮对话是怎样形成的

假设用户第一次问:

[
  { role: 'system', content: '你是一个前端技术助手。' },
  { role: 'user', content: '什么是 React Server Components?' },
]

模型返回:

{ role: 'assistant', content: 'React Server Components 是...' }

当用户继续问“它和 SSR 有什么区别?”时,你不能只传这一句:

[{ role: 'user', content: '它和 SSR 有什么区别?' }]

因为“它”指代什么,模型可能不知道。你应该把前面的上下文也带上:

[
  { role: 'system', content: '你是一个前端技术助手。' },
  { role: 'user', content: '什么是 React Server Components?' },
  { role: 'assistant', content: 'React Server Components 是...' },
  { role: 'user', content: '它和 SSR 有什么区别?' },
]

这就是多轮对话的基本机制。

模型看起来像“记得”,本质上是你把历史重新传给了它。

上下文不是越多越好

既然历史要重新传入,一个自然问题是:是不是应该把所有历史都传给模型?

不一定。

上下文越长,通常会带来几个问题:

  • 成本更高。
  • 延迟更高。
  • 可能超过模型上下文限制。
  • 早期无关信息可能干扰当前回答。
  • 隐私和安全风险增加。

真实应用里通常需要做上下文管理:

  • 只保留最近几轮关键消息。
  • 对更早历史做摘要。
  • 把业务数据通过检索按需注入。
  • 删除和当前任务无关的 UI 噪音。
  • 对敏感字段做过滤。

这部分能力往往比“调通 API”更能决定产品质量。

常见误区

第一个误区:以为 Chat Completion 会自动保存会话。

不会。API 请求之间默认没有记忆。会话历史应该由你的应用保存,并在下一次请求时传入。

第二个误区:以为 messages 就等于前端消息列表。

前端消息列表服务于界面渲染,API messages 服务于模型理解。二者可以互相转换,但不应该完全混在一起。

第三个误区:以为 role 只是装饰字段。

role 会影响模型理解消息的来源和优先级。尤其是 system message,它常用来描述模型行为边界和回答风格。

第四个误区:以为 Chat Completion 只能做聊天。

它可以用于很多非聊天任务,比如生成标题、总结工单、改写文案、生成表单默认值、抽取结构化数据。聊天只是最直观的外壳。

第五个误区:以为模型输出可以直接当作可靠业务结果。

模型输出需要校验。尤其是 JSON、代码、金额、权限、医疗、法律、金融等场景,不能只因为文本看起来合理就直接执行。

小结

Chat Completion 是一种对话式模型调用方式:你提供一组带角色的消息,模型生成下一条 assistant 回复。

它不是聊天产品本身,也不自动管理历史。前端工程师真正要掌握的是:如何维护 UI 消息,如何整理 API messages,如何控制上下文,如何处理不确定输出,并把一次模型调用放进可靠的产品流程里。

理解这一点之后,后面的 system prompt、user prompt、assistant message、多轮对话、temperature 和 streaming 才会变得清晰。