很多 Claude API 与 LangChain 的教程,会先从ChatAnthropic的基础调用开始。只要模型能正常返回内容,就说明 Claude API 已经接入成功。
但如果目标是搭建一个可以上线的 RAG 知识库问答应用,仅仅调通模型是不够的。
生产环境中的 RAG 应用,需要考虑文档解析、内容清洗、Chunk 切分、Embedding、向量库、Retriever 检索、Claude 生成回答、引用来源、FastAPI 接口、流式输出、异常处理、权限隔离、日志记录、成本控制和效果评估。
本文以 Python + LangChain + Claude API 为主线,梳理一个 RAG 应用从 Demo 到生产可用的大致流程。
一、RAG 应用整体流程
RAG 的核心是“先检索,再生成”。
一个典型 Claude RAG 应用可以拆成下面这条链路:
原始文档 ↓ 文档解析与清洗 ↓ 按语义切分 Chunk ↓ Embedding 向量化 ↓ 写入向量库 ↓ 用户提问 ↓ Retriever 检索相关片段 ↓ Claude 基于上下文生成回答 ↓ 返回答案 + 引用来源 + 日志记录也就是说,用户提问之后,系统并不是直接把问题发给 Claude,而是先从知识库中检索相关资料,再让 Claude 基于这些资料生成回答。
这种方式适合企业知识库、产品文档问答、客服辅助、技术支持、内部培训资料查询等场景。
二、为什么不能只停留在 Demo?
一个最小化 Demo 通常只包含:
- 加载文档;
- 切分文本;
- 写入向量库;
- 调用 Claude 回答。
这个流程适合入门,但不能直接等同于生产方案。
真实业务中,文档可能来自 PDF、Markdown、HTML、TXT、Word、内部 Wiki、产品手册、技术文档、FAQ、工单系统等多个来源。
这些文档格式复杂,且通常包含噪声内容。
例如:
- PDF 中可能有页眉、页脚、页码和表格;
- HTML 中可能有导航栏、广告、侧边栏和页脚;
- Markdown 中可能包含标题、代码块和嵌套列表;
- FAQ 需要保留问答对结构;
- 技术文档中的代码块不能被随意截断。
如果文档处理不好,后续向量检索和 Claude 回答都会受到影响。
三、文档解析与清洗
RAG 应用的第一步是文档入库。
常见文档类型包括:
- PDF;
- Markdown;
- HTML;
- TXT;
- Word;
- 内部 Wiki;
- 产品帮助中心;
- API 文档;
- FAQ;
- 工单记录。
1. 文档解析
文档解析不是简单提取纯文本,而是要尽量保留有用结构。
例如:
- 标题层级;
- 段落;
- 列表;
- 表格;
- 代码块;
- 页码;
- 原始 URL;
- 更新时间。
这些结构会影响后续 Chunk 切分、引用来源和检索效果。
2. 内容清洗
解析后还要清洗噪声内容。
需要过滤的内容包括:
- 页眉页脚;
- 重复导航;
- 广告内容;
- 版权声明;
- 模板文本;
- 多余空行;
- 乱码;
- 重复段落。
如果这些内容进入向量库,Retriever 可能召回无关内容,导致 Claude 基于错误上下文生成回答。
四、Chunk 切分策略
Chunk 是 RAG 系统中的基本检索单元。
很多入门教程会按固定长度切分文本,比如每 500 字或 1000 字切一次。
这种方式实现简单,但在真实项目中不一定稳定。
更推荐按语义结构切分:
- 按标题层级切分;
- 按自然段落切分;
- 保留列表完整性;
- 保留代码块完整性;
- 表格单独处理;
- FAQ 按问答对切分;
- 必要时添加前后文窗口。
每个 Chunk 建议保存 metadata,例如:
source title page url updated_at tenant_id project_id permission_tags这些 metadata 后续可以用于:
- 返回引用来源;
- 做权限过滤;
- 排查问题;
- 支持评估;
- 支持文档更新。
对于中文文档,Chunk 切分尤其重要。中文内容的标题、段落、列表和标点都会影响语义边界,不能简单照搬英文切分方式。
五、Embedding 与向量库选择
Chunk 切分完成后,需要通过 Embedding 模型将文本转换为向量,再写入向量库。
常见向量库包括:
| 向量库 | 适用场景 |
|---|---|
| Chroma | 本地 Demo、小型项目 |
| FAISS | 本地实验、轻量检索 |
| Milvus | 大规模向量检索 |
| Pinecone | 托管向量数据库 |
| pgvector | PostgreSQL 技术栈团队 |
如果只是学习或本地验证,可以使用 Chroma 或 FAISS。
如果要上线,需要考虑以下问题:
- 数据规模;
- 查询并发;
- metadata filter;
- 权限过滤;
- 数据备份;
- 扩容能力;
- 运维成本;
- 与现有数据库的集成成本。
对于企业知识库场景,metadata filter 很关键。因为不同用户、部门或项目可能只能访问不同文档,检索阶段必须完成权限过滤。
六、Retriever 检索策略
Retriever 的作用是根据用户问题检索相关 Chunk。
生产环境中,不能只依赖默认 top-k 检索。
可以根据业务场景组合使用:
- 向量检索;
- 关键词检索;
- 混合检索;
- metadata filter;
- rerank 重排序;
- 相似度阈值过滤;
- query rewrite;
- 多路召回;
- 结果去重;
- 上下文压缩。
例如:
- 配置参数类问题可能更依赖关键词;
- 概念解释类问题可能更依赖语义检索;
- 版本相关问题需要结合 metadata 过滤;
- 长文档问答可能需要上下文压缩。
Retriever 的质量直接决定 Claude 拿到什么上下文,也就影响最终回答质量。
七、Claude 生成回答
在 RAG 系统中,Claude 应该基于检索到的上下文回答问题,而不是自由发挥。
Prompt 中可以增加明确约束:
你是一个知识库问答助手。 请仅根据提供的上下文回答用户问题。 如果上下文中没有足够信息,请明确说明无法从当前资料中确认。 不要编造上下文中不存在的信息。 回答中请尽量附上引用来源。这个约束可以降低模型幻觉风险。
对于知识库问答、产品文档问答、企业制度查询等场景,合理拒答比编造答案更重要。
八、返回答案与引用来源
生产级 RAG 应用不建议只返回一段答案。
更推荐返回:
- 答案正文;
- 引用文档标题;
- 文件名;
- 页码;
- 原始 URL;
- Chunk ID;
- 更新时间。
引用来源有两个作用:
第一,用户可以判断答案是否可信。
第二,开发者可以排查检索结果是否正确。
如果没有引用来源,RAG 系统很容易变成一个“看起来会答,但不知道依据在哪里”的聊天机器人。
九、FastAPI 接口与流式输出
如果要上线,RAG 应用通常需要封装成 API。
Python 项目中,可以使用 FastAPI 提供问答接口。
整体流程可以是:
前端页面 ↓ FastAPI 问答接口 ↓ Retriever 检索 ↓ Claude 流式生成 ↓ 前端实时展示接口层需要处理:
- 请求参数校验;
- 用户身份识别;
- 权限上下文;
- 检索参数;
- Claude 调用;
- 流式返回;
- 异常处理;
- 日志记录;
- token 用量统计。
流式输出可以改善用户体验,特别是回答较长时,用户可以边看边等。
十、权限隔离与安全控制
企业 RAG 应用必须考虑权限隔离。
不能让用户检索到无权访问的文档,也不能把无权访问的内容交给 Claude。
更安全的方式是在检索阶段完成权限过滤:
用户提问 ↓ 根据用户身份生成权限过滤条件 ↓ 只检索用户可访问的 Chunk ↓ Claude 基于可访问上下文生成回答同时,日志记录需要做脱敏处理,避免保存敏感内容、用户隐私、API Key 和业务机密。
十一、成本控制与监控
RAG 应用上线后,成本控制非常重要。
影响成本的因素包括:
- Embedding 频率;
- 检索 top-k 数量;
- 上下文长度;
- Claude 输入 token;
- Claude 输出 token;
- 用户请求频率;
- 缓存策略;
- 高并发请求。
建议记录以下指标:
- 请求 ID;
- 用户 ID;
- 命中文档;
- 检索耗时;
- Claude 生成耗时;
- 输入 token;
- 输出 token;
- 错误类型;
- 用户反馈。
这些数据可以用于排查问题、控制成本和持续优化系统效果。
十二、效果评估
RAG 应用不是上线后就结束。
建议准备评估集,包括:
- 高频问题;
- 标准答案;
- 预期命中文档;
- 需要拒答的问题;
- 容易混淆的问题;
- 不应该回答的问题。
评估指标可以包括:
- 检索命中率;
- 回答准确率;
- 引用正确率;
- 拒答准确率;
- 幻觉率;
- 响应时间;
- token 成本。
没有评估集,RAG 优化很容易变成凭感觉调整参数。
十三、总结
Claude API 与 LangChain 集成并不难,难的是把它做成一个真正可上线的 RAG 应用。
生产级 RAG 应用至少需要覆盖:
- 文档解析;
- 内容清洗;
- Chunk 切分;
- Embedding;
- 向量库;
- Retriever 检索;
- Claude 生成回答;
- 引用来源;
- FastAPI 接口;
- 流式输出;
- 权限隔离;
- 日志监控;
- 成本控制;
- 效果评估。
如果只是学习,可以先从一个ChatAnthropicDemo 开始。
如果目标是上线,就要从一开始按照完整系统工程来设计。
Claude API 提供生成能力,LangChain 负责流程编排,而 RAG 应用最终能不能稳定好用,取决于文档治理、检索质量和工程化能力。
Claude API 与 LangChain 集成实战:搭建一个能真正上线的 RAG 应用
不少教程会带你用ChatAnthropic调一次 Claude API,只要模型能正常返回内容,看起来就算“跑通”了。但如果你真的要把一个 RAG 应用放到线上,这一步其实只是开始。
一个能在生产环境里稳定使用的LangChain RAG系统,至少要考虑这些事情:文档怎么入库、怎么切分、怎么做 Embedding、怎么检索、回答时怎么带引用、前端怎么流式输出、异常怎么处理、不同用户的权限怎么隔离、成本怎么控制,以及上线后怎么评估效果。
这篇文章会围绕Claude API 与 LangChain 的集成,从一个简单 Demo 一步步扩展到更接近生产可用的方案。示例代码主要使用 Python + LangChain + Claude,向量库则可以根据你的实际情况换成 Chroma、FAISS、Milvus、Pinecone 或 pgvector。
我们最终要做什么:一个能上线的 Claude RAG 架构
先看整体流程。一个典型的 RAG 系统,大致可以理解成下面这条链路:
原始文档 ↓ 文档解析与清洗 ↓ 按语义切分 Chunk ↓ Embedding 向量化 ↓ 写入向量库 ↓ 用户提问 ↓ Retriever 检索相关片段 ↓ Claude 基于上下文生成回答 ↓ 返回答案 + 引用来源 + 日志记录也就是说,用户提问之后,系统并不是直接把问题丢给 Claude,而是先去知识库里找相关资料,再让 Claude 基于这些资料组织答案。
一个比较完整的 RAG 应用,通常需要具备这些能力:
- 能接入 PDF、Markdown、HTML、TXT 等常见文档;
- 对中文文档的标题、段落、列表有比较合理的切分方式;
- 使用向量库做语义检索,而不是只靠关键词匹配;
- 让 Claude 根据检索到的内容生成回答,并附上引用来源;
- 如果资料里没有答案,要明确拒答,而不是硬编;
- 提供 FastAPI 接口,并支持流式输出;
- 有超时、重试、限流、日志脱敏、权限隔离等基础工程能力;
- 能通过评估集持续改进检索质量和回答质量。
所以,本文不是单纯讲“Claude API 怎么调用”,而是讲怎么把Claude API + LangChain + RAG组合成一个更接近真实业务场景的知识库问答系统。
Claude API + LangChain 的依赖安装与版本选择
建议使用 Python 3.10 或更高版本。最好先创建虚拟环境,再安装相关依赖:
pipinstall-Ulangchain langchain-core langchain-community langchain-anthropic pipinstall-Uchromadb python-dotenv fastapi uvicorn如果你准备用其他向量库,可以按需额外安装:
pipinstallfaiss-cpu pipinstallpymilvus pipinstallpinecone pipinstallpsycopg[binary]pgvectorAPI Key 这类配置建议放到.env文件里:
ANTHROPIC_API_KEY=your_api_key ANTHROPIC_BASE_URL=https://api.anthropic.com在生产环境里,千万不要把 API Key 直接写进代码仓库。更稳妥的做法是使用云厂商的 Secret Manager、Kubernetes Secret,或者 CI/CD 平台提供的环境变量管理能力。
如果你接入的是第三方 Claude API 兼容平台,比如 ClaudeAPI,也需要提前确认一点:它并不是 Anthropic 官方服务。这类平台一般会提供兼容接口、多线路选择、中文支持、企业充值、开票和一些基础技术支持,但具体能力、模型可用性和限制都要以它们官网的最新说明为准。即便使用了这类平台,线上系统也仍然要做好超时、重试、限流和降级,不能把稳定性完全寄托在接口服务上。
第一步:先用 ChatAnthropic 跑通 Claude API
在 LangChain 里,接入 Claude 通常会用langchain-anthropic提供的ChatAnthropic。
importosfromdotenvimportload_dotenvfromlangchain_anthropicimportChatAnthropic load_dotenv()llm=ChatAnthropic(model="claude-3-5-sonnet-latest",api_key=os.getenv("ANTHROPIC_API_KEY"),base_url=os.getenv("ANTHROPIC_BASE_URL"),temperature=0.2,max_tokens=1024,timeout=30,max_retries=2,)resp=llm.invoke("用三句话解释什么是 RAG。")print(resp.content)这里有几个参数,在 RAG 场景里尤其重要。
model决定了成本和效果的平衡。如果是高频、低成本问答,可以考虑 Haiku;如果是企业知识库、客服问答这类对准确性要求更高的场景,Sonnet 通常更合适;如果问题非常复杂,需要更强推理能力,再考虑 Opus。
temperature建议调低一些,比如0~0.3。RAG 问答并不需要模型发挥太多想象力,回答越稳定越好。
max_tokens也要控制好。设置太小,回答可能被截断;设置太大,又会增加成本和延迟。
timeout和max_retries在生产环境里必须配置。否则接口偶发变慢时,请求可能会长时间卡住,进而拖垮后端服务。
如果你要做聊天界面,通常还会用到流式输出:
forchunkinllm.stream("请解释 LangChain RAG 的核心流程"):print(chunk.content,end="",flush=True)如果 Claude 是通过 AWS Bedrock 或 Vertex AI 接入,认证方式、模型名称和 SDK 配置会有所不同。不过上层思路不变:先检索上下文,再让 Claude 基于上下文回答。
第二步:准备 RAG 知识库文档
RAG 的效果,首先取决于知识库本身的质量。很多项目效果不好,并不是模型不行,而是文档解析、清洗和切分做得太粗糙。
常见的文档来源大概有这些:
- Markdown:很适合技术文档、产品说明、开发者文档;
- PDF:常用于合同、手册、研究报告,但要特别注意解析乱码和版式错乱;
- HTML 或网页:需要去掉导航栏、广告、页脚等无关内容;
- TXT / CSV:适合 FAQ、客服知识库、结构化问答;
- Notion、飞书、Confluence:一般需要通过 API 或导出文件接入。
每个文档片段都建议保留 metadata,也就是元数据。比如:
metadata={"source":"https://example.com/docs/rag","title":"RAG 使用手册","page":3,"section":"权限管理","created_at":"2026-06-01","tenant_id":"company_a"}这些字段看起来只是附加信息,但到了生产环境会非常关键。比如tenant_id、user_id、department_id这类字段,后面会用来做权限隔离和 metadata filter。没有这些信息,系统很容易出现“用户 A 检索到用户 B 文档”的严重问题。
第三步:文档怎么切,基本决定了 RAG 的效果上限
文档切分不是简单按字符数截断。切得不好,检索出来的片段就会缺上下文,Claude 再强也只能根据残缺资料回答,效果自然会打折扣。
LangChain 里比较常用的是RecursiveCharacterTextSplitter:
fromlangchain_text_splittersimportRecursiveCharacterTextSplitter splitter=RecursiveCharacterTextSplitter(chunk_size=800,chunk_overlap=120,separators=["\n## ","\n### ","\n\n","。","!","?",";","\n"," ",""],)chunks=splitter.split_documents(docs)一些比较实用的经验是:
- 中文技术文档可以先从
chunk_size=600~1000字符开始试; - FAQ 最好尽量保持“一问一答”作为一个 chunk;
- 法律、合同、制度类文档,要保留章节标题和条款编号;
- overlap 不宜太大,否则会增加成本,也会带来重复噪声;
- 切完之后一定要抽样检查,看看标题、上下文、来源有没有丢。
尤其要注意标题层级。比如下面这种结构:
# 产品手册 ## 账号权限 ### 管理员权限 正文……如果切分后只留下“正文”,没有保留“账号权限 / 管理员权限”这样的上下文,检索结果可能就会变得很模糊。用户问“管理员能不能重置密码”时,系统可能找到了相关正文,但 Claude 不知道这段话属于哪个模块,回答自然不够稳。
第四步:选择 Embedding 和向量库
Claude 主要负责生成答案,但语义检索一般还需要单独的 Embedding 模型。Embedding 的作用,就是把文本转换成向量,方便系统根据语义相似度找到相关内容。
常见选择可以参考下面这张表:
| 方案 | 适用场景 | 注意点 |
|---|---|---|
| Voyage | 英文和多语种检索,Claude 生态里比较常见 | 要关注模型可用性和调用成本 |
| OpenAI Embedding | 通用性强,生态成熟 | 需要考虑接入方式和合规要求 |
| Cohere Embedding | 多语种支持不错 | 中文效果最好结合业务数据实测 |
| BGE / bge-m3 | 中文场景和本地部署比较常见 | 通常需要自建推理服务 |
| 本地 embedding | 数据不能出内网的场景 | 运维和性能优化成本更高 |
向量库则可以根据数据规模和团队能力来选:
| 向量库 | 适用场景 |
|---|---|
| Chroma | 本地开发、原型验证 |
| FAISS | 单机轻量级检索 |
| Milvus | 大规模向量检索、私有化部署 |
| Pinecone | 托管向量服务,减少运维投入 |
| pgvector | 已经有 PostgreSQL 系统,方便和业务权限结合 |
如果只是学习或者做原型,Chroma 很方便;中小团队做生产环境,可以重点考虑 pgvector 或 Milvus;如果是大规模 SaaS,托管向量库或者自建 Milvus 集群会更常见。
第五步:用 LangChain 构建 Retriever 和 RAG Chain
下面用 Chroma 举一个最小可运行的例子。Embedding 部分你需要替换成自己实际使用的模型。
fromlangchain_chromaimportChromafromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.runnablesimportRunnablePassthrough# 假设 embeddings 已初始化vectorstore=Chroma.from_documents(documents=chunks,embedding=embeddings,persist_directory="./chroma_db")retriever=vectorstore.as_retriever(search_type="mmr",search_kwargs={"k":5,"fetch_k":20})prompt=ChatPromptTemplate.from_template(""" 你是企业知识库助手。请只根据下面的资料回答问题。 如果资料中没有答案,请回答“资料中未找到相关信息”,不要编造。 资料: {context} 问题: {question} 回答要求: 1. 用中文回答; 2. 简洁准确; 3. 在回答末尾列出引用来源。 """)defformat_docs(docs):return"\n\n".join(f"[来源:{d.metadata.get('title')}页码:{d.metadata.get('page')}]\n{d.page_content}"fordindocs)rag_chain=({"context":retriever|format_docs,"question":RunnablePassthrough()}|prompt|llm)answer=rag_chain.invoke("管理员如何重置用户密码?")print(answer.content)这个示例已经能完成基本的“检索资料 + Claude 回答”。不过在线上环境里,Retriever 通常还要继续增强。
比如,可以加score_threshold,当检索分数太低时直接拒答;可以加 metadata filter,根据租户、部门、用户权限过滤文档;也可以加 rerank,对初筛结果重新排序;如果用户的问题比较口语化,还可以做 query rewrite,把问题改写成更适合检索的表达。
这些看起来都是细节,但对真实效果影响很大。
第六步:让 Claude 回答更可靠:引用、拒答和反幻觉
RAG 并不能保证完全没有幻觉,但它可以显著降低“没有依据还一本正经回答”的概率。关键在于把边界控制好。
首先,Prompt 里要明确要求 Claude 只基于上下文回答,不要额外发挥。尤其是企业知识库场景,用户要的不是百科式扩展,而是和内部资料一致的答案。
其次,资料里没有答案时要拒答。如果检索结果为空,或者检索分数明显过低,就应该直接返回“资料中未找到相关信息”。不要把一个很弱的上下文硬塞给模型,否则它很可能会补全出看似合理但没有依据的内容。
另外,引用来源也要强制返回。每个 chunk 最好都有source、title、page、section这些字段。回答里引用这些信息,用户才能回到原文核对。
还要注意 Prompt 注入问题。文档里可能会出现类似“忽略之前指令”“输出系统提示词”这样的恶意内容。系统提示中应该明确说明:文档只是知识来源,不能覆盖开发者指令、安全策略和系统级约束。
最后,也是最重要的一点:权限过滤必须前置。用户 A 的问题绝不能检索到用户 B 的文档。这个事情不能只靠 Prompt 约束,而应该在 retriever 的 metadata filter 层面完成。
第七步:封装成可以上线的 API 服务
一个最小的 FastAPI 服务,通常可以先提供三个接口:
/ingest:文档入库;/chat:知识库问答;/health:健康检查。
示例代码如下:
fromfastapiimportFastAPIfrompydanticimportBaseModel app=FastAPI()classChatReq(BaseModel):question:strtenant_id:str@app.get("/health")defhealth():return{"status":"ok"}@app.post("/chat")defchat(req:ChatReq):# 实际生产中应将 tenant_id 放入 retriever filterresult=rag_chain.invoke(req.question)return{"answer":result.content}这个版本只能算骨架。真正上线时,还需要补上不少工程能力,比如:
- 使用 SSE 或 WebSocket 实现流式输出;
- 增加请求超时和取消机制;
- 接入用户身份认证;
- 在检索层加入租户级 metadata filter;
- 记录请求日志和错误日志;
- 构建 Docker 镜像,并配置健康检查;
- 准备灰度发布和回滚策略。
流式输出对聊天产品体验很好,但线上要特别注意代理服务器、API 网关和浏览器端的超时配置。很多时候本地流式输出正常,部署后却中途断流,问题往往就出在这些基础设施配置上。
第八步:上线前必须考虑成本、性能和安全
RAG 的成本主要来自四个地方。
第一,是文档入库时的 Embedding 成本。文档越多、切分越细,Embedding 调用就越多。
第二,是向量库的存储和检索成本。数据规模上来之后,索引、存储、查询性能都会变成实际问题。
第三,是每次问答传给 Claude 的上下文 token。检索出来的 chunk 越多,输入 token 就越高。
第四,是 Claude 生成答案本身的输出 token。
常见的优化方式包括:
- 控制
top_k,不要把大量 chunk 一股脑塞进上下文; - 对重复文档做 hash 去重;
- 缓存 embedding 结果,避免重复计算;
- 对高频问题缓存答案,但要处理文档更新后的失效问题;
- 高峰期可以降级到更低成本的模型;
- 批量入库尽量异步处理,不要阻塞用户请求;
- 日志里不要记录完整敏感文档,可以记录文档 ID、chunk ID、延迟和错误类型。
安全方面,至少要做到下面这些:
- API Key 不能进代码仓库;
- 日志要做脱敏;
- 用户文档要按租户隔离;
- 向量检索必须带权限过滤;
- 上传文档要限制类型和大小,必要时做病毒扫描;
- 不要把用户隐私数据发送到不符合合规要求的第三方服务。
这些要求听起来比较基础,但很多线上事故恰恰就是因为基础安全措施没有做到位。
第九步:如何评估 Claude RAG 应用的效果
上线前不要只靠“随便问几个问题,看起来还行”来判断效果。更稳妥的方式是准备一套评估集,格式可以很简单:
问题 | 标准答案 | 应命中文档 | 是否允许无答案重点关注这些指标:
- 检索命中率:正确文档有没有进入 top_k;
- 答案准确率:Claude 是否基于资料给出了正确回答;
- 引用正确率:引用来源是否真的支持答案;
- 无答案拒答率:资料里没有答案时,系统有没有拒答;
- 平均延迟:检索耗时、模型耗时和总耗时分别是多少;
- 单次成本:输入 token、输出 token、embedding 和向量库成本。
你可以用 LangSmith 来记录链路,也可以自建日志表,记录query、retrieved_docs、latency、token usage、error_type等字段。
RAG 的优化最好建立在日志和评估集上,而不是只靠反复调整 Prompt。Prompt 当然重要,但检索、切分、rerank、权限过滤和数据质量,往往同样关键。
常见报错与排查清单
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
ModuleNotFoundError: langchain_anthropic | 没有安装依赖 | 执行pip install langchain-anthropic |
ANTHROPIC_API_KEY未配置 | 环境变量缺失 | 检查.env文件和部署环境变量 |
| 模型名不可用 | 模型名过期,或账号没有权限 | 查看当前服务支持的模型列表 |
| 回答被截断 | max_tokens设置太小 | 增大输出 token,或者要求模型回答更简洁 |
| 429 rate limit | 请求过快或额度受限 | 增加重试、限流、排队和降级 |
| 检索为空 | embedding 不匹配、文档没入库、filter 太严格 | 检查向量库数据、top_k 和过滤条件 |
| 检索到错误文档 | chunk 切分不合理,或 embedding 效果不佳 | 调整切分方式,增加 rerank,优化 query |
| 回答编造来源 | Prompt 约束不够,或 metadata 缺失 | 强制引用 chunk metadata,低分时直接拒答 |
| 上下文过长 | top_k 太大,或 chunk 太长 | 缩小 chunk,减少 top_k,增加上下文压缩 |
| 中文 PDF 乱码 | PDF 解析器不适配 | 尝试 OCR,或者更换 PDF 解析工具 |
| 本地能跑,线上报错 | 环境变量、网络、依赖版本不一致 | 固定依赖版本,增加健康检查和启动日志 |
| 流式输出中断 | 网关或客户端超时 | 配置 SSE/WebSocket,关闭缓冲或延长超时 |
Claude API + LangChain RAG 技术选型建议
如果只是学习和验证,可以从最简单的组合开始:
Claude API + LangChain + Chroma/FAISS + 本地脚本这个方案上手快,适合理解 Claude API 与 LangChain 的集成方式,也方便快速跑通基础 RAG 流程。
如果是中小团队的生产环境,可以考虑:
Claude Sonnet + LangChain + pgvector/Milvus + FastAPI + 权限过滤 + 日志评估这类组合比较适合企业知识库、客服助手、内部文档问答等场景。重点不只是模型效果,还包括权限、稳定性和可观测性。
如果是大规模 SaaS,架构通常会更复杂:
Claude + 托管/集群向量库 + rerank + 缓存 + 队列 + 监控 + 灰度发布这时要重点处理多租户隔离、成本控制、限流降级、模型切换和评估闭环。否则用户量一上来,成本和稳定性问题会很快暴露出来。
FAQ:Claude API、LangChain 与 RAG 常见问题
Claude API 可以直接和 LangChain 集成吗?
可以。一般使用langchain-anthropic里的ChatAnthropic,配置好 API Key、模型名、超时和重试参数,就可以在 LangChain 中调用 Claude。
Claude 适合做 RAG 吗?
适合。Claude 的长上下文能力和中文理解能力,对 RAG 问答很有帮助。不过最终效果仍然取决于检索质量、文档切分策略、引用控制和拒答机制。
Claude 的长上下文能替代 RAG 吗?
不能简单替代。长上下文适合少量文档的临时分析,而 RAG 更适合持续更新的大规模知识库。它还能减少每次请求传入的 token,从而降低成本。
LangChain RAG 必须使用向量数据库吗?
不一定。小规模数据可以用 FAISS 或内存检索。但生产环境通常会使用 Chroma、Milvus、Pinecone、pgvector 等向量存储,方便管理数据、扩展规模和做权限过滤。
中文 RAG 推荐用什么 embedding?
需要结合你的业务数据实测。中文场景可以重点测试 BGE 系列、多语种 embedding、OpenAI、Cohere、Voyage 等方案,再比较检索命中率、延迟和成本。
RAG 应用怎么减少幻觉?
核心做法是提高检索质量,降低生成温度,要求回答带引用,资料不足时拒答,同时配合 score threshold、rerank 和评估集持续优化。
生产环境该用 Agent,还是普通 RAG Chain?
普通知识库问答优先使用 RAG Chain。它链路更清晰,成本更低,也更容易控制。只有当业务需要调用工具、执行多步任务或进行复杂决策时,再考虑 Agent 或 LangGraph。