☰
AI Agent框架选型实战:从制度查询系统看状态管理、工具调用与RAG落地
2026/10/16 5:04:40 网站建设 项目流程

“喂,帮我看下项目经费报销的流程到哪一步了,我们部门的预算还剩多少?”这种问题,在很多公司里每天都在发生。前几天,我参与的一个面向某公司内部的制度查询助手进入了联调测试阶段。这个项目的技术难度不算高,但前期的框架选型过程却极具代表性——我们几乎把目前主流的AI Agent搭建方案都过了一遍,踩了不少坑,也理清了不少技术边界。

这个项目的核心需求,是把分散在几百个Word、PDF文件里的公司规章制度、审批流程、报销标准等内容,变成一个可以自然语言对话的AI入口。听起来简单,但真正做起来,你会发现这里面的坑比想象中多得多:有的框架擅长处理简单问答,但一遇到多轮对话就“失忆”;有的框架工具调用很灵活,但上下文管理完全是个黑盒;还有些方案看着配置简单,真正遇到复杂权限场景时根本没法表达。这类项目最适合用来做Agent框架的选型测试,因为它不涉及特别深的行业知识,但覆盖了Agent最核心的几个技术点:状态管理、上下文窗口、工具调用、外部知识库对接、以及人机交互边界。

这篇文章,我就以这次制度查询系统的选型和搭建为线索,聊聊AI Agent框架到底该怎么选。我梳理了几种主流方案的在类似场景下的真实表现,把为什么选它、为什么不选它、以及真正跑起来之后遇到的问题都摊开来讲。如果你也在纠结Agent框架选型,或者正在做一个类似的“内网知识问答”类项目,这篇文章应该能帮你节省不少调研时间。

1. 内容整体设计与思路拆解

1.1 制度查询场景的真实技术需求

先想想这个场景到底需要什么。用户问“报销流程到哪一步”,这句话背后至少隐含了三个动作:第一,系统要知道“报销流程”是什么制度;第二,要知道“到哪一步”意味着要查一条审批状态;第三,如果预算信息也要回答,系统还得接上另一个系统。也就是说,这不是简单的一个“问答对”,而是一个需要拆解意图、匹配工具、查询数据、组织答案的完整链条。

但真实使用中情况会更复杂。用户可能会追问:“那如果发票丢了怎么报销?”这时候系统需要记住刚才的上下文——用户问的是报销流程,现在问题变成了“发票确实情况下的变通处理”。如果框架没有很好的会话状态保持能力,这时候就会把问题当成全新请求,答非所问。制度类还有一个特点:很多制度之间有互斥和优先级关系,比如“普通员工报销”和“高管报销”的标准不一样,同一个条款在不同情况下有不同的解释。这意味着Agent不仅要找到文档,还要能基于用户身份做推理。

所以,抛开“AI很神奇”的滤镜,这个场景对Agent框架的核心要求是:可靠的对话状态管理、灵活的工具注册与调用、能接入外部知识库、以及可控的上下文窗口策略。这四条是一条一条死磕出来的,缺一个,后面的体验都会崩。

1.2 为什么拿这种场景做框架边界测试

其实一开始我们并没有把这单当成框架选型项目来做。团队里有人建议直接用大模型API加个前置检索就搞定,也有人拍板用某个流行的低代码Agent平台。但推进到联调阶段,问题一个接一个浮出来:有的工具没法自定义工具参数类型,有的不支持流式输出与工具调用的混合,还有的在长上下文中频繁丢信息。被迫地,我们把市面上能试的几个方案都拉出来跑了一圈。

制度查询是个非常典型的“企业级RAG+工具调用”混合体。它不像纯粹的代码生成Agent那样对模型推理能力要求极高,也不像网页Agent那样对浏览器嵌入依赖很重。它的难度在于“确定性”和“灵活性”的平衡:制度是确定的事实,但用户提问方式是千变万化的。这个平衡点能把框架的边界逼出来——你的框架是否支持细粒度的工具返回值处理?是否支持多轮调用后的自我修正?是否允许开发者干预每一轮的决策?

不管你是做一个智能客服、一个垂直领域问答机器人,还是一个能操作内部系统的数字员工,制度查询这个场景都能作为一块很好的“试金石”。它能测试出框架的工程化程度、对复杂真实场景的支持力度、以及后续自己改代码的空间。

2. 核心细节解析与实操要点

2.1 Agent框架的六个技术维度拆解

