大模型应用开发核心:Langchain、RAG、Agent与向量数据库Milvus实战解析

📅 2026/8/12 18:24:34
大模型应用开发核心:Langchain、RAG、Agent与向量数据库Milvus实战解析
最近在准备大模型相关的面试发现很多同学对 Langchain、Milvus、RAG、Agent、FDE 这些核心概念和技术栈的理解还停留在表面面试时一旦被问到原理、实现细节和工程实践就容易卡壳。本文结合高频面试题和实战经验系统梳理这五大技术模块的核心知识点、常见面试问题、避坑指南和最佳实践帮你构建完整的知识体系无论是准备面试还是项目落地都能直接参考。1. 背景与核心概念为什么是这五个技术在 AI 大模型应用开发领域Langchain、Milvus、RAG、Agent 和 FDE 是构建复杂、实用系统的核心支柱。它们分别解决了不同层面的问题共同构成了从数据准备、模型调用到智能决策的完整链路。Langchain是一个用于开发由语言模型驱动的应用程序的框架。它不是一个具体的模型而是一个“粘合剂”和“脚手架”核心价值在于提供了标准化的接口如 LLM、记忆、工具、链和丰富的组件让开发者能够以模块化的方式编排大模型的能力快速构建复杂的应用如问答系统、摘要工具、代码生成器等。面试常问其与 LangGraph 的区别简单来说Langchain 侧重于链式调用而 LangGraph 基于状态机更适合有复杂循环、分支和状态管理的 Agent 场景。Milvus是一个开源的向量数据库。大模型如 GPT、文心一言本身并不擅长记忆海量、实时的私有知识也无法进行精确的数值比较如相似度搜索。Milvus 的职责就是高效存储和检索文本、图像等数据对应的向量即 Embedding是实现 RAG 和语义搜索的基石。面试会深入其架构如 Segment 数据分片、混合检索结合标量过滤和向量搜索以及分布式集群部署的考量。RAG代表检索增强生成。这是当前解决大模型“幻觉”胡编乱造和知识滞后问题的核心技术范式。其核心流程是用户提问 - 从知识库如 Milvus中检索相关文档片段 - 将问题和检索到的片段一起交给大模型 - 模型基于给定的“证据”生成答案。这保证了答案的准确性和可追溯性。面试官会关注 RAG 的全流程细节包括文档切分、向量化、检索策略、重排序以及如何评估 RAG 系统的效果。Agent即智能体。如果说链是预定义的固定流程那么 Agent 则具备自主规划、调用工具、持续执行的能力。它接收一个高级目标如“分析上季度销售数据并写份报告”然后自主拆解任务决定调用哪个工具如搜索、计算、写文档并循环执行直到完成。面试重点在于 Agent 的框架如 ReAct 模式、工具定义、记忆机制以及如何避免陷入死循环。FDE是一个相对较新的概念在不同语境下有不同含义。在 AI 工程领域它常指Frontend, Decision Engine或与特定框架相关的概念。结合面试场景它可能指代Function Calling, Decision, Execution的循环即智能体决策执行框架的一部分或者是某个企业内部 AI 平台如 Hermes Agent的架构组件。面试中遇到需要结合上下文厘清其具体指代核心是理解其作为连接意图识别、决策与具体工具执行的桥梁作用。掌握这五项技术意味着你不仅能调用 API更能设计并实现一个可靠、高效、可维护的大模型应用系统。2. 环境准备与版本说明在深入具体问题前我们先明确一个可复现的实践环境。以下配置是一个常见的组合但请注意具体版本需根据你的项目需求调整。操作系统: Ubuntu 20.04 LTS / macOS Monterey 或更高 / Windows 10/11 (Windows 下部分服务部署可能更复杂建议开发环境使用 WSL2)。Python: 3.8 - 3.11 版本。3.12 及以上版本需注意某些库的兼容性。核心库版本参考:langchain/langchain-community: 0.1.x 版本。Langchain 版本迭代较快API 变化较大建议锁定版本并仔细阅读对应版本的官方文档。pymilvus: 2.3.x 版本。需与 Milvus 服务端版本匹配。openai: 1.x 版本。注意 V1.x API 与旧版 0.28.x 有重大变化。向量化模型例如sentence-transformers库常用模型all-MiniLM-L6-v2。其他chromadb(可选用于对比学习)fastapi,uvicorn(用于构建简单 API 服务)。Milvus 服务端: 建议使用 2.3.x 稳定版。部署方式有多种Docker 部署推荐用于开发/测试: 最快捷的方式通过 Docker Compose 一键启动包含 Milvus、Etcd 和 MinIO 的完整服务。非 Docker 安装: 适用于生产环境或对资源控制有严格要求的场景需要手动安装并配置 Milvus、Etcd、MinIO/Pulsar 等依赖步骤较为复杂。分布式集群部署: 用于海量数据和高并发场景涉及多个 Milvus 节点、消息队列如 Pulsar/Kafka和对象存储的集群化配置是面试中高级话题。大模型 API: 准备一个可用的 API Key例如 OpenAI GPT-4/3.5-Turbo、 Anthropic Claude、或国内的通义千问、文心一言等。本文示例将使用 OpenAI 格式的 API 进行演示。3. Langchain 核心面试题与实战拆解Langchain 是面试中的重中之重问题往往从使用深入到设计理念。3.1 Langchain 的核心组件与抽象面试官可能会问“Langchain 有哪些核心抽象请举例说明它们是如何协作的。”核心答案: Langchain 通过六大核心抽象降低开发复杂度Models (模型): 对各类大模型LLMs、ChatModels和嵌入模型Embedding Models的抽象。例如ChatOpenAI,HuggingFaceEmbeddings。Prompts (提示词): 管理模板和动态提示词。如ChatPromptTemplate,FewShotPromptTemplate。它解决了硬编码提示词难以维护的问题。Indexes (索引): 用于文档加载、分割和向量化存储是 RAG 的基石。包含DocumentLoader,TextSplitter,VectorStore等。Memory (记忆): 管理对话或应用的状态。如ConversationBufferMemory保存历史对话ConversationSummaryMemory则对长历史进行摘要。Chains (链): 将多个组件或其他链按预定顺序组合起来。LLMChain是最基础的链SequentialChain用于顺序执行RetrievalQA链则封装了 RAG 流程。Agents (智能体): 基于 LLM 自主决定调用哪些工具Tools来完成任务。这是 Langchain 最强大的部分之一。协作示例一个简单的问答链RetrievalQA其内部就包含了VectorStoreRetriever(属于 Indexes)、LLM(属于 Models)、PromptTemplate(属于 Prompts)。Agent 则会使用Tool、LLM和AgentExecutor(一种特殊的 Chain) 来工作。3.2 LCEL (LangChain Expression Language) 与旧式链写法随着 Langchain 发展官方强力推荐使用 LCEL。面试官可能会让你对比两种写法。旧式写法 (0.0.x 风格):from langchain.llms import OpenAI from langchain.prompts import PromptTemplate llm OpenAI(temperature0) prompt PromptTemplate( input_variables[product], template给 {product} 写一个创意标语。, ) chain LLMChain(llmllm, promptprompt) result chain.run(环保咖啡杯) print(result)LCEL 写法 (推荐更声明式、支持流式等高级特性):from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser model ChatOpenAI(modelgpt-3.5-turbo) prompt ChatPromptTemplate.from_template(给 {product} 写一个创意标语。) output_parser StrOutputParser() chain prompt | model | output_parser # 使用管道符组合 # 调用方式1 result chain.invoke({product: 环保咖啡杯}) print(result) # 调用方式2 (流式输出) for chunk in chain.stream({product: 环保咖啡杯}): print(chunk, end, flushTrue)面试要点:LCEL 使用|操作符连接可运行对象Runnable代码更简洁、模块化。LCEL 原生支持invoke,batch,stream,astream_log等统一方法。理解RunnablePassthrough,RunnableParallel等组件用于数据流转。3.3 自定义工具 (Tools) 与智能体 (Agents)这是考察工程能力的关键点。面试题“如何让 Langchain Agent 调用一个查询数据库的工具”步骤与代码示例:定义工具函数使用tool装饰器或继承BaseTool。from langchain.tools import tool from typing import Optional tool def query_user_database(user_id: str, query_field: Optional[str] None) - str: 根据用户ID查询用户数据库。可以指定查询的字段如‘name‘, ’email‘默认返回所有信息。 Args: user_id: 用户的唯一标识符。 query_field: 可选要查询的特定字段。 Returns: 用户的查询结果字符串。 # 模拟数据库查询 user_data { 001: {name: 张三, email: zhangsanexample.com, role: admin}, 002: {name: 李四, email: lisiexample.com, role: user} } data user_data.get(user_id, {}) if not data: return f未找到用户ID为 {user_id} 的记录。 if query_field: return str(data.get(query_field, 字段不存在)) return str(data)创建智能体选择 Agent 类型如 OpenAI Functions, ReAct并传入工具列表。from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain_openai import ChatOpenAI from langchain import hub # 拉取一个预设的提示词包含如何思考和使用工具的指令 prompt hub.pull(hwchase17/openai-functions-agent) # 初始化LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 工具列表 tools [query_user_database] # 创建Agent agent create_openai_functions_agent(llm, tools, prompt) # 创建执行器 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue)运行智能体result agent_executor.invoke({ input: 请查询用户ID为 001 的邮箱地址是什么 }) print(result[output]) # 预期输出zhangsanexample.com面试深入问题:工具描述的重要性LLM 仅通过工具函数的docstring来决定是否以及如何调用它因此描述必须清晰准确。错误处理handle_parsing_errorsTrue可以防止因 LLM 输出格式错误导致整个 Agent 崩溃。Agent 类型选择OpenAI FunctionsAgent 与 GPT 系列结合较好ReActAgent 更通用但可能需更复杂的提示工程。4. Milvus 向量数据库面试核心Milvus 的面试问题通常围绕其架构、操作和优化展开。4.1 Milvus 基础概念与数据模型面试题“解释一下 Milvus 中的 Collection、Partition、Segment 和 Entity。”核心答案:Collection (集合): 相当于关系数据库中的表是存储向量和标量数据的基本单位。创建时需要定义 Schema包含字段名、数据类型如FloatVector、INT64、VARCHAR。Partition (分区): 一个 Collection 下的逻辑分组用于数据隔离和管理。查询可以限定在特定分区提高效率。类似于按时间或业务分区。Segment (段): 数据持久化的物理单元。Milvus 会将到达的数据在内存中生成一个MemSegment达到一定大小后持久化为Sealed Segment。Segment 是数据压缩、索引构建的基本单位。理解 Segment 是理解 Milvus 数据一致性和查询性能的关键。Entity (实体): 相当于一行记录包含多个字段Field其中必须有一个向量字段。创建 Collection 的代码示例:from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection, utility # 连接 Milvus connections.connect(aliasdefault, hostlocalhost, port19530) # 1. 定义字段 fields [ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue, auto_idTrue), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim768), # 假设向量维度是768 FieldSchema(nametext, dtypeDataType.VARCHAR, max_length1000), FieldSchema(namecategory, dtypeDataType.VARCHAR, max_length50), ] # 2. 定义 Schema schema CollectionSchema(fields, description一个文档知识库集合) # 3. 创建 Collection collection_name my_rag_collection if utility.has_collection(collection_name): utility.drop_collection(collection_name) # 如果存在则删除 collection Collection(namecollection_name, schemaschema) print(fCollection {collection_name} 创建成功。)4.2 索引与查询IVF_FLAT 与 HNSW面试题“Milvus 中 IVF_FLAT 和 HNSW 索引有什么区别如何选择”核心答案:IVF_FLAT (Inverted File with Flat):原理先对向量空间进行聚类形成nlist个聚类中心倒排列表。搜索时先找到距离目标向量最近的nprobe个聚类然后在这些聚类内的所有向量中进行精确比较Flat。特点内存占用相对较小因为只存储原始向量和聚类信息。查询速度取决于nlist和nprobe的平衡。适合内存受限、数据集中等百万级的场景。参数nlist聚类数nprobe搜索的聚类数。HNSW (Hierarchical Navigable Small World):原理基于图算法构建一个层次化的近邻图。搜索时从顶层开始逐层向下导航快速逼近目标向量的近邻。特点查询速度极快尤其是高召回率场景。但构建索引慢内存占用大需要存储图结构。适合查询性能要求极高、数据集规模适中、内存充足的场景。参数M每个节点的最大连接数efConstruction索引构建时的搜索范围ef搜索时的动态候选集大小。选择建议:追求高查询性能且内存充足 -HNSW。内存敏感数据集较大能接受稍慢的查询 -IVF_FLAT或IVF_SQ8量化版牺牲精度换内存。十亿级以上规模 - 考虑DISKANN或分布式方案。创建索引示例:# 为 embedding 字段创建 IVF_FLAT 索引 index_params { metric_type: L2, # 距离度量方式还有 IP内积、Jaccard等 index_type: IVF_FLAT, params: {nlist: 1024} } collection.create_index(field_nameembedding, index_paramsindex_params) print(索引创建成功。) # 加载集合到内存查询前必须加载 collection.load() # 执行向量搜索 search_params {metric_type: L2, params: {nprobe: 10}} vectors_to_search [[0.1]*768] # 假设要搜索的向量 results collection.search( datavectors_to_search, anns_fieldembedding, paramsearch_params, limit5, # 返回 top-5 output_fields[id, text] # 指定返回的字段 ) for hits in results: for hit in hits: print(fID: {hit.id}, 距离: {hit.distance}, 文本: {hit.entity.get(text)})4.3 混合检索与标量过滤面试题“如何在 Milvus 中实现‘先过滤类别再在结果里做向量搜索’”这就是混合检索。Milvus 支持在向量搜索前或后结合标量字段的过滤。代码示例 (搜索前过滤):# 假设我们只想在 ‘技术文档‘ 这个类别里搜索 search_params {metric_type: L2, params: {nprobe: 10}} # 使用 expr 参数进行标量过滤 results collection.search( datavectors_to_search, anns_fieldembedding, paramsearch_params, limit5, exprcategory 技术文档, # 关键搜索表达式 output_fields[id, text, category] )面试要点:expr参数支持丰富的布尔表达式and,or,in等。过滤发生在向量搜索之前可以大幅减少搜索空间提升性能。确保过滤字段建立了标量索引对于VARCHAR 默认的Trie索引通常足够。5. RAG 全流程实战与高频面试题RAG 的面试问题贯穿整个流水线从数据准备到效果评估。5.1 RAG 流程拆解与关键组件一个完整的 RAG 系统包含以下步骤每一步都有坑点文档加载: 支持 PDF、Word、HTML、Markdown、数据库等。Langchain 提供了大量DocumentLoader。文档分割: 使用TextSplitter。关键是如何设置chunk_size和chunk_overlap。过小丢失上下文过大则检索精度下降且成本高。通常chunk_size500-1000,overlap50-100。向量化: 使用 Embedding 模型将文本块转为向量。选择模型很重要如text-embedding-ada-002,bge-large-zh。存储: 将向量和元数据存入向量数据库如 Milvus。检索: 用户提问时将问题向量化在向量库中检索最相似的 K 个片段。重排序 (可选但重要): 初步检索的 Top-K 可能不完全相关使用一个更精细的交叉编码器模型对候选片段进行重排序选出最相关的几个。提示构建与生成: 将问题、检索到的片段组装成提示词发送给 LLM 生成最终答案。5.2 基于 Langchain Milvus 的 RAG 实现面试题“请用代码展示一个最简单的 Langchain RAG 流程。”完整示例:import os from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_community.vectorstores import Milvus from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate # 0. 环境变量设置 (你的API Key) os.environ[OPENAI_API_KEY] your-api-key-here # 1. 加载文档 loader TextLoader(./sample_doc.txt, encodingutf-8) documents loader.load() # 2. 分割文档 text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, length_functionlen, separators[\n\n, \n, 。, , , , , , ] ) docs text_splitter.split_documents(documents) print(f原始文档分割为 {len(docs)} 个片段。) # 3. 初始化 Embedding 模型和 LLM embeddings OpenAIEmbeddings(modeltext-embedding-ada-002) llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 4. 存入 Milvus # 连接参数 vector_store Milvus.from_documents( docs, embeddings, connection_args{host: localhost, port: 19530}, collection_namelangchain_rag_demo, drop_oldTrue # 如果集合存在则删除重建 ) print(文档已向量化并存入 Milvus。) # 5. 构建检索器 retriever vector_store.as_retriever(search_kwargs{k: 3}) # 检索 top-3 # 6. 自定义提示模板 (可选但推荐) prompt_template 基于以下上下文信息请回答问题。如果你不知道答案就说不知道不要编造。 上下文 {context} 问题{question} 请给出答案 PROMPT PromptTemplate( templateprompt_template, input_variables[context, question] ) # 7. 创建 RetrievalQA 链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 最简单的方式将所有上下文塞入提示词 retrieverretriever, chain_type_kwargs{prompt: PROMPT}, # 使用自定义提示词 return_source_documentsTrue # 返回源文档便于追溯 ) # 8. 提问 query 这篇文章主要讲了什么 result qa_chain.invoke({query: query}) print(f问题{query}) print(f答案{result[result]}) print(\n 参考来源 ) for i, doc in enumerate(result[source_documents]): print(f[{i1}] {doc.page_content[:200]}...) # 打印前200字符5.3 RAG 的挑战与优化策略面试高频问题“RAG 系统有哪些常见问题如何优化”问题与优化:检索不相关原因chunk 分割不合理、Embedding 模型不匹配、检索策略单一。优化多粒度分割同时保留大块保留上下文和小块提高精度。混合检索结合向量搜索和关键词搜索如 BM25。重排序使用Cross-Encoder模型对初筛结果进行精排。查询扩展/改写用 LLM 对原始问题进行改写或生成多个相关问题并行检索。上下文长度限制原因LLM 有 Token 限制stuff方式可能超限。优化Map-Reduce将各 chunk 答案分别生成再汇总。Refine迭代式生成基于前一个 chunk 的答案和当前 chunk 生成新答案。Selective Context只选择最相关的几个 chunk 送入 LLM。答案未基于上下文幻觉原因提示词指令不强或 LLM 自身知识干扰。优化强化提示词如“严格基于给定上下文回答”、“引用上下文中的句子”。6. Agent 智能体开发进阶Agent 是让 LLM 从“聊天机器”变为“自动执行者”的关键。6.1 Agent 的核心模式ReAct面试题“解释一下 ReAct 模式并写一个简单示例。”核心答案 ReAct (Reason Act) 模式让 Agent 以Thought - Action - Observation的循环进行推理。Thought: Agent 分析当前状况决定下一步做什么。Action: 根据 Thought执行一个动作通常是调用一个工具并传入参数。Observation: 获取工具执行的结果作为下一轮 Thought 的输入。Langchain 中的 ReAct 示例:from langchain.agents import Tool, AgentExecutor, create_react_agent from langchain_openai import ChatOpenAI from langchain import hub import math # 定义工具 def calculate_sqrt(input_str: str) - str: 计算一个数的平方根。输入应为一个数字。 try: num float(input_str) if num 0: return 错误不能计算负数的平方根。 return str(math.sqrt(num)) except ValueError: return 错误输入不是一个有效的数字。 tools [ Tool( nameCalculator, funccalculate_sqrt, description用于计算数字的平方根。输入一个数字。 ) ] # 使用 ReAct 提示词模板 prompt hub.pull(hwchase17/react-chat) llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 创建 ReAct Agent agent create_react_agent(llm, tools, prompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, max_iterations3) # 执行 result agent_executor.invoke({ input: 36的平方根是多少再给这个结果加10。, chat_history: [] # 如果是多轮对话需要传入历史 }) print(result[output])执行过程verboseTrue 时可见:Thought: 用户先问36的平方根我需要用计算器工具。然后需要把结果加10这可能需要再次推理。 Action: Calculator Action Input: 36 Observation: 6.0 Thought: 我得到了6.0。现在需要给这个结果加10。这是一个简单的加法我可以在脑中计算不需要工具。 Final Answer: 36的平方根是6.0加10后是16.0。6.2 多智能体协作与 LangGraph面试题“Langchain 和 LangGraph 在构建 Agent 时有什么区别”核心答案:Langchain Agent通常是一个单一的智能体按照预设的循环ReAct工作。适合任务相对线性、工具调用明确的场景。LangGraph是一个基于状态机的库用于构建有向图节点可以是 LLM、工具或其他函数边代表状态流转。它天生支持多智能体协作、循环、分支和持久化状态。适用场景需要多个角色如分析师、作家、评审员协作完成任务或者任务需要反复检查、修正的复杂工作流。简单 LangGraph 概念示例伪代码思路:# 注意此为概念说明非完整可运行代码 from langgraph.graph import StateGraph, END # 定义状态结构 class AgentState(TypedDict): question: str analysis: str answer: str # 定义节点函数 def analysis_node(state: AgentState) - AgentState: # 调用LLM分析问题 state[analysis] llm.invoke(f分析问题{state[question]}) return state def answer_node(state: AgentState) - AgentState: # 基于分析生成答案 state[answer] llm.invoke(f基于分析‘{state[analysis]}‘回答问题{state[question]}) return state def quality_check_node(state: AgentState) - AgentState: # 检查答案质量决定是否重新分析 if 不明确 in state[answer]: return need_reanalysis # 跳回 analysis_node else: return final # 流向 END # 构建图 workflow StateGraph(AgentState) workflow.add_node(analyze, analysis_node) workflow.add_node(answer, answer_node) workflow.add_node(check, quality_check_node) workflow.set_entry_point(analyze) workflow.add_edge(analyze, answer) workflow.add_edge(answer, check) workflow.add_conditional_edges(check, # 条件边 lambda x: x, # 根据 check_node 的返回值决定流向 {need_reanalysis: analyze, final: END}) app workflow.compile()面试要点当被问到复杂工作流、审批流程、具有循环依赖的任务时可以提及 LangGraph 是比基础 Langchain Agent 更合适的工具。7. FDE 概念辨析与工程实践FDE 在面试中可能是一个特定领域术语需要结合上下文理解。7.1 FDE 的可能含义与关联Function Calling, Decision, Execution (循环):这是 Agent 运行的核心循环。LLM 根据对话决定是否需要调用函数Function Calling然后决策Decision调用哪个函数及其参数最后执行Execution该函数并观察结果进入下一轮。这本质上是 ReAct 模式在 OpenAI Function Calling 格式下的体现。Frontend, Decision Engine (架构组件):在一些企业级 AI 应用架构中Frontend可能指面向用户的界面或 API 网关负责接收请求、管理会话。Decision Engine是大脑负责解析用户意图、规划任务、调用合适的工具链可能包含多个 RAG、Agent 等。这强调了前后端分离和决策中枢的概念。特定框架/平台组件:例如在Hermes Agent或其他一些 AI 平台中FDE 可能特指其内部某个负责流程编排的模块。面试中如果遇到应询问面试官该术语在对方业务上下文中的具体定义。7.2 从 FDE 角度设计一个客服 Agent 系统面试设计题“假设要设计一个智能客服系统能处理查询、投诉、转人工你会如何设计架构”参考回答融入 FDE 概念:1. **前端 (Frontend)**: - 提供 Web/App/API 接口接收用户自然语言提问。 - 维护对话上下文Session。 2. **决策引擎 (Decision Engine)**: - **意图识别**: 使用一个分类 LLM 或规则引擎判断用户意图如“查询订单”、“投诉物流”、“转人工”。 - **任务规划**: 根据意图规划执行步骤。 - 若是“查询订单”则触发 **RAG 流程**从知识库Milvus检索订单相关FAQ或调用“订单查询工具”。 - 若是“投诉”则触发 **Agent 流程**调用“创建工单工具”并可能要求用户补充信息。 - 若是“转人工”则调用“分配客服工具”。 - **上下文管理**: 维护整个对话的历史和当前状态确保决策连贯。 3. **执行层 (Execution)**: - **工具集**: 封装所有能力如 - query_knowledge_base(): 基于 RAG 的问答。 - get_order_status(order_id): 调用内部订单 API。 - create_complaint_ticket(user_info, details): 调用工单系统 API。 - escalate_to_human_agent(session_id): 通知客服系统。 - **RAG 模块**: 专门处理知识检索与回答。 - **Agent 执行器**: 负责运行规划好的动作序列。 4. **流程**: 用户输入 - 前端接收 - 决策引擎识别意图 - 规划任务 - 调用对应工具执行 - 将结果返回前端 - 前端回复用户。 整个过程是一个动态的 FDE 循环决策引擎会根据执行结果决定下一步例如工具返回“未找到订单”决策引擎可能决定让用户重新输入或直接转人工。这个设计体现了模块化思想并将 RAG、Agent 等技术作为决策引擎下的具体执行手段。8. 常见问题与排查思路在实际开发和面试中会遇到各种问题。以下是一些高频问题的排查清单。问题现象可能原因排查步骤与解决方案Langchain 调用 LLM 超时或报错1. API Key 错误或失效。2. 网络问题或代理设置。3. 模型名称错误。4. 请求速率超限。1. 检查os.environ[“OPENAI_API_KEY”]是否正确设置。2. 检查网络连接如有需要设置openai.proxy。3. 核对模型名如“gpt-3.5-turbo”。4. 查看 OpenAI 控制台用量和速率限制考虑增加延迟或使用重试机制。Milvus 连接失败1. Milvus 服务未启动。2. 端口或地址错误。3. 版本不兼容PyMilvus 与 Milvus 服务端。1. 运行docker ps或sudo systemctl status milvus检查服务状态。2. 确认连接参数host和port默认 19530。3. 确保 PyMilvus 版本与 Milvus 服务端版本匹配。向量检索结果不相关1. 文档分割策略不佳。2. Embedding 模型不匹配如用中文模型处理英文。3. 索引参数不合理如nprobe太小。4. 查询未进行向量化或向量化错误。1. 调整chunk_size和chunk_overlap或尝试不同TextSplitter。2. 选择与文本语言匹配的 Embedding 模型。3. 调整索引和搜索参数如增大nprobe。4. 确保查询文本使用了相同的 Embedding 模型进行向量化。Agent 陷入死循环或重复调用工具1. 工具描述不清导致 LLM 误解。2.max_iterations设置过高或无限制。3. Agent 类型选择不当无法处理复杂逻辑。1. 优化工具函数的description明确输入输出。2. 设置合理的max_iterations如 5-10。3. 对于复杂任务考虑使用LangGraph构建有明确终止条件的工作流。RAG 答案出现幻觉编造1. 提示词未强制要求基于上下文。2. 检索到的上下文完全不相关LLM 被迫编造。3. LLM 的temperature参数过高。1. 在提示词中加入强指令“仅根据提供的上下文回答如果上下文没有相关信息请说‘我不知道’。”2. 优化检索环节见 5.3。3. 将temperature设为 0 或接近 0 以减少随机性。安装依赖冲突1. Langchain 等库版本更新快API 不兼容。2. Python 版本不匹配。1.强烈建议使用虚拟环境venv或conda。2. 使用requirements.txt或pyproject.toml精确锁定版本。3. 查看官方文档的版本说明和迁移指南。9. 最佳实践与工程建议将这些技术应用于生产环境需要遵循一些工程准则。1. 配置与密钥管理永远不要将 API Key、数据库密码等硬编码在代码中。使用环境变量.env文件配合python-dotenv或专业的配置管理服务。为不同环境开发、测试、生产设置不同的配置。2. 版本控制与依赖管理使用requirements.txt或Poetry明确记录所有依赖及其版本。定期更新依赖但升级前务必在测试环境验证兼容性尤其是 Langchain 这类快速迭代的库。3. 错误处理与日志对 LLM 调用、数据库操作、工具调用进行完善的try-except包装。记录详细的日志包括请求、响应、耗时、错误信息便于排查问题。可以使用langchain.callbacks中的回调函数。from langchain.callbacks import StdOutCallbackHandler handler StdOutCallbackHandler() chain.invoke({query: ...}, config{callbacks: [handler]})4. 性能与成本优化缓存对 Embedding 结果和常见的 LLM 回答进行缓存如使用langchain.cache。批处理对大量文档进行向量化时使用 Embedding 模型的批处理功能。Token 管理监控 Token 使用量优化提示词和 chunk 大小以控制成本。异步调用对于高并发场景使用 Langchain 的异步接口ainvoke,abatch,astream。5. RAG 系统评估建立评估体系不仅看答案流畅度更要看忠实度是否基于给定上下文和答案相关性。可以构造测试集使用 LLM 作为裁判LLM-as-a-Judge或其他评估框架进行自动化评估。6. Agent 设计原则工具设计要精确工具功能应单一、明确描述清晰。设置安全边界对于可能造成副作用的工具如删除、发送邮件加入确认机制或权限检查。提供逃生通道当 Agent 多次尝试失败后应能优雅降级例如转交人工或返回一个友好的错误信息。掌握 Langchain、Milvus、RAG、Agent 乃至 FDE 所代表的系统思维意味着你具备了构建下一代 AI 应用的核心能力。面试不仅是考察知识点更是考察你如何将这些技术有机组合解决真实世界的问题。建议在理解上述内容的基础上亲手搭建一个小型项目例如一个个人知识库问答系统或一个自动化数据分析助手在实践中深化理解并积累属于自己的“踩坑”经验。