Long Context vs RAG:128K上下文时代,我们还需要RAG吗?
Long Context vs RAG:128K上下文时代,我们还需要RAG吗?
那场差点让RAG项目被砍掉的架构评审
2026年3月,郑磊在公司季度架构评审上被怼了一下,那一下差点把他的项目给搞死。
郑磊是一家律所数字化转型团队的技术负责人,他们花了4个月建了一套法律文书检索系统,核心是RAG:用户输入法律问题,系统从3万份判决书和法规文档中检索相关片段,再由GPT-4o生成答案。整个系统稳定运行了2个月,用户满意度还不错。
评审会上,CTO刘总突然抛出一个问题:
"我看Gemini 1.5 Pro现在支持100万Token上下文,ChatGPT也支持128K了。你们3万份文档,塞进去不就完了?要RAG干什么?"
整个会议室安静了三秒。
郑磊当时没有答上来——不是因为他不懂,而是因为他没有量化的数据支撑。他知道Long Context有问题,但说不出具体是什么问题,说不出在什么场景下RAG更好。
会后他用了两周时间,系统性地做了一套对比测试,把这个问题彻底搞清楚了。
结论是:RAG没有死,但它需要更精准的使用场景定义。CTO的问题问得对——有些场景确实不需要RAG了,但有些场景RAG依然不可替代。
这篇文章就是那两周测试的完整复盘,包括所有测试数据和代码。
先说结论(TL;DR)
| 维度 | Long Context | RAG | 推荐场景 |
|---|---|---|---|
| 适用文档量 | <500页 | 无限制 | - |
| 响应延迟 | 高(10-60s) | 低(1-3s) | 实时场景选RAG |
| 成本(1000页) | $8-25/次 | $0.02-0.05/次 | 高频访问选RAG |
| 知识更新 | 需重新构建 | 实时更新 | 动态知识选RAG |
| 精确性(特定问题) | 中等 | 高 | 精准查询选RAG |
| 推理性(全文分析) | 高 | 低 | 全文分析选Long Context |
| 实现复杂度 | 低 | 高 | MVP阶段选Long Context |
核心结论:
- 文档量小(<100页)+ 问题需要全局理解:用Long Context
- 文档量大 + 问题定向精确:用RAG
- 高频访问 + 成本敏感:必须用RAG
- 最优方案:两者结合——RAG粗检索 + Long Context精读
Long Context的现状:各模型上下文窗口对比
截至2026年Q1,主流模型的上下文窗口:
| 模型 | 上下文窗口 | 约合文字数 | 输入价格(每1M Token) |
|---|---|---|---|
| GPT-4o | 128K | 约10万字 | $2.50 |
| GPT-4o-mini | 128K | 约10万字 | $0.15 |
| Claude 3.5 Sonnet | 200K | 约15万字 | $3.00 |
| Claude 3 Opus | 200K | 约15万字 | $15.00 |
| Gemini 1.5 Pro | 1M | 约75万字 | $1.25 |
| Gemini 1.5 Flash | 1M | 约75万字 | $0.075 |
| Llama 3.1 | 128K | 约10万字 | 开源 |
| Qwen2.5 | 128K | 约10万字 | 开源 |
看起来很美——1百万Token,够塞进去很多内容。但实测下来,问题比想象中多。
Long Context的三大局限
局限1:注意力衰减——"大海捞针"效应
这是最严重的问题,有严格的学术研究支撑。
Greg Kamradt在2023年发布的"Needle In A Haystack"测试揭示了一个规律:当关键信息处于长文本的中间位置时,模型的提取准确率会显著下降。
郑磊团队的实测数据(法律文书场景):
| 关键条款位置 | GPT-4o准确率 | Gemini 1.5 Pro准确率 |
|---|---|---|
| 文档前20% | 94% | 91% |
| 文档中间40-60% | 68% | 73% |
| 文档后20% | 92% | 89% |
对比RAG(精确检索到相关段落后回答):92%的准确率,不受位置影响。
局限2:成本爆炸
来做一道小学数学题。
郑磊团队的法律文书库有3万份文档,平均每份15页,即45万页,约3.6亿中文字,换算成Token约5.4亿。
如果用Long Context把所有文档都塞进去(假设技术上可行):
- 输入Token:540,000,000
- GPT-4o价格:$2.50 / 1M Token
- 单次查询成本:$1,350
即使是最便宜的Gemini 1.5 Flash:
- 单次查询成本:$40.5
而RAG方案:
- 检索并返回top-10个chunk:约2000 Token
- LLM生成答案:约500 Token input,200 Token output
- 单次查询成本:$0.006(用GPT-4o-mini)
成本差距:200倍到225,000倍。
实际上没人会把所有文档都塞进去——但即使只塞一份15页的文档(约10,000字,约15K Token),每次查询成本也比RAG高10倍以上。
局限3:延迟高、速度慢
郑磊团队实测的响应时间(以法律问题查询为例):
| 方案 | 文档量 | 首Token延迟 | 完整响应时间 |
|---|---|---|---|
| RAG | 3万份 | 0.8s | 2.1s |
| Long Context(单文档15页) | 1份 | 3.2s | 8.5s |
| Long Context(10份文档) | 10份 | 12.4s | 28.6s |
| Long Context(100份文档) | 100份 | 超时(>60s) | N/A |
对于需要实时响应的场景,Long Context基本不可用。
RAG的核心优势
优势1:精准检索
RAG不是把所有内容给模型看,而是只给模型看最相关的内容。对于特定问题的查询,精准的检索结果比海量上下文更有用。
这就好比问一个工作经验丰富的律师"这份合同的违约金条款是什么"——他不会把整本合同背给你听,他会直接翻到第8条给你看。
优势2:知识实时更新
Long Context的知识是静态的——你每次调用都要传入文档。如果文档更新了,下次调用时需要更新传入的内容,对于动态知识库这是巨大的负担。
RAG的向量库可以实时更新(参考上一篇文章),新文档入库后立即可以被检索到。
优势3:可解释性
RAG天然提供"引用来源"——可以告诉用户"这个答案来自第3号文档的第15段"。这在法律、医疗、金融等合规场景极其重要。
Long Context虽然也能做,但需要额外的后处理来定位来源段落。
选型矩阵:什么场景用哪个
具体场景判断表:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 单份合同审核(<50页) | Long Context | 需要整体理解,文档小 |
| 法规库查询(3万份文档) | RAG | 文档量大,问题定向 |
| 代码库问答 | RAG | 代码量大,精确匹配 |
| 会议纪要摘要 | Long Context | 需要全文理解 |
| 产品手册问答 | RAG | 用户问题定向,需要速度 |
| 学术论文综述 | Long Context | 需要跨文档推理 |
| 客服知识库 | RAG | 高频访问,成本敏感 |
| 个人文档助手(<100页) | Long Context | 简单,够用 |
| 企业知识库(100万文档) | RAG | 只能RAG |
混合方案:RAG检索 + Long Context精读
这是2026年的最佳实践。
代码实现:
package com.laozhang.rag.hybrid;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* 混合检索服务:RAG粗检索 + Long Context精读
*
* 两步走:
* 1. 用向量检索从大规模知识库中找到最相关的20个片段
* 2. 把这20个片段(通常2-3万字)作为上下文,让LLM精读后回答
*
* 效果:比纯RAG准确(上下文更丰富),比纯Long Context便宜(不用传整个知识库)
*/
@Service
public class HybridRetrievalService {
private final VectorStore vectorStore;
private final ChatClient chatClient;
private final RerankService rerankService;
public HybridRetrievalService(VectorStore vectorStore,
ChatClient chatClient,
RerankService rerankService) {
this.vectorStore = vectorStore;
this.chatClient = chatClient;
this.rerankService = rerankService;
}
/**
* 混合检索问答
*
* @param question 用户问题
* @param topKRetrieval 向量检索召回数量(粗检索)
* @param topKFinal 最终传给LLM的数量(精选后)
*/
public HybridAnswer answer(String question, int topKRetrieval, int topKFinal) {
long startTime = System.currentTimeMillis();
// Step 1: 向量检索(粗召回)
List<Document> candidates = vectorStore.similaritySearch(
SearchRequest.query(question)
.withTopK(topKRetrieval)
.withSimilarityThreshold(0.6)
);
long retrievalTime = System.currentTimeMillis() - startTime;
if (candidates.isEmpty()) {
return HybridAnswer.builder()
.answer("抱歉,知识库中没有找到与您问题相关的内容。")
.sources(List.of())
.build();
}
// Step 2: 精排(Rerank)——从topKRetrieval中选出topKFinal
List<Document> selected = rerankService.rerank(question, candidates, topKFinal);
long rerankTime = System.currentTimeMillis() - startTime - retrievalTime;
// Step 3: 构建上下文(这里允许比普通RAG多得多的上下文)
String context = buildRichContext(selected);
// Step 4: LLM精读(使用支持Long Context的模型)
String answer = generateAnswer(question, context, selected);
long totalTime = System.currentTimeMillis() - startTime;
return HybridAnswer.builder()
.answer(answer)
.sources(extractSources(selected))
.retrievalTimeMs(retrievalTime)
.rerankTimeMs(rerankTime)
.totalTimeMs(totalTime)
.contextTokens(estimateTokens(context))
.build();
}
private String buildRichContext(List<Document> documents) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < documents.size(); i++) {
Document doc = documents.get(i);
sb.append("=== 参考资料 ").append(i + 1).append(" ===\n");
// 添加文档元数据
if (doc.getMetadata().containsKey("title")) {
sb.append("来源:").append(doc.getMetadata().get("title")).append("\n");
}
if (doc.getMetadata().containsKey("section")) {
sb.append("章节:").append(doc.getMetadata().get("section")).append("\n");
}
sb.append("内容:\n").append(doc.getContent()).append("\n\n");
}
return sb.toString();
}
private String generateAnswer(String question, String context, List<Document> sources) {
String systemPrompt = """
你是一位专业的法律顾问助手。请基于以下参考资料,准确回答用户的问题。
回答要求:
1. 直接基于参考资料中的内容回答,不要添加参考资料中没有的信息
2. 如果参考资料中有明确的法条或条款编号,请在答案中引用
3. 如果问题的答案在参考资料中找不到,请明确说明
4. 答案要简洁准确,避免冗余
参考资料:
""" + context;
String userPrompt = "问题:" + question;
return chatClient.call(new Prompt(List.of(
new SystemMessage(systemPrompt),
new UserMessage(userPrompt)
))).getResult().getOutput().getContent();
}
private List<SourceReference> extractSources(List<Document> documents) {
return documents.stream()
.map(doc -> SourceReference.builder()
.documentId(doc.getId())
.title((String) doc.getMetadata().getOrDefault("title", "未知文档"))
.section((String) doc.getMetadata().getOrDefault("section", ""))
.relevanceScore((Double) doc.getMetadata().getOrDefault("distance", 0.0))
.build())
.collect(Collectors.toList());
}
private int estimateTokens(String text) {
// 中文大约1.5字符/token,英文大约4字符/token
return (int) (text.length() / 1.5);
}
}完整的Spring Boot配置
package com.laozhang.rag.config;
import io.milvus.client.MilvusServiceClient;
import io.milvus.param.ConnectParam;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.openai.OpenAiEmbeddingClient;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RagConfig {
@Value("${milvus.host:localhost}")
private String milvusHost;
@Value("${milvus.port:19530}")
private int milvusPort;
@Value("${spring.ai.openai.api-key}")
private String openAiApiKey;
@Bean
public MilvusServiceClient milvusClient() {
ConnectParam connectParam = ConnectParam.newBuilder()
.withHost(milvusHost)
.withPort(milvusPort)
.build();
return new MilvusServiceClient(connectParam);
}
@Bean
public OpenAiApi openAiApi() {
return new OpenAiApi(openAiApiKey);
}
/**
* 使用GPT-4o作为推理模型(Long Context能力强)
*/
@Bean(name = "reasoningChatClient")
public OpenAiChatClient reasoningChatClient(OpenAiApi openAiApi) {
return OpenAiChatClient.builder()
.openAiApi(openAiApi)
.defaultOptions(
OpenAiChatOptions.builder()
.withModel("gpt-4o")
.withTemperature(0.1f) // 法律场景要低温度
.withMaxTokens(2000)
.build()
)
.build();
}
/**
* 使用GPT-4o-mini作为快速响应模型(成本低)
*/
@Bean(name = "fastChatClient")
public OpenAiChatClient fastChatClient(OpenAiApi openAiApi) {
return OpenAiChatClient.builder()
.openAiApi(openAiApi)
.defaultOptions(
OpenAiChatOptions.builder()
.withModel("gpt-4o-mini")
.withTemperature(0.1f)
.withMaxTokens(1000)
.build()
)
.build();
}
}成本对比:处理1000页文档的真实费用
郑磊团队的实测数据,以法律文书场景为基准:
场景1:偶发查询(每天10次)
| 方案 | 每次成本 | 每天成本 | 每月成本 |
|---|---|---|---|
| Long Context(单文档15页) | $0.038 | $0.38 | $11.4 |
| Long Context(10份文档) | $0.38 | $3.8 | $114 |
| RAG(top-5检索) | $0.003 | $0.03 | $0.9 |
| 混合RAG+LongContext | $0.015 | $0.15 | $4.5 |
结论:偶发查询、文档量小的情况下,Long Context还可以接受。
场景2:高频查询(每天5000次)
| 方案 | 每天成本 | 每月成本 | 每年成本 |
|---|---|---|---|
| Long Context(单文档15页) | $190 | $5,700 | $68,400 |
| Long Context(10份文档) | $1,900 | $57,000 | $684,000 |
| RAG(top-5检索) | $15 | $450 | $5,400 |
| 混合RAG+LongContext | $75 | $2,250 | $27,000 |
结论:高频查询场景,RAG的成本优势是决定性的。
延迟对比:实测响应时间
郑磊团队用同一组100个法律问题,分别在三种方案下测试P50/P95/P99延迟:
| 方案 | P50 延迟 | P95 延迟 | P99 延迟 |
|---|---|---|---|
| 纯Long Context(15页文档) | 8.5s | 15.2s | 22.1s |
| 纯RAG(top-5) | 1.8s | 3.2s | 5.1s |
| 混合方案(RAG top-20 + Long Context读) | 3.1s | 5.8s | 8.9s |
| 纯RAG(top-20,更多上下文) | 2.4s | 4.1s | 6.3s |
对于需要秒级响应的产品,Long Context的延迟基本不可接受。
准确率对比:在法律文书任务上的实测
测试集:100个标注了标准答案的法律问题,答案来源于具体的法条和判决。
评估维度:
1. 答案准确性(是否给出了正确答案)
2. 来源定位(是否正确标注了出处)
3. 不该回答时的拒绝率(知识库中没有答案时,是否说"不知道"而不是编造)| 方案 | 答案准确率 | 来源定位率 | 拒绝率(应为100%) |
|---|---|---|---|
| Long Context(15页文档) | 82% | 58% | 73% |
| Long Context(100页文档) | 71% | 41% | 61% |
| 纯RAG | 89% | 91% | 87% |
| 混合方案 | 94% | 93% | 92% |
混合方案在所有维度上都表现最好。这符合直觉:RAG负责精准找到相关内容,Long Context负责在丰富上下文中做高质量推理。
Java实现:自动选型路由器
根据上面的分析,可以实现一个自动选型路由器,根据问题特征和文档量自动决定用哪种方案。
package com.laozhang.rag.router;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 智能路由服务:自动选择Long Context或RAG方案
*
* 决策逻辑:
* 1. 文档量 > 阈值 → RAG
* 2. 需要全局分析(摘要、综合) → Long Context
* 3. 实时性要求高 → RAG
* 4. 默认 → 混合方案
*/
@Slf4j
@Service
public class RetrievalStrategyRouter {
private final HybridRetrievalService hybridService;
private final LongContextService longContextService;
private final PureRagService ragService;
private final QueryClassifier queryClassifier;
// 配置阈值
private static final int MAX_DOCS_FOR_LONG_CONTEXT = 50; // 超过50页文档不用Long Context
private static final int MAX_TOKENS_FOR_LONG_CONTEXT = 80000; // 超过80K Token不用Long Context
private static final long MAX_LATENCY_MS = 5000; // 要求5秒内响应则不用Long Context
public StrategyResult route(RetrievalRequest request) {
QueryType queryType = queryClassifier.classify(request.getQuestion());
log.info("Query classified as: {}, docs: {}, latency requirement: {}ms",
queryType, request.getDocumentCount(), request.getMaxLatencyMs());
// 决策1:文档量太大,只能用RAG
if (request.getDocumentCount() > MAX_DOCS_FOR_LONG_CONTEXT) {
log.info("Using RAG: document count {} exceeds threshold", request.getDocumentCount());
return executeRag(request, queryType);
}
// 决策2:有严格延迟要求,用纯RAG
if (request.getMaxLatencyMs() != null && request.getMaxLatencyMs() < MAX_LATENCY_MS) {
log.info("Using RAG: strict latency requirement {}ms", request.getMaxLatencyMs());
return executeRag(request, queryType);
}
// 决策3:需要全局分析(如摘要、综合分析),用Long Context
if (queryType == QueryType.GLOBAL_ANALYSIS || queryType == QueryType.SUMMARIZATION) {
log.info("Using Long Context: query requires global understanding");
return executeLongContext(request);
}
// 决策4:文档较少且问题定向,用混合方案
if (request.getDocumentCount() <= MAX_DOCS_FOR_LONG_CONTEXT) {
log.info("Using Hybrid: moderate document count with directed question");
return executeHybrid(request);
}
// 默认:混合方案
return executeHybrid(request);
}
private StrategyResult executeRag(RetrievalRequest request, QueryType queryType) {
// 根据问题类型调整检索参数
int topK = queryType == QueryType.FACTUAL ? 5 : 10;
RagAnswer answer = ragService.answer(request.getQuestion(), topK);
return StrategyResult.builder()
.strategy(RetrievalStrategy.RAG)
.answer(answer.getText())
.sources(answer.getSources())
.latencyMs(answer.getLatencyMs())
.build();
}
private StrategyResult executeLongContext(RetrievalRequest request) {
LongContextAnswer answer = longContextService.answer(
request.getQuestion(),
request.getDocuments() // 传入完整文档
);
return StrategyResult.builder()
.strategy(RetrievalStrategy.LONG_CONTEXT)
.answer(answer.getText())
.sources(answer.getSources())
.latencyMs(answer.getLatencyMs())
.costUsd(answer.getCostUsd())
.build();
}
private StrategyResult executeHybrid(RetrievalRequest request) {
HybridAnswer answer = hybridService.answer(
request.getQuestion(),
20, // topKRetrieval
5 // topKFinal
);
return StrategyResult.builder()
.strategy(RetrievalStrategy.HYBRID)
.answer(answer.getAnswer())
.sources(answer.getSources())
.latencyMs(answer.getTotalTimeMs())
.build();
}
}QueryClassifier实现
@Service
public class QueryClassifier {
private final ChatClient fastClient;
private static final String CLASSIFICATION_PROMPT = """
请分析以下问题属于哪种类型,只回复类型名称:
- FACTUAL: 查找具体事实、数据、条款(如"这份合同的违约金是多少")
- GLOBAL_ANALYSIS: 需要理解整个文档才能回答(如"总结这份合同的主要风险")
- SUMMARIZATION: 摘要类问题(如"这份报告的核心结论是什么")
- COMPARISON: 比较类问题(如"A和B方案哪个更好")
- REASONING: 需要推理的问题(如"根据这些条款,甲方是否违约")
问题:{question}
类型(只回复类型名称):
""";
public QueryType classify(String question) {
try {
String typeStr = fastClient.call(
CLASSIFICATION_PROMPT.replace("{question}", question)
).trim().toUpperCase();
return QueryType.valueOf(typeStr);
} catch (Exception e) {
// 分类失败时默认为FACTUAL
return QueryType.FACTUAL;
}
}
}2026年的最佳实践建议
郑磊在搞定了这套测试体系后,在架构评审上给了刘总一份系统性的回答。以下是他总结的2026年最佳实践:
实践1:不要非此即彼
Long Context和RAG不是竞争关系,而是互补关系。系统设计时,两者都应该在工具箱里。
实践2:用问题类型驱动选型
不是文档越少就越应该用Long Context,关键是问题类型。"这份合同哪里有风险?"(全局分析)适合Long Context。"合同的违约赔偿金额是多少?"(精确查询)适合RAG。
实践3:成本预算先行
在系统设计阶段,必须先算清楚:预期日查询量 × 每次查询Token数 × 模型价格 = 月成本。超过可接受范围的方案,技术上再好用也没用。
实践4:混合方案是甜蜜点
对于大多数企业知识库场景,混合方案(RAG粗检索20个chunk + LLM精读)是性价比最高的选择。它比纯Long Context便宜10倍以上,比纯RAG准确率高5-10个百分点。
实践5:建立评估框架
无论选哪种方案,都要建立评估体系(见article-129)。你的"感觉更好",可能只是安慰剂效应。
生产注意事项
Context Window溢出处理
@Service
public class ContextWindowManager {
// GPT-4o 128K token,留20K给输出
private static final int MAX_CONTEXT_TOKENS = 108_000;
/**
* 当上下文超出窗口时,智能截断
* 策略:优先保留高相关性内容,截断低相关性内容
*/
public String truncateContext(List<Document> documents, int maxTokens) {
// 按相关性降序排列
documents.sort((a, b) -> {
double scoreA = (Double) a.getMetadata().getOrDefault("relevance_score", 0.0);
double scoreB = (Double) b.getMetadata().getOrDefault("relevance_score", 0.0);
return Double.compare(scoreB, scoreA);
});
StringBuilder context = new StringBuilder();
int usedTokens = 0;
for (Document doc : documents) {
int docTokens = estimateTokens(doc.getContent());
if (usedTokens + docTokens > maxTokens) {
// 超出窗口,截断当前文档(只取开头)
int remainingTokens = maxTokens - usedTokens;
if (remainingTokens > 100) { // 至少留100 token才值得加
String truncated = truncateToTokens(doc.getContent(), remainingTokens);
context.append(truncated).append("\n[内容因长度限制被截断]\n");
}
break;
}
context.append(doc.getContent()).append("\n\n");
usedTokens += docTokens;
}
return context.toString();
}
}常见问题解答
Q1:128K Token够用吗?还是应该用Gemini的1M Token?
128K Token约合10万中文字,对于单个文档或小型知识库够用。如果你的场景需要同时处理数百页文档,1M Token模型才有意义,但成本也更高。建议先从RAG开始,再按需评估是否要升级到更大上下文。
Q2:Long Context精度问题在新版模型上是否已经解决了?
2026年的模型比2023年好很多,但"中间遗忘"问题仍然存在,只是程度减轻了。郑磊的测试数据是在GPT-4o上跑的,中间位置准确率68%,这已经是比较新的模型了。
Q3:RAG + Long Context混合方案的实现复杂度高吗?
不高。核心是:先用向量检索拿到top-20个chunk,然后把这20个chunk拼接成上下文,再用LLM回答。Spring AI框架可以很快速地实现这个流程,参考本文代码。
Q4:什么情况下应该考虑放弃RAG改用Long Context?
当你的知识库非常小(<100页)、更新频率极低(月一次或更少)、且对成本不敏感时,Long Context可以减少系统复杂度。MVP阶段也可以先用Long Context验证产品方向。
Q5:如何测试我的场景适合哪种方案?
准备100-200个标注了标准答案的测试问题,分别用三种方案跑一遍,比较准确率、延迟和成本。用数据说话,别凭感觉。
Q6:混合方案里的Reranker该怎么选?
Cohere Rerank API是最简单的选择,效果好、接入快。开源方案可以考虑BGE-Reranker。如果预算有限,用LLM打分也是可行的替代方案(但会增加延迟)。
总结
Long Context和RAG各有其位置,关键是找准场景边界。
行动清单:
RAG没有死,但它需要你更清楚地知道它该在哪里用,不该在哪里用。