我梳理了六个维度,每次选型都用它来做横向对比,这次也一样。

第一个维度是状态管理。这里说的不是前端状态,而是Agent的会话状态——对话历史、中间推理步骤、待执行的工具调用队列、以及执行结果缓存。对于做制度查询这类流程型任务,好的状态管理应该支持随时挂起、恢复和分支。

第二个维度是工具调用协议。现在的Agent要干实事,一定绕不开调用工具。制度查询里的工具可能是一个查报销标准的函数、一个查审批进度的API、一个查考勤数据的内部接口。框架能不能让开发者方便地定义参数Schema、能不能处理并发的工具调用、能不能清晰返回结构化的工具结果,直接决定开发效率。

第三个维度是上下文管理策略。前面说了,Agent最容易翻车的地方就是“忘事”。有些框架把所有消息一股脑塞给模型,然后靠模型自己参悟;有些框架支持消息去重、截断、摘要压缩;还有些框架允许开发者显式控制哪些内容进入上下文。制度查询的业务要求决定了上下文管理必须是显式的——比如用户说“那报销标准呢?”,“那”字就要追溯到上一条消息里的业务对象。

第四个维度是与知识库的对接深度。制度文档一般存在向量数据库里,但是单纯做向量检索,效果并不好。专业的做法是先做基于规则的意图路由,再在命中“制度查询”意图时才触发RAG检索,最后让Agent基于检索结果组织答案。框架如果自带了RAG组件,要看它是否支持自定义重排序逻辑。

第五个维度是可观测性。这个往往被忽略,但上线第一天就会让你后悔。Agent在跑的时候,关键节点比如意图识别结果、命中的工具、工具返回的原始结果,都需要能被追踪到,技术上也就是Trace。贵的商用框架虽然开箱即用,但追踪链路是黑盒,出了问题你根本不知道是检索抽风了还是模型答偏了。

第六个维度是部署和定制成本。你要考虑这个Agent是嵌在飞书/钉钉里,还是做一个独立网页,或者走企业微信的接口。不同框架对多渠道接入的支持差别很大,有的天生就是聊天机器人壳子,有的更像是一个需要你自己搞前端的推理引擎。

2.2 几种典型方案的边界画像

我把常见的方案分成三类,分开说它们的适配边界。

第一类是低代码Agent平台,比如Dify、Coze这类。优点是上手极快,拖拖拽拽就能搭出一个能聊天的应用,知识库组件也现成。但边界也很明显:当业务逻辑复杂到需要自定义Agent决策时,平台给的画布往往不够用,尤其是条件分支一多,画布就乱成一团;平台对自定义Python代码和第三方库的依赖管理也比较弱,遇到稍微复杂一点的工具就得靠写插件接口绕。它们让我最难受的一点是会话状态和Trace数据的导出受限,复盘效果问题很难受。

第二类是代码优先的Agent编排框架,比如LangGraph。这类框架把Agent定义成一张“图”,节点是处理逻辑,边是流转逻辑,状态在节点之间显式传递。边界清晰,调试直接,适合需要精细控制流程和上下文的场景。代价是需要写代码,对团队的技术能力有要求。我们用LangGraph实现了一套“意图识别—制度确认—参数抽取—工具调用—答案生成”的流程,每一个节点都可以单独打日志、单独设置懒加载,这在低代码平台上是做不到的。

第三类是直接大模型API+自行封装。这种方式最灵活,你可以对Prompt、工具、上下文做任意程度的干预。但代价是所有的工程问题都要自己扛——会话存储、重试、流式输出、Token计费、模型切换——全都是工作量。如果你只是做个Demo,那很爽,但要上生产环境,这部分工作量会占掉整个项目的一半以上。

从边界测试的结果来看,如果你的Agent流程相对固定、需要的工具类型不超过三个、交互深度也不深,低代码平台效率最高;一旦涉及身份权限、多轮追问、条件分支甚至是循环操作,代码优先或者混合方案才扛得住。

2.3 框架选型中的“必要性思维”

选型时最忌讳的就是“别人用什么我也用什么”。我习惯把需求分为“必要”和“想要”两类,必要需求不满足就一票否决。

在这次制度查询项目里,必要的需求是:会话级状态保存至少二十轮;支持动态注入用户角色和部门信息;支持自定义工具参数,比如“查询审批进度”要传工单号;支持对工具返回结果做二次格式化;支持流式输出。

想要但不必要的包括:可视化编排、语音输入、第三方插件市场、开箱即用的管理后台。这几条就算不具备,也不影响系统核心跑通。

