基于多智能体协作的RAG系统:从架构设计到工程实践 1. 项目概述当大语言模型遇上巴西劳动法最近在折腾一个挺有意思的项目核心目标很简单用大语言模型LLM来回答关于巴西劳动法的问题。听起来是不是觉得“这不就是个RAG检索增强生成应用吗” 一开始我也这么想但实际一上手问题就来了。巴西的劳动法体系比如著名的《统一劳动法》Consolidação das Leis do Trabalho, CLT条文繁杂、解释众多还有大量的判例和补充规定。一个简单的RAG管道把文档切片、向量化、然后检索生成在面对“员工在远程办公期间因家庭网络故障导致的工作延误公司是否有权扣减工资”这类复杂、需要多步推理和交叉引用的问题时经常力不从心。要么检索不到关键片段要么生成的答案片面或自相矛盾。这就是“HR-Agents”这个项目想解决的问题。它的核心思路不是用一个“超级智能体”包打天下而是采用多智能体Multi-Agent协作的架构让多个各司其职的LLM智能体像一支专业团队一样工作共同处理一个复杂的劳动法咨询。这有点像公司里的法务部有人负责查法条检索专家有人负责分析判例推理专家有人负责起草法律意见生成专家最后还有个人负责统稿和校验协调与审核专家。通过这种分工协作最终产出的答案在准确性、完整性和逻辑性上都远胜于单打独斗。这个项目背后是当前LLM应用从“单点工具”向“系统化智能体工作流”演进的一个缩影。单纯依靠提示工程Prompt Engineering或基础RAG已经难以应对专业垂直领域的深层次问答需求。而像CrewAI、LangGraph这类多智能体框架的兴起为我们构建这样的协作系统提供了强大的基础设施。接下来我就结合这个巴西劳动法QA的场景拆解一下如何从零搭建一个高效的多智能体系统分享其中的设计思路、技术选型、实操步骤以及我踩过的那些坑。2. 核心架构设计从单兵作战到团队协作传统的劳动法问答机器人通常是一个“检索-生成”的线性流程。用户提问 - 向量数据库检索相关片段 - LLM根据片段生成答案。这种模式的问题在于检索瓶颈如果问题涉及多个法律概念如“加班费”、“解雇赔偿”、“带薪休假”简单的语义检索可能无法一次性召回所有必要信息。推理局限LLM需要同时完成信息理解、逻辑推理、冲突消解和语言组织对于复杂场景容易“脑力过载”产生幻觉或忽略细节。缺乏校验答案生成后缺乏审核机制可能包含与法律精神相悖或表述不严谨的内容。HR-Agents的多智能体架构旨在解决这些问题。其核心设计哲学是分解任务专业化处理有序协作。整个系统可以看作一个虚拟的“劳动法咨询团队”。2.1 智能体角色定义与职责划分我们设计了四个核心智能体角色每个角色由特定的LLM或同一LLM的不同提示词驱动拥有明确的目标和工具集。智能体一检索分析师Retrieval Analyst目标全面、无遗漏地找到与用户问题相关的所有法律文本片段。职责理解用户问题的核心法律诉求如涉及“工时”、“薪酬”、“合同解除”等。将复杂问题拆解成多个独立的检索子查询。例如针对“远程办公工伤认定”问题可拆解为“远程办公定义”、“工伤认定标准”、“工作场所界定”等多个查询。调用向量数据库进行多轮、多角度的混合检索结合语义搜索和关键词搜索。初步过滤明显不相关的检索结果并按相关性排序将原始材料打包传递给下游智能体。工具向量数据库查询接口如Milvus、Pinecone、关键词提取器、查询改写器。智能体二逻辑推理师Logic Reasoner目标对检索到的材料进行深度分析、推理和矛盾消解。职责梳理检索材料中的法律条文、判例要点和专家解释。识别不同材料之间可能存在的冲突或补充关系例如基本法条与特殊行业规定。构建问题解答的逻辑链。例如要回答“是否有权扣薪”需先确定“故障责任归属”再引用“薪酬支付原则”相关法条。提取关键事实、法律依据和推理过程形成结构化的“推理备忘录”。工具思维链Chain-of-Thought提示模板、矛盾检测规则、逻辑框架模板。智能体三答案生成师Answer Generator目标基于推理备忘录生成专业、清晰、人性化的最终答案。职责将结构化的推理备忘录转化为连贯的自然语言。确保答案包含结论摘要、详细法律依据分点阐述、可能存在的例外情况说明、以及给用户的行动建议。调整语言风格使其既专业严谨又便于非法律专业人士理解。在答案中标注关键引用来源如“根据CLT第X条第Y款”。工具高质量答案模板、风格调整提示词、引用格式化工具。智能体四质量审核员Quality Auditor目标对生成的答案进行最终校验确保安全、合规、准确。职责事实一致性检查核对答案中的陈述是否与检索到的原始材料严格一致杜绝幻觉。逻辑自洽性检查确保答案内部逻辑连贯没有自相矛盾之处。安全与合规检查过滤任何可能产生误导、激进或不妥的建议例如绝对不能建议用户采取违法对抗行动。格式与清晰度优化检查答案的段落结构、标点符号和术语使用是否规范。工具一致性校验提示词、安全规则列表、合规性检查清单。实操心得角色定义是关键在项目初期我们曾尝试让一个智能体身兼检索和推理二职效果很差。LLM很容易在检索结果不完美的情况下“硬着头皮”推理导致错误。明确的分工迫使每个智能体“专注本职”大大提升了中间产物的质量。角色定义需要紧密结合业务场景思考一个真实专家团队会如何分工。2.2 协作流程与框架选型CrewAI实战定义了角色下一步就是让它们动起来并有序协作。这里我们选择了CrewAI作为多智能体编排框架。相比自己用LangChain或LlamaIndex从头搭建工作流CrewAI提供了更高层级的抽象专注于定义Agent智能体、Task任务和Process流程让协作逻辑变得非常直观。为什么选择CrewAI面向协作的设计它的核心概念Crew, Agent, Task天然契合多智能体团队协作的隐喻开发体验更顺畅。流程控制灵活支持顺序sequential、分层hierarchical和自主协作autonomous等多种流程适合我们这种有明确上下游依赖的场景。集成度高与LangChain工具链兼容性好可以方便地接入各种工具和LLM。社区活跃能较快地跟进LLM生态的最新进展。基于CrewAI的HR-Agents工作流搭建整个工作流被定义为一个Crew包含上述四个Agent以及为每个Agent分配的Task。流程设置为sequential顺序执行因为后一个任务严重依赖前一个任务的输出。# 伪代码示例展示CrewAI的核心结构 from crewai import Agent, Task, Crew, Process from langchain_openai import ChatOpenAI # 1. 定义LLM可以是同一个模型也可以是针对任务优化的不同模型 llm ChatOpenAI(modelgpt-4-turbo, temperature0.1) # 推理和生成用低随机性 llm_for_retrieval ChatOpenAI(modelgpt-4-turbo, temperature0) # 检索任务用零随机性 # 2. 创建智能体 retrieval_analyst Agent( role巴西劳动法检索分析师, goal根据用户问题全面、准确地检索所有相关的巴西劳动法律条文、判例及解释, backstory你是精通巴西CLT法律体系及判例数据库的专家擅长多角度拆解问题并进行深度检索。, llmllm_for_retrieval, tools[vector_db_tool, query_decomposer_tool], # 自定义的工具 verboseTrue ) logic_reasoner Agent( role劳动法逻辑推理师, goal分析检索材料构建严谨的法律推理链识别并消解信息冲突, backstory你是拥有十年经验的劳动法律师擅长从复杂材料中提炼关键事实和法律关系并进行逻辑论证。, llmllm, tools[cot_prompt_tool], # 思维链提示工具 verboseTrue ) # ... 类似定义 answer_generator 和 quality_auditor # 3. 创建任务并明确任务间的依赖关系 task_retrieve Task( description针对用户问题{user_question}执行全面检索并输出整理后的材料包。, agentretrieval_analyst, expected_output一份包含3-5个最相关法律片段及其元数据来源、条款号的JSON格式材料包。 ) task_reason Task( description基于检索分析师提供的材料包进行法律逻辑推理形成推理备忘录。, agentlogic_reasoner, context[task_retrieve], # 关键此任务依赖 task_retrieve 的输出 expected_output一份结构化的推理备忘录包含核心争议点、适用法律依据、推理步骤、潜在冲突说明。 ) task_generate Task( description基于推理备忘录生成面向用户的最终答案。, agentanswer_generator, context[task_reason], expected_output一份专业、清晰、带引用标记的最终答案文本。 ) task_audit Task( description对生成的答案进行事实、逻辑、安全性的最终审核与优化。, agentquality_auditor, context[task_generate], expected_output经过审核和优化后的最终安全答案。 ) # 4. 组建团队并运行 hr_crew Crew( agents[retrieval_analyst, logic_reasoner, answer_generator, quality_auditor], tasks[task_retrieve, task_reason, task_generate, task_audit], processProcess.sequential # 顺序执行 ) result hr_crew.kickoff(inputs{user_question: 员工在远程办公期间因家庭网络故障导致的工作延误公司是否有权扣减工资}) print(result.final_output)这个框架清晰地勾勒出了智能体之间的协作关系。context参数是定义依赖的关键它确保了数据流的方向。在实际运行中你可以观察到每个智能体“思考”调用LLM和“行动”调用工具的详细日志这对于调试和优化至关重要。3. 核心模块深度解析与实现有了顶层架构我们来深入看看几个核心模块的具体实现和优化点。3.1 知识库构建RAG的基石多智能体系统再强大如果知识库本身质量差那就是“垃圾进垃圾出”。针对巴西劳动法这类专业文档知识库构建需要格外精细。文档预处理与切片策略巴西劳动法文档通常是结构化的PDF或HTML包含章节、条款、项、目。切忌简单按固定字符数切片这会把一个完整的法律条款切得支离破碎。我们采用语义切片和规则切片相结合的方式。规则切片首先利用文档的标记如“Art. 1º”, “§ 1º”, “a)”进行初步切分确保每个切片是一个完整的法律意义单元如一条完整的法律条文。语义切片对于较长的条款或评述再使用嵌入模型计算语义边界在保证句子完整性的前提下进行二次切分。我们使用了langchain.text_splitter.RecursiveCharacterTextSplitter但自定义了分隔符优先级[\n\n, \nArt., \n§, \n, 。, , , ]并设置一个较大的chunk_size如1000和较小的chunk_overlap150以保留上下文。元数据丰富为每个切片附加丰富的元数据这对后续检索和答案引用至关重要。source: 原始文件名。article: 条款号如“CLT Art. 458”。section: 所属章节。type: 文本类型如“法律条文”、“判例摘要”、“官方解释”。summary: 由LLM生成的该切片简短摘要用于辅助检索。向量化与索引构建嵌入模型选型对于葡萄牙语法律文本我们测试了多种开源和商用嵌入模型。最终选择了专门针对法律文本微调过的sentence-transformers模型如jurbert的变体它在法律概念相似性匹配上显著优于通用模型如text-embedding-ada-002。关键是要在本地构建一个小的测试集评估模型对“同义法律术语”、“上下位关系”的捕捉能力。向量数据库选用Milvus。理由是其对高维向量的高性能检索支持、丰富的索引类型如IVF_FLAT, HNSW以及方便的元数据过滤功能。例如在检索时我们可以先通过元数据type过滤出“法律条文”再进行语义搜索提高精度。混合检索策略这是提升召回率的关键。除了向量相似性搜索我们集成了关键词搜索BM25。具体实现是将切片文本同时存入Milvus向量元数据和Elasticsearch用于关键词检索。检索分析师智能体可以并行发起两种查询然后对结果进行重排序Rerank。我们使用了一个轻量级的交叉编码器Cross-Encoder模型对初筛结果进行精排计算查询与每个候选片段的相关性分数最终融合向量分和关键词分选出Top-K个最相关片段。踩坑实录切片与检索的“对齐”问题最大的坑在于“检索粒度”与“回答需求”不匹配。早期我们按段落切片结果经常检索到只包含前提或例外情况的片段导致推理混乱。后来改为“按法律意义单元切片”并强制要求检索分析师智能体每次必须检索至少3个不同来源或类型的片段才有效避免了信息片面性。另一个教训是元数据summary的生成本身也需要消耗LLM Token需要在构建成本和质量之间权衡我们最终只为超过200字符的切片生成摘要。3.2 智能体提示工程塑造专家思维每个智能体的能力很大程度上由驱动它的LLM提示词Prompt决定。我们的目标是写出能让LLM“扮演”好特定角色的提示词。检索分析师提示词核心要素你是一名专业的巴西劳动法检索专家。你的唯一目标是找到与用户问题最相关的法律原文。 用户问题是{question} **你的工作流程** 1. **深度理解问题**识别问题中的核心法律实体如“员工”、“雇主”、“加班费”、“解雇”、行为如“扣减”、“支付”、“申请”和法律关系。 2. **生成搜索查询**基于你的理解生成最多3个侧重点不同的搜索查询。这些查询应 - 包含核心术语的同义词或相关法律术语如“薪酬”可联想到“工资”、“报酬”、“薪金”。 - 将复杂问题拆解为子问题如将“远程办公工伤”拆为“远程办公”和“工伤认定”。 - 使用葡萄牙语专业法律词汇。 3. **执行检索**你将使用工具执行这些查询。 4. **整理结果**合并去重检索结果按相关性排序并以指定JSON格式输出。对于每个片段思考它为何相关。 **输出格式必须是严格的JSON** { analysis: 你对问题的理解拆解, queries: [生成的查询1, 查询2, ...], materials: [ {content: 法律文本片段1, source: 来源, article: 条款, relevance_reason: 相关原因}, ... ] }逻辑推理师提示词核心要素引入思维链和少样本示例你是一名资深劳动法律师负责分析法律材料并构建推理。 **用户问题**{question} **检索到的材料**{retrieved_materials} **你的任务** 1. **提取关键事实与主张**从问题和材料中提炼出各方员工/雇主的主张、争议焦点。 2. **定位核心法律依据**从材料中找出直接支持或反对各方主张的法律条文、判例原则。列出具体出处。 3. **构建逻辑链**以“如果...那么...”的形式一步步推导出结论。必须展示从法律依据到事实应用的过程。 4. **识别冲突与例外**检查不同材料间是否存在冲突是否存在适用的例外情况如特殊行业规定 5. **形成备忘录**总结你的推理。 **示例仅展示结构** 问题试用期员工被解雇是否有权获得解雇赔偿 推理备忘录 - 争议焦点试用期解雇的性质是否属于无正当理由解雇。 - 核心法律依据CLT Art. 482列举了正当解雇理由CLT Art. 478关于试用期。 - 逻辑链如果解雇原因不属于Art. 482所列的正当理由如严重过失那么该解雇属于无正当理由解雇Art. 477。试用期Art. 478并不改变解雇性质的定义仅影响通知期。因此试用期员工若无正当理由被解雇仍有权获得解雇赔偿。 - 例外/冲突无。 - 初步结论有权获得。 现在请基于提供的材料完成你的推理备忘录。通过这种结构化的提示我们极大地约束了LLM的输出使其思考过程变得可控、可解释并且格式统一便于下游智能体处理。4. 系统实现与集成挑战将设计落地为可运行的系统涉及到工程化集成和性能优化。4.1 工具链集成与智能体赋能智能体需要通过“工具”与环境交互。我们使用LangChain的Tool装饰器来封装各种功能。from langchain.tools import tool from langchain_community.vectorstores import Milvus from pymilvus import connections # 连接Milvus connections.connect(hostlocalhost, port19530) vector_store Milvus(embedding_functionembed_fn, collection_namebrazilian_labor_law) tool def hybrid_retrieval_tool(query: str, top_k: int 5) - list: 执行混合检索向量关键词。 参数: query: 检索查询语句。 top_k: 返回结果数量。 返回: 一个字典列表每个字典包含‘content’, ‘source’, ‘article’等字段。 # 1. 向量检索 vector_results vector_store.similarity_search_with_score(query, ktop_k*2) # 2. 关键词检索 (假设有ES客户端 es_client) keyword_results es_client.search(indexlaw_index, body{query: {match: {text: query}}}, sizetop_k*2) # 3. 结果融合与重排序这里简化实际可用交叉编码器 all_results merge_and_rerank(vector_results, keyword_results) return all_results[:top_k] tool def query_decomposer_tool(complex_question: str) - list: 将复杂问题分解为多个子查询。 # 使用一个LLM调用提示其进行问题分解 decomposition_prompt f 将以下巴西劳动法问题分解为2-4个独立的子查询便于进行文档检索。 问题{complex_question} 输出格式JSON列表例如 [子查询1, 子查询2] # 调用LLM并解析JSON输出 # ... 省略LLM调用代码 return sub_queries然后在创建CrewAI的Agent时将这些工具传入即可。智能体在思考时会根据提示词决定何时调用哪个工具并将工具返回的结果作为后续思考的上下文。4.2 流程编排、状态管理与错误处理在顺序流程中错误处理相对简单因为一个任务失败后续任务就无法进行。CrewAI本身提供了任务执行的状态跟踪。我们需要做的是为每个Task设置超时和重试机制防止某个智能体“卡住”。验证中间输出格式在任务传递时使用Pydantic模型验证expected_output是否符合约定的JSON Schema格式错误则触发重试或降级处理。设计降级策略例如如果质量审核员连续多次否决生成的答案系统可以自动降级为“仅提供检索到的法律原文片段并注明无法生成确定性建议”这比生成一个可能有风险的答案更安全。对于更复杂的、可能需要循环或条件分支的流程例如审核不通过则返回给生成师修改CrewAI的Process.sequential可能不够用。这时可以考虑使用LangGraph来构建有状态的、图状的工作流。LangGraph允许你明确定义节点智能体/任务和边条件转移非常适合需要多轮交互的复杂场景。例如可以设计一个“审核-修订”循环直到审核通过或达到最大循环次数。4.3 性能优化与成本控制多智能体系统意味着多次LLM调用成本和延迟是必须考虑的问题。模型选型分层并非所有智能体都需要最强大的模型。质量审核员需要最高的准确性和安全性可以使用GPT-4。答案生成师需要良好的语言能力也可以用GPT-4或Claude 3。而检索分析师和逻辑推理师其任务相对结构化可以使用成本更低的模型如GPT-3.5-Turbo或开源的Llama 3 70B通过API并通过精细的提示工程来保证质量。缓存策略对于常见的、标准化的查询如“最低工资是多少”其检索结果和最终答案可以缓存起来避免重复计算。可以使用Redis缓存每个智能体任务的输入输出哈希。异步执行在非严格顺序依赖的环节可以考虑异步执行。例如检索分析师拆解出的多个子查询可以并发地进行向量检索和关键词检索。Token消耗监控详细记录每个智能体每次调用的输入输出Token数分析瓶颈。通常逻辑推理师和答案生成师的Prompt较长消耗最多。可以通过压缩上下文例如让推理师只关注最相关的几个片段来优化。5. 评估、迭代与常见问题排查系统上线后持续的评估和迭代是保证其长期有效的关键。5.1 如何评估多智能体系统的效果不能只看最终答案的对错需要建立多维度的评估体系端到端答案准确性这是最终指标。需要构建一个涵盖各种问题类型事实型、解释型、场景型的测试集由领域专家评判答案的准确性、完整性和安全性。中间产物质量检索召回率与精度评估检索分析师找到的材料是否真正相关且全面。推理链的合理性评估逻辑推理师构建的推理备忘录是否逻辑严密、依据充分。可以请法律专家评审。审核有效性故意注入一些有事实错误或逻辑问题的答案看质量审核员能否发现并纠正。人工评估与A/B测试在真实用户中开展小范围测试收集反馈对比多智能体系统与基线RAG系统的答案满意度。5.2 实战中遇到的典型问题与解决方案在开发和测试HR-Agents的过程中我们遇到了不少挑战以下是部分实录问题一智能体之间“扯皮”或信息丢失现象推理师抱怨检索师给的材料不够生成师抱怨推理师的备忘录太晦涩。根因任务之间的接口expected_output定义不够清晰、结构化。智能体输出的是自由文本下游解析困难。解决方案强制规定所有智能体间传递的信息必须使用严格的、结构化的JSON格式。就像上面的提示词示例那样为每个智能体定义明确的输出Schema。这大大降低了信息解析的复杂度使得智能体可以专注于内容生产而非格式理解。问题二检索结果“碎片化”导致推理困难现象检索师返回了5个高相关度的片段但它们来自法律的不同部分甚至彼此有些微冲突推理师无法拼凑出完整图景。解决方案改进检索策略在混合检索的重排序阶段引入“多样性”惩罚避免返回过于相似或来自同一狭窄范围的片段。赋予推理师“追问”权进阶在更复杂的架构中可以让推理师在认为材料不足时向检索师发起一轮新的、更精确的检索请求。这需要在CrewAI中设计分层流程或使用LangGraph实现循环。问题三审核员过于“保守”或“激进”现象审核员要么放过了所有答案形同虚设要么否决了太多答案导致系统吞吐量低下。解决方案精细化设计审核员的审核清单和判断阈值。事实一致性要求审核员必须逐条核对答案中的事实陈述是否能在提供的源材料中找到直接或合理推论的支持。不能是“感觉不对”。安全合规提供一个明确的不允许出现的建议清单如“建议员工罢工”、“建议伪造文件”并让审核员检查答案是否包含此类内容的变体。设置置信度阈值对于模糊地带让审核员输出一个“风险等级”低、中、高。只有“高”风险答案才被驳回修改“中”风险答案可以附加免责声明后输出。问题四系统延迟过高现象回答一个复杂问题需要超过30秒。分析耗时主要在LLM调用和检索。优化措施LLM调用采用流式响应如果支持让用户先看到部分答案将非严格串行的任务并行化如检索多个子查询。检索优化为向量数据库建立更高效的索引如HNSW对高频查询的结果进行缓存。模型蒸馏考虑为某些角色训练更小、更快的专用模型替代通用的LLM API调用。构建HR-Agents这样的多智能体系统是一个不断在“效果”、“成本”、“速度”和“复杂度”之间寻找平衡点的过程。它没有一劳永逸的银弹但通过清晰的架构、严谨的提示工程和持续的迭代优化我们确实能够打造出远超传统单模型或简单RAG系统的专业级问答应用。这个项目的经验告诉我LLM应用的未来不在于追求单个模型的“全能”而在于如何巧妙地设计和协调多个“专才”让它们协同解决复杂问题。