我有个前同事做 Java 开发的,最近被迫转行做 Agent 开发,他们公司要求不转型就拜拜,所以也只能硬着头皮上了,每天晚上都跟打了鸡血一样要找我聊五块钱的~
他问我的第一个问题就是:哪个大模型最强?
emmm,恕我直言,当时我脑子里一片混乱,竟然不知道从哪里谈起。

在我看来,他这个问题少了非常关键的半句:你准备让模型在系统里干什么?
比如说看懂一张图片、从知识库中检索资料、给候选文档排序、判断用户意图、生成最终回复,这些虽然都可以出现在同一个 Agent 里,背后却不一定由同一种模型完成。
所以,大模型其实是个很大的概念,当你要做 Agent 开发的时候,首要的就是理解"大模型的分类",这不是为了让你在聊五块钱的时候侃侃而谈,而是为了建立一种工程判断:先拆任务,再给每个任务选择合适的模型。
先说我的结论:大模型可以先从"模态"和"功能"两个角度理解,但不能把它们画成一棵互相排斥的分类树。到了真正的 Agent 开发中,我更愿意把一个模型看成一张多维能力配置表。
一、按模态分类
先看模型能接收什么、输出什么
"模态"这个词听起来有些抽象,其实就是信息存在的形式。
文字是一种模态,图片是一种模态,语音和视频也是一种模态。模型只能处理其中一种,所以通常可以叫单模态模型;能够处理两种或更多信息形式,就具备多模态能力。
不过,"多模态"绝不等于"什么都会"。最稳妥的判断方式,是把输入和输出分开看。
| 模型能力 | 可能的输入 | 可能的输出 | 典型任务 |
|---|---|---|---|
| 语言模型 | 文本 | 文本 | 问答、摘要、写作、代码生成 |
| 多模态理解 | 图片、音频、视频、文本 | 通常是文本或结构化结果 | 看图问答、语音识别、视频理解 |
| 多模态生成 | 文本、图片、音频等 | 图片、音频、视频等 | 文生图、图生视频、语音合成 |
举个最直观的例子。
我给模型一张发票照片,问它"这张发票的金额和日期是什么",重点是从图片中理解信息。我要是再说"根据这些信息生成一张新的报销单图片",重点就变成了内容生成。
这里要修正一个容易误导的理解:多模态理解并不等于先把所有非文本内容机械地转换成文本,多模态生成也不等于只能从文本生成其他模态。
现代多模态模型可能在统一的表示空间中处理文字、视觉和声音,也可能同时具备理解与生成能力。例如,Qwen2.5-Omni 的官方说明包含文本、图像、音频和视频输入,并支持文本与语音输出。它很难被塞进"只负责理解"或"只负责生成"中的一个抽屉里。
所以对于"多模态模型"这个标签,不要马上假设它能看图、听语音、生成图片和实时对话。需要继续核对四件事:
- 支持哪些输入模态?
- 支持哪些输出模态?
- 是原生处理,还是平台先做了 OCR、转写等预处理?
- 是否支持流式输入、实时输出和中途打断?
这些问题到了浏览器 Agent、桌面 Agent、语音 Agent 中,往往会比"多模态"三个字本身更重要。
二、按功能分类
看模型在系统里负责什么
如果说模态回答的是"模型处理什么信息",那么功能回答的就是"模型在系统里干什么活"。
在 RAG 和 Agent 开发中,通常模型角色会分成四类:生成模型、Embedding 模型、Rerank 模型和分类模型。
| 模型角色 | 主要输入 | 主要输出 | 在系统中的工作 |
|---|---|---|---|
| 生成模型 | 提示词、上下文、图片等 | 文本、图片、音频、视频等内容 | 理解指令、推理并组织最终结果 |
| Embedding 模型 | 文本或其他数据 | 向量 | 把语义变成可计算的表示,用于召回 |
| Rerank 模型 | 查询和候选文档 | 相关性分数或新顺序 | 对候选资料进行精排 |
| 分类模型 | 待判断的数据 | 标签或概率 | 意图识别、风险判断、内容路由 |
这四类模型解决的是不同问题。
1. 生成模型:负责理解、推理和表达
我们日常接触最多的聊天模型就属于生成模型。用户给出上下文和要求,模型按 token 逐步生成回答。
写文章、总结合同、解释代码、规划步骤,最终都表现为内容生成。图像、音频和视频模型同样可以属于生成模型,只是输出模态不同。
在 Agent 中,生成模型通常承担"大脑"的一部分工作,例如:
- 理解用户目标;
- 决定下一步要不要使用工具;
- 根据工具返回结果继续推理;
- 把证据整理成用户能读懂的答案。
但这里我要特别强调一下:能生成工具调用参数,不代表模型自己执行了工具,更不代表它已经是一个完整 Agent。
对于客户端工具,真正的流程通常是:应用把工具定义交给模型,模型返回工具名称和参数,应用执行真实代码,再把结果传回模型。权限、超时、重试、审计和错误恢复都属于 Agent 系统,而不是模型权重凭空完成的能力。
2. Embedding:把语义变成可计算的向量
假设公司有 10 万份制度文档,用户问:"出差住酒店一晚最多报销多少钱?"
最粗暴的做法,是把所有文档都塞进大模型上下文。但显然这会遇到长度、成本、延迟和无关信息的干扰等问题。
所以更常见的做法是:
- 把文档切成较小的片段,也就是 chunk。
- 用 Embedding 模型把每个片段转换成一串数字,也就是向量。
- 用户提问时,也把问题转换成向量。
- 计算查询向量与文档向量之间的相似度。
- 召回一批可能相关的文档片段。
chunk你可以理解成镇关西把肉细细切成的臊子,切好了才好下锅。向量空间你可以想象成一座巨大的仓库,语义相近的内容,更容易被摆在相近的货架上。用户提出问题后,系统先去附近货架寻找可能有用的资料。
这里有一个细节需要说一下:Embedding 向量不是"至少 1536 维"。 不同模型的维度不同,例如 BGE-M3 是 1024 维,BGE Base 和 Small 还可以是 768 维、384 维。维度更高也不代表检索效果更好,它还会影响存储空间、索引大小和计算成本。我那个朋友被CSDN的一个文章给误导了,在这里打个假。
关于如何衡量两个向量是否接近,大家有兴趣可以看看一些常见的计算方式,比如余弦相似度,但是我这里要说的是计算的结果是"0.7 就相关"还是"0.99 才能用"并不是业内的通用规则。这个阈值必须结合所用模型、数据分布和真实业务问题做评测。
3. Rerank:从"可能相关"里挑出"真正更相关"
Embedding 检索强调快,适合从海量资料中先召回一批候选项,但快不等于判断足够细。
例如,用户问:"Apple 最近一代芯片适合本地运行模型吗?"初步检索可能同时找到苹果公司、苹果水果、芯片和本地模型部署等片段。Embedding 负责先把可能相关的内容捞出来,Rerank 再把查询与每个候选文档放在一起,重新判断相关性。
因此,Rerank 不只是把原来的余弦分数从大到小再排一遍。那样数据库自己就能完成,不需要第二个模型。它的价值在于:用更精细但更昂贵的方式,重新评估 query 和 document 的关系。
实际工程中常见的是两阶段检索:
text
用户问题
-> Embedding / 关键词检索召回 Top 50
-> Rerank 精排 Top 50
-> 选出 Top 5 作为证据
-> 生成模型组织答案
Rerank 分数同样不能照搬固定阈值。Cohere 的官方建议也是用代表性的业务查询和"临界相关"文档来校准,而不是把某个数字当作标准。
4. 分类模型:不要让大模型包办所有判断
分类模型的输出通常不是一篇长回答,而是标签、概率或 Yes/No。
比如:
- 判断用户想咨询、投诉还是申请退款;
- 判断一段内容是正面、负面还是中性;
- 判断请求是否需要人工确认;
- 把任务路由给知识库 Agent、数据分析 Agent 或客服 Agent。
在企业生产系统中,分类不一定非要使用传统小模型。它可以是经过微调的 BERT 类模型,也可以是生成模型的结构化输出,甚至可以由规则完成。
所以我的选择标准不是"分类模型一定更便宜",而是看准确率、延迟、成本、可解释性和维护成本。如果任务类别固定、调用量大、边界清楚,专用小模型通常值得评估;如果类别变化快、判断依赖复杂上下文,生成模型可能更灵活。
顺便提一嘴,建议在企业业务的起步阶段直接用 Qwen3-0.6B(或 1.7B)做分类 + 路由 + 生成,一套模型打天下,快速验证业务,不要过早优化。因为对于大多数企业级应用来说,Qwen3-0.6B 这类小尺寸大模型做分类已经是一个足够好且工程上更简单的选择了~
三、用一个 Agent 场景把四类模型串起来
假设我要做一个企业报销 Agent。用户上传一张出租车发票,并问:"这笔费用能不能报销?如果可以,帮我提交。"
整个系统可能这样协作:
- 多模态理解模型读取发票图片中的金额、时间、发票号和行程信息。
- 分类模型判断这是"费用报销"任务,并检查是否属于高风险操作。
- Embedding 模型从公司制度库中召回交通费、发票要求和报销额度相关片段。
- Rerank 模型重新排序这些片段,留下与当前城市、职级和出差类型最相关的规定。
- 生成模型结合发票与制度,解释能否报销,并生成待提交的结构化参数。
- Agent 执行器检查权限、请求用户确认,然后调用财务系统 API。
- 生成模型根据真实 API 返回值,告诉用户提交是否成功。
用一段不绑定任何框架的伪代码表示,大致是这样:
typescript
// ============ 类型定义 ============
interface InvoiceInfo {
amount: number;
date: string;
invoiceNumber: string;
tripDetails: string;
}
interface IntentResult {
taskType: string; // e.g. "expense_reimbursement"
isHighRisk: boolean;
}
interface EvidenceSnippet {
id: string;
content: string;
score: number;
}
interface ReimbursementDecision {
canReimburse: boolean;
explanation: string;
requiresSubmission: boolean;
formData?: Record<string, unknown>;
}
interface SubmissionResult {
success: boolean;
message: string;
transactionId?: string;
}
// ============ 模型 / 服务接口(不绑定具体实现) ============
interface VisionModel {
extract(image: Buffer | string): Promise<InvoiceInfo>;
}
interface Classifier {
predict(message: string): Promise<IntentResult>;
}
interface Embedder {
embed(text: string): Promise<number[]>;
}
interface VectorStore {
search(vector: number[], topK: number): Promise<EvidenceSnippet[]>;
}
interface Reranker {
rank(query: string, candidates: EvidenceSnippet[], topN: number): Promise<EvidenceSnippet[]>;
}
interface LLM {
generate(params: {
question: string;
invoice: InvoiceInfo;
evidence: EvidenceSnippet[];
}): Promise<ReimbursementDecision>;
}
interface FinanceApi {
submit(formData: Record<string, unknown>): Promise<SubmissionResult>;
}
// ============ 核心流程 ============
async function handleReimbursement(
userMessage: string,
invoiceImage: Buffer | string,
userConfirmed: boolean,
// 依赖注入,方便测试和替换实现
visionModel: VisionModel,
classifier: Classifier,
embedder: Embedder,
vectorStore: VectorStore,
reranker: Reranker,
llm: LLM,
financeApi: FinanceApi,
): Promise<{ decision: ReimbursementDecision; submission?: SubmissionResult }> {
// 1. 多模态理解:提取发票信息
const invoice = await visionModel.extract(invoiceImage);
// 2. 意图分类 + 风险判断
const intent = await classifier.predict(userMessage);
// 3. 检索相关制度片段
const queryVector = await embedder.embed(userMessage);
const candidates = await vectorStore.search(queryVector, 50);
// 4. 精排,保留最相关的规定
const evidence = await reranker.rank(userMessage, candidates, 5);
// 5. 生成决策与结构化参数
const decision = await llm.generate({
question: userMessage,
invoice,
evidence,
});
// 6. 工具执行由应用层控制,模型只负责"建议"
let submission: SubmissionResult | undefined;
if (decision.requiresSubmission && userConfirmed) {
if (!decision.formData) {
throw new Error("LLM indicated submission is required but did not produce form data");
}
submission = await financeApi.submit(decision.formData);
}
return { decision, submission };
}
这段流程更容易看清:一个 Agent 产品可以叫同一个名字,界面里也只有一个输入框,但背后可能是多个模型、检索系统、业务规则和工具执行器协作。
最后
大模型分类最容易犯的错误,是把一个产品名称当成一种模型,把一种模型标签当成全部能力。
所以记住两句话:
模态决定模型能处理什么信息,功能决定模型在系统里承担什么角色。
Agent 不是一个"万能大模型",而是一组模型、工具、状态和控制逻辑围绕任务形成的系统。