拿这个清单去套框架,很多方案的优缺点就很清楚了。有的平台管理后台很漂亮,但当你需要自定义工具Schema时,它的类型系统根本表达不了嵌套的JSON结构,只能写死为字符串。一票否决。有的框架支持超高自由度的自定制,但它要你额外部署一套状态服务和高可用方案,研发成本大增,对一个预算有限的内部项目来说,性价比反而不高。

3. 实操过程与核心环节实现

3.1 技术栈与系统架构

最终我们选了LangGraph作为主框架,服务端用Python实现,前端单独写了一个简单的Web聊天界面。向量数据库用开源的方案,不引入重型的商业化产品。文档解析这块,我们自己做了一个预处理管线:把PDF、Word统一转成带章节层级的纯文本,然后把层级信息作为元数据存起来,方便后续做过滤检索。整体架构并不复杂,核心就是一个FastAPI服务,上面挂了Agent的运行时,再对接了大模型API、向量数据库和内部审批系统的接口。

这个方案相对较重,但好处是可控性强。我们在LangGraph里实现了四个核心节点:意图识别节点、制度检索节点、工具执行节点、答案生成节点。每个节点之间的状态传递都是显式的Python字典,出问题可以直接看管道里的内容,调试起来很舒服。

3.2 关键节点设计:意图识别

意图识别节点是整个流程的入口,也是我花时间最多的部分。我们没有直接让大模型随意发挥,而是设计了一个相对狭窄的分类体系——制度的查询、流程进度的查询、闲聊、以及模糊问题的澄清请求。四种意图,分别走不通的分支。

下面是意图识别节点的核心定义,我用的是一个结构化的输出方式:

type Intent = | 'policy_query' // 制度/条款/标准查询 | 'process_tracking' // 审批进度/流程状态查询 | 'clarification' // 用户问得模糊,需要反问澄清 | 'chitchat' // 无关闲聊,不做RAG检索 interface AgentState { messages: ChatMessage[] intent: Intent extracted_params: Record<string, any> retrieved_chunks: DocumentChunk[] tool_results: Record<string, any> final_answer: string }

在意图识别时,我们不只是让模型输出一个单词,而是强制它输出一个JSON,里面包括意图类型和相关的参数。比如用户问“报销到哪了”,模型会输出这样的结构化内容:

{ "intent": "process_tracking", "params": { "process_type": "expense_reimbursement", "query_target": "approval_step" } }

这样做最大的好处是,后续节点不再需要从原始文本里重新猜参数,直接拿这个JSON去拼下一步的查询条件就行了。对于制度查询来说,参数化的意图识别比自由文本的问答要稳定得多,也更便于调试。如果你去看用户的真实问题,你会发现“到哪了”“怎么办”“多少钱”这些口语化表达,其实对应着完全不同的参数结构,不做意图识别就想一步到位问答,必然翻车。

3.3 工具调用与上下文管理的实现细节

工具调用这块,我们注册了三个主要工具:

第一个是get_policy_content,参数是制度名和章节名,返回对应的制度原文片段。这个工具背后接的是向量库加关键词混合检索。

第二个是check_process_status,参数是工单号和审批类型,返回审批进度JSON。这个工具对接的是内部OA系统的只读查询接口。

第三个是list_reimbursement_standards,参数是员工职级和费用类型,返回可报销的金额上限和需要提供的材料列表。

在LangGraph里,工具的调用不是“一把梭”。我们用一个循环节点来调度工具调用——只要模型认为还需要调用工具,循环就不会终止。但为了防止模型陷入死循环,我们设置了最大工具调用次数为三次,超过就直接终止并返回错误提示。

上下文管理上踩过一个很关键的坑:最开始我们把所有历史消息一股脑全塞给模型,结果导致两轮之后Token耗尽,而且模型容易被无关历史干扰。后来我们改成了滑动窗口加摘要的混合策略。具体做法是:对话历史的最近四轮完整保留,四轮之前的对话内容由另一个模型总结成摘要,作为背景信息拼接进Prompt。这样既不丢关键信息,又控制住了成本。制度查询里有一种很典型的场景:用户先问A制度,再问B制度,之后又问“那A和B哪个标准更高?”这时候如果只保留最近四轮,可能就把A制度的细节给冲掉了。于是我们又在摘要策略之上加了一个“关键实体保留表”,把之前对话中出现过的制度名和参数以表格形式追加在上下文尾部,确保实体的可回溯性。

3.4 制度检索层:不迷信向量话术

制度查询里最核心的工程环节是什么?我认为是混合检索的设计。纯向量检索在外面宣传得很多,但实际测下来,中文制度文档里的专业术语和简称特别多,比如“差旅费”和“出差费用”在向量空间上确实相近,但“特批”和“权限外审批”这种不太常见的关联,向量召回很容易漏。

我们的检索层采用了双通道设计。通道一是BM25关键词检索,用来保证字面命中的准确率;通道二是向量检索,用来保证语义泛化的召回率。两路结果各取Top20,然后用一个小的重排序模型做融合,选出最终的Top5片段送进大模型。

这个设计比直接单走向量检索的效果稳定很多。在100条真实测试问题上,Hit Rate从纯向量的78%提升到了94%,看起来提升不大,但对制度问答来说,差的那16%恰恰是使用者最关心的那种“模糊问题”。比如用户问“三个月以内的短期借款要什么手续”,制度原文里根本没有“短期借款”四个字,只有“借款期限不超过九十天”这样的表述。这种问题只有靠语义召回才能找出来。

注意:做混合检索时,关键词通道的权重不要调得太高,否则很多口语化问法会匹配到一堆看似相近但实际无关的制度标题,反而拉低精度。我们的经验是,BM25和向量的初始权重设为4:6,再根据验证集上的效果微调。

3.5 最终答案生成的安全护栏

制度问答对严谨性的要求很高,不能让模型自由发挥,更不能凭空捏造不存在的条款。我们在生成阶段加了三个安全护栏。

第一个是检索片段引用约束。Prompt里明确要求:答案只能基于提供的检索片段生成,如果片段里没有相关信息,必须回复“制度文档中未查询到相关内容”,绝不能编造。同时要求生成答案时在句末用[1][2]这种形式标注引用来源编号,方便用户点进原文去核对。

第二个是风险提示注入。对于报销、请假、借款这类涉及钱和审批的高敏感查询,我们会在答案尾部自动附带一句“以上信息仅供参考,具体以最新制度版本为准”的提示。这不是废话,因为在真实业务里,制度可能存在新旧版本交替期,系统检索到的可能是旧版本文档,主动提示可以降低误解风险。

第三个是输出格式校验。模型生成的答案在返回前端之前,会经过一个格式校验器,检查是否包含了明显的幻觉用词,比如“一般来说”“按照惯例”这类不能用在不严谨制度场景里的表达。一旦命中,就触发一次重新生成。这个校验逻辑不能完全杜绝幻觉,但至少能减少不靠谱的模糊答复。

4. 常见问题与排查技巧实录

4.1 多轮对话中的“失忆”问题

联调阶段我们遇到最多的一个问题,就是对话到了第三轮、第四轮之后,模型突然不理解用户指代的内容了。比如用户说“那刚才说的那个制度需要什么材料?”,模型把“那个制度”理解成了当前正在聊的制度,但实际用户可能指的是三分钟前提到的另一个制度。

排查之后发现,问题出在消息历史的截断策略上。我们最初只用了一个固定的四轮窗口,当对话超过四轮,早先的制度名就被截掉了。后来调整了策略,关键实体保留表就是为这个问题设计的。电子表格里固定存着当前对话周期内出现过的所有制度全称、简称和参数,在每次生成答案之前都会被追加进Prompt。这个改动立竿见影,“指代消解”准确率从70%提高到了92%左右。

这个问题的本质是,上下文管理不是简单的“截断或压缩”,而是要区分哪些信息对当前任务来说是关键的、必须保留的。做Agent框架选型时,一定要确认框架是否支持这种定制化的上下文注入能力。如果框架内部把上下文处理封装得死死的,这个坑就可能一直踩到上线。

4.2 工具调用的“死循环”

第二个典型问题是模型认为某个参数缺失,反复调用同一个工具而不出结果。举个例子,用户问“三级的报销标准”,但系统里职级有“专员三级”“经理三级”“总监三级”,模型不确定是哪一个,于是一遍又一遍地调用list_reimbursement_standards,每次都因为参数不全返回空结果,死循环。

排查方法比较简单:在LangGraph里给工具调用节点加了次数的监控日志,发现同一工具被连续调用五次以上,且每次的入参都一样,就说明模型在打转。解决方案是增加了一个“参数澄清前置节点”。在调用工具之前,如果模型认为参数不完整,先走一次澄清对话,把缺失参数问清楚,而不是直接尝试错误调用。同时,为每个工具增加了一个“最小可用参数”的校验逻辑,参数不够直接返回“参数缺失”而不去访问后端接口,节省了不必要的调用开销。

这个经验对任何Agent项目都适用。别让模型在“参数不完整的模糊状态”下去调用工具,那大概率会浪费Token,还会产生一些奇怪的中间结果。

4.3 检索片段太长导致答案跑偏

有一类问题在知识库问答里特别常见:检索回来的Top5片段内容太长,每个片段有几百上千字,大模型在生成时被无关信息带偏了。尤其是制度文档里经常有大段的“适用范围”“职责分工”这类前置章节,它们和具体的“操作步骤”混在一起,模型就容易把职责分工的内容当成操作步骤回答给用户。

我们做了两处优化。第一处是检索后处理,把命中的章节按“条款类型”做分类,比如“适用范围”“审批权限”“材料要求”“报销标准”,然后根据用户的查询意图只保留相关类型。第二处是片段切分粒度,把原来的固定512字切分改为按“条款”切分,尽量让每个片段对应一条完整制度条款,而不是把好几条混在一个窗口里。切分工作做在前端文档处理阶段,而不是在检索阶段用滑窗硬凑,效果会好得多。

4.4 问题排查速查表

我把联调过程中最常见的几类问题整理成了一份速查表,方便大家在类似项目里直接对照:

现象可能原因排查路径解决方案
多轮对话突然答非所问历史消息截断策略过于粗暴查看该次会话的完整Prompt输入,检查旧消息是否被截掉增加关键实体保留表,用结构化摘要替代简单截断
工具被反复调用但不落库模型在参数不足时反复试探检查工具调用次数监控日志,比对入参是否相同增加参数预检和澄清前置节点
答案引用了无关章节内容检索片段不干净,含大量前置条款检查最终送入Prompt的检索片段内容按条款类型过滤片段,细化切分粒度
模型编造不存在的制度条目Prompt约束不严,检索为空未兜底检查空检索分支的回复逻辑增加强制引用标注和空结果兜底话术
Token成本超预算上下文叠加太厚,历史窗口塞满全文统计每次调用的Token组成用摘要替代完整历史,设置最大工具循环次数

4.5 框架选型的三个忠告

整趟下来,我的核心体会可以浓缩成三句话。

第一句,不要迷信框架的品牌。同样一套流程,在演示环境里跑得飞快的平台,接上你们公司内部的API以后可能天天报错。选型之前,拿一套真实的业务场景数据,让每个候选方案跑通一条完整链路,比看任何技术文档都管用。具体来说,跑通的定义是:至少十轮真实对话不崩溃、工具调用结果能正确格式化、连续运行三天不出现上下文越堆越大的情况。

第二句,Agent框架的能力边界在工程化,不在模型能力。你现在觉得某个框架很灵活,等真正要上线的时候,你会发现团队需要的是日志、监控、回放、降级方案、以及可控的成本。我一个朋友的做法是,直接在框架选型阶段就要求候选方案提供监控面板的演示,不能提供的一票否决,这个方法后来被证明非常有效。

第三句,先看清自己是哪种团队。团队人数少、但每个人都能写代码,适合代码优先的方案;团队业务人员多、需要自己配置Agent流程,那低代码平台更现实。归根结底,选框架就是选一个自己能驾驭的复杂度上限,不要被外部的“All in Agent”概念带着跑。

5. 从选型到落地的思考

回到开头那个问题,AI Agent框架怎么选,我的答案是:把具体的业务场景往前多推一步,再去选框架。框架不是越强大越好,而是越能贴合你的核心流程越好。制度查询这个场景虽然听上去不够“性化”,但它把Agent最关键的几个技术要素都暴露出来了——状态管理、工具调用、上下文控制、检索质量、以及成本消耗。把这些问题一个个解决掉之后,框架的技术边界自然就清楚了。

我个人在实际操作中的体会是,选型文档写得再漂亮,都不如把两个候选框架放在同一组业务数据上飙一轮来得直观。别怕试错,代码优先的框架前期搭建稍慢,但后期的调整空间和可调试性,确实比那些拖拽配置的平台要好太多。这个项目现在还在持续迭代,下一步我们计划加入制度版本比对能力和基于用户行为的个性化推荐,这些都是依赖现有框架的定制能力去实现的。框架的边界不是限制,它才是你真正制定技术路线的起点。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询