☰
LlamaIndex实战:LLM在RAG流水线中的五大工程场景
2026/10/18 22:33:55 网站建设 项目流程

在LlamaIndex里做过几个RAG项目之后,我对“LLM到底在管什么”的认知被彻底刷新。很多人以为它只是最后回答问题的那张嘴,实际上从文档进入索引那一步开始,LLM就已经深度参与:数据摄取、查询理解、结构化操作、Agent编排、质量评估,每个环节它都能扛不同的活。这篇文章就围绕我在实际工程里反复用到的五类场景展开,把搭建思路、代码片段和踩过的坑一并写上。适合正在用LlamaIndex做企业知识库、复杂问答、多文档分析,或者准备把RAG从“Demo能跑”推向“线上能扛”的人。

1. 先摸清全貌:LLM在LlamaIndex的流水线里干了哪些活

1.1 一条典型数据流里,LLM卡位的五大环节

LlamaIndex不是一个简单的“文档塞进去、问题丢出来”的黑盒。把它拆开看,它的流水线大致是:数据接入与解析入库、索引构建、查询规划、检索器召回、响应合成,再外面还有Agent循环和评估层。

在这条流水线里,LLM可以出现在几乎每一个“需要理解语义”的位置。我按工程里最常见的分工,把它的核心应用归纳成五个方面:

环节LLM承担的核心任务典型落地对象
数据摄取提取元数据、生成摘要、抽取实体关系MetadataExtractor、KnowledgeGraphIndex
查询理解改写、扩展、压缩查询,判断去哪个数据源QueryTransform、RouterQueryEngine
结构化交互把自然语言转成SQL、查询图谱三元组NLSQLTableQueryEngine、GraphIndex
Agent编排选择工具、拆解任务、多步执行、结果整合FunctionCallingAgentWorker
质量评估判断答案是否忠实、是否相关,生成评测集FaithfulnessEvaluator、RelevancyEvaluator

这五类不是并列的小工具,而是层层递进的关系。数据摄取决定了系统“知道什么”,查询理解决定了“怎么问”,结构化交互决定了“能不能问出深度”,Agent编排决定了“复杂任务能不能自己拆”,评估决定了“你敢不敢把它放上线”。很多项目只把LLM用在最后一个问答环节,前面全靠字符串匹配和向量相似度,效果当然能跑,但一遇到长尾表达就露馅。

1.2 配置前必须想清楚的边界:LLM和传统程序各管哪一段

聊应用之前,我觉得先把边界厘清更重要。LlamaIndex里不全靠LLM,底层很多模块是传统确定性算法,比如文档切分的规则、embedding模型的向量化、向量索引的最近邻检索、SQL执行器本身的运算。这些环节你用LLM去替代,往往是画蛇添足。

我现在的划分方式是一句话:凡是“有标准答案、需要精确计算、需要可复现”的事,尽量交给传统代码;凡是“语义开放、表达多样、需要理解意图”的事,才值得把LLM叫出来。比如让LLM算一个订单总金额,它可能会因为读错数字而翻车,但让它把问题“上个月哪个品类的退货率最高”改写成“SELECT对应字段”的意图,它做得很好。

另一个容易被忽略的问题是:同一个LLM不一定适合所有环节。我在某个项目里曾用一个开源小模型同时做元数据提取和SQL生成,结果关键词提取勉强能用,SQL生成一塌糊涂。后来把策略改成“重任务用强模型,轻任务用弱模型”,成本反而降了,因为强模型的调用次数少了。这件事放到后面每个环节里都成立,不要在全局只配置一个LLM就万事大吉。

2. 第一类:文档摄取阶段的LLM指令——入库前先加工一遍

2.1 元数据提取让检索从“全文比较”变成“属性过滤”

很多初版RAG系统都是直接把文档切块后全部向量化,查询时做相似度匹配。这种做法不是不行,而是效率低、噪音大:一个十几页的PDF,真正和问题相关的可能就一小段,但你仍然要把所有片段都过一遍相似度,还可能被相似但无关的段落干扰。

LLM在入库阶段能做的最实际的一件事,就是提取结构化元数据。LlamaIndex里的MetadataExtractor可以让你给每个节点打上标题、关键词、主题等标签。我常用的是这样一套配置:

from llama_index.core.extractors import ( MetadataExtractor, TitleExtractor, KeywordExtractor, ) from llama_index.core.node_parser import TokenTextSplitter extractor = MetadataExtractor( extractors=[ TitleExtractor(nodes=5), KeywordExtractor(keywords=15), ], ) node_parser = TokenTextSplitter( chunk_size=1024, chunk_overlap=64, )

这段代码做的事情很直白:把长文档切块后,每块额外生成一个标题和一批关键词。有了这些字段后,我可以在查询阶段先按关键词过滤,再去向量检索,召回精度提升非常明显。举个例子,一个合同库里有采购合同、服务合同、保密协议,如果节点上面有“合同类型”这个元数据,用户问“保密协议里仲裁条款怎么写的”,就能先过滤掉八成无关内容。

这里有个容易理解偏差的点:标题和关键词这类信息,常规规则其实也能提取一部分,比如正则抓日期、按文件路径猜分类。但开放域的文档没有那么好的规律,LLM的价值在于它不需要预先定义每个文档类型,就能给出语义上合理的标签。这也是为什么很多知识库项目把这一步当作标配。

2.2 摘要、剥离与节点组织的实际做法

入库阶段的另一个高价值操作是生成节点摘要。摘要不是简单地把内容缩短,而是给检索和问答提供一个“概览层”。我在做多文档问答时经常遇到的情况是:用户问的是跨文档的对比问题,比如“三份报价单里有哪些不同”。这时候如果把每份文档的原始切片都交给LLM去比较,上下文窗口很快被撑爆。更聪明的做法是让LLM先为每份文档生成一个摘要节点,检索层先命中摘要,然后再深入对应的原始切片。

我用过一段比较顺手的配置,给摘要节点打了一个独立的类型标签:

from llama_index.core.schema import MetadataMode # 示意:在已有节点基础上生成摘要,并给节点打上 type 字段 for node in nodes: summary = await llm.acomplete( f"请用3-5句话总结这个文档片段的核心内容:\n{node.text}" ) node.metadata["node_type"] = "summary" node.metadata["summary_text"] = str(summary)

这种做法等于给知识库建立了一个“先看目录、再翻正文”的阅读习惯。检索时如果问题的概括性很强,就先命中摘要节点;如果问题问到具体数字,再落到原始切片。实际测下来,这种分层检索对长文档问答的帮助比单纯调大chunk_size更明显。

还要注意,切片数量越多,需要LLM生成的摘要数量越大,这一步通常离线执行,别等用户提问时才现算。我的习惯是文档一进来就异步跑一遍加工管道,加工结果持久化到索引里,线上查询完全不碰提取任务。

2.3 我在跑批处理时踩过的token和稳定性问题

这里一定要说几个坑,几乎每个项目都会遇到。

第一是token消耗被低估。假设你有一万份文档,每个节点用LLM生成一次摘要和关键词,平均每次消耗几百token,一轮下来就是几百万token。所以我后来强制给自己定了一条规则:摘要任务用强模型,关键词提取用轻量模型,二者分开配置。很多框架支持按不同组件指定不同LLM,别嫌麻烦,这个收益直接体现在账单上。

第二是失败的幂等处理。大模型调用偶尔会超时、返回空内容、或者返回一段JSON解析失败。批量跑的时候如果进程中途挂了,最好支持断点续跑。我一般会把“已生成的摘要文本字段是否为空”当作处理状态标记,跑完之后扫描一遍缺失字段再补跑,而不是每次重新全量执行。

第三是截断问题。LLM对长文档做摘要时,如果直接传入整个节点文本,后台可能会悄悄截断,导致摘要只覆盖前半段。规避办法是控制输入长度,超过上限的分两次摘要再合并。这也是为什么我习惯先切块再做摘要,而不是把整份文档直接扔给模型。

3. 第二类:查询面的理解与路由调整——让检索入口变得更聪明

3.1 查询转换:多查询、折叠、HyDE类改写

数据加工完之后,检索不是直接从问题跳到向量,中间还需要一个查询理解层。原因很简单:用户的问题通常很口语化,而文档里的表述往往更书面。用户问“最近一波行情对制造业的冲击”,文档里可能只有“供应链中断”“订单波动”之类的话,直接拿原问题去做向量匹配,召回效果会打折扣。

LlamaIndex里处理这个问题的主要思路是查询转换,它的目标是把“用户的原始表达”变成“更可能在文档中命中语义的表达”。我常用的几种方式包括:

  • 多查询:让LLM根据原问题生成多个同义改写,分别去检索,最后合并结果去重。适合文档里同一件事有不同叫法的场景。
  • 子问题拆分:把“A和B的区别是什么”拆成“A有什么特征”“B有什么特征”“二者有哪些共同点”等子问题,分别检索再拼答案。
  • 假设性文档Embedding(类似HyDE的做法):让LLM先根据问题写一段“如果文档里有答案,它大概会怎么写”的假想回答,再用这段假想回答去做向量检索,能吃下不少表述差异。

用官方组件来实现多查询,大致的框架长这样:

from llama_index.core.query_engine import RetrieverQueryEngine from llama_index.core.retrievers import QueryFusionRetriever retriever = QueryFusionRetriever( [vector_index.as_retriever(similarity_top_k=4)], num_queries=4, mode="reciprocal_rerank", use_async=True, ) query_engine = RetrieverQueryEngine.from_args(retriever)

我建议从单路改写开始做,别一开始就铺多路召回。多查询意味着多个LLM调用和多次检索,查询延迟会成倍上涨。对于响应时间敏感的场景,先评估原始查询是否足够清晰,再决定要不要做扩展。我在一个客服场景里把多查询的开关做成动态的:当第一轮检索分数低于阈值时才触发多查询,效果和全量开启接近,但成本低了很多。

3.2 LLM做路由:数据源选择与索引选择

不少人忽略的一个事实是:企业里很少只有一个知识库。可能是SQL数据库加上文档库,再加上一个操作手册Wiki,用户一句话可能需要去不同数据源找答案。这时候LLM的用途是当“路由分发器”,决定该去哪个索引或工具里查。

LlamaIndex里的RouterQueryEngine就是干这个的。它的核心想法是:每个查询引擎被描述成一个带说明的工具,LLM根据用户问题判断哪个工具最合适。我一般这样组织:

from llama_index.core.query_engine import RouterQueryEngine from llama_index.core.tools import QueryEngineTool sql_tool = QueryEngineTool.from_defaults( query_engine=sql_query_engine, description="用于查询订单、价格、库存等结构化数据。", ) doc_tool = QueryEngineTool.from_defaults( query_engine=doc_query_engine, description="用于查询产品手册、制度文件等非结构化文档。", ) router = RouterQueryEngine.from_defaults( query_engine_tools=[sql_tool, doc_tool], selector=LLMSingleSelector(llm=llm), )

这个思路很简单,但实际工程里有三个坑。

一是工具描述不能写得太模糊。如果你只写“查询订单数据”,LLM可能把“上个月的销售额是多少”这种统计问题也丢给文档检索,而不会去SQL引擎。我后来在描述里明确加上“支持聚合、筛选、按时间范围统计”等关键词,路由准确率立刻上来了。

二是路由失败的兜底非常关键。我见过不少系统,路由判断错了就直接答错。稳妥的做法是加一个默认兜底引擎,当LLM对路由结果不确定时,路由到“同时检索多个数据源再合并”。代价是慢一点,但至少不会因为路由错误而给出完全无依据的回答。

三是日志里一定要能看到路由结果。每次用户问题最终走了哪个工具,这个信息对调试极有价值。你可能会发现,大量问题被路由到了同一个工具,而另一个工具几乎无人问津,那要么是描述有问题,要么是业务上那个数据源本来就不该接入。

3.3 一个带降级策略的路由配置示例

我在生产环境里常用的不是单一Router,而是叠加了降级策略。大体逻辑是:先用轻量分类器判断问题是否包含“统计、金额、数量”这类结构化信号,命中就强制走SQL工具;否则走LLM路由;如果LLM路由给出的置信度很低,默认落到向量检索。伪代码如下:

def route_query(question: str): if contains_struct_signal(question): return "sql" result = llm_complete( f"判断问题应使用哪个工具:\n{question}\n" f"可选:sql / docs / both / none" ) if result in ("sql", "docs", "both"): return result return "docs" # 默认兜底

这不是什么高深技术,但能很大程度避免花哨的LLM判断带来低级的错误。很多团队一上来就用RouterQueryEngine,却忘了它的输出本质上是一个概率判断,不是绝对真理。再加上一层业务规则和兜底,系统才会稳。

另一个经验是:路由查询和普通检索最好分开配置模型。路由任务对LLM的推理要求不高,但对速度和成本敏感,用一个中等偏小的模型就够了。真正需要把大模型资源留给后端答案生成的阶段。

4. 第三类:自然语言转结构化操作——SQL与知识图谱场景

4.1 Text-to-SQL引擎的搭建思路

文档向量检索擅长处理非结构化内容,但企业问答里大量问题是结构化的:订单金额、库存数量、每个月的变化趋势。这些问题需要精确计算,向量模型给不了可靠的数字答案,这时候就得让LLM去生成SQL。

LlamaIndex里有NLSQLTableQueryEngine这类组件,我通常会用类似下面的方式建立SQL问答能力:

from llama_index.core.query_engine import NLSQLTableQueryEngine from sqlalchemy import create_engine engine = create_engine("sqlite:///sales.db") sql_query_engine = NLSQLTableQueryEngine( sql_database=engine, tables=["orders", "customers", "products"], llm=llm, )

它内部的逻辑是:先把数据库表结构注册到LLM上下文里,用户提问后,LLM生成一个SQL,框架再执行SQL并把结果返回。这套流程有两个明显的好处:第一,用户不需要懂SQL;第二,只要SQL正确,答案数值就是精确的,不存在编造。

但Text-to-SQL远没有看上去那么省心。我踩过最典型的问题就是“表结构太多导致生成错误”。当数据库有几十张表时,如果全部塞给LLM,它会经常选错表或写错关联关系。解决办法有两个方向:一是只给问题可能涉及的表,减少干扰;二是在表名和字段名后面附上一句话注释,比如“order_status表示订单状态,1为已支付,2为已取消”。LLM去理解带注释的表结构,比裸看字段名可靠得多。

另外,强烈建议给SQL执行加一道安全校验。给LLM一个只读权限的数据库账号,禁止DROP、DELETE这类危险操作。这个不是LlamaIndex框架层的配置,而是你连接数据库时就应该做好的事情。我见过有人直接用生产库连接字符串去跑NL2SQL,吓得我当时就让他改了。

4.2 知识图谱索引中的实体与关系抽取

结构化交互的另一大场景是知识图谱问答。它解决的问题是“多跳关系推理”,比如“某项目由哪个团队负责,该团队之前是否做过同类项目”。这类问题如果靠向量检索,每一跳都可能有语义偏差,答案往往东拼西凑;而图谱能把实体和关系连起来,答案来源更清楚。

构建知识图谱Index时,LLM负责从文本里抽取实体和关系三元组。类似下图这样:

from llama_index.core.indices.knowledge_graph import KnowledgeGraphIndex kg_index = KnowledgeGraphIndex.from_documents( documents, llm=llm, include_summary=True, max_triplets_per_chunk=10, )

抽取三元组的效果,很大程度上取决于模型对实体边界的理解。同一个“苹果”,在一篇讲水果的文档里是食物,在一篇讲科技公司的文档里是公司。所以我一般在给LLM的提示词里明确加上“结合上下文判断实体类型,不要所有专有名词都当成公司名”这样的约束。这个提示词看起来不起眼,但在实际评测里可以把三元组准确率提升一截。

知识图谱不能替代向量索引,它们更像是互补关系。向量索引适合“找相关段落”,图谱适合“找关联路径”。在实际系统里,我通常会把文档同时建两种索引,让路由层决定什么时候用哪一种。如果问题明显需要关系链推理,走图谱;如果只是按主题找资料,走向量。

4.3 什么情况下不该硬上这类结构化能力

聊到这儿必须泼一盆冷水:不是所有问题都值得上SQL或图谱方案。我有一次遇到一个项目,产品经理希望所有合同条款都能做精确对比。听起来很适合图谱,实际上合同文本这种强规则文本用结构化抽取成本极高,而且条款之间的差异常常是自然语言层面的细节,三元组表达不了那么细。最后我们还是用了带条款编号的元数据过滤加摘要对比,效果反而好。

我的判断标准有三个:

  • 问题是否频繁要求精确数值:是,考虑SQL;否,向量检索足够。
  • 实体之间的关系是否稳定且可枚举:是,图谱有优势;关系高度开放,图谱维护成本会失控。
  • 数据质量是否支持结构化:如果源数据本身就是噪声很大的OCR文档,先清洗数据,别急着建图谱。

结构化能力的建设成本远高于普通的向量索引,它需要更仔细的数据建模、更干净的元数据、更长的调优周期。如果用户实际问答里这类需求占比不高,理性选择是先用文档检索顶住,把结构化能力放到第二阶段迭代。

5. 第四类:Agent编排与多步规划——LLM开始当调度员

5.1 工具选择与函数调用的运行机制

当你把“查询文档”“查数据库”“发请求”“写文件”这些能力都封装成工具后,单轮的检索问答就不够用了。用户的问题往往需要组合多个工具,比如“查一下最近三个月的销售额,再对比去年同期,把差距最大的品类列出来”。这中间涉及两步查询,甚至可能需要调用一次计算工具。这时LLM的角色从“信息生成者”变成了“任务调度员”。

LlamaIndex里的Agent机制核心是函数调用,框架把工具列表暴露给LLM,LLM在对话循环里自己决定调用哪个工具、传什么参数、然后再根据结果决定下一步动作。我在项目里通常这样组织:

from llama_index.core.agent import FunctionCallingAgentWorker from llama_index.core.tools import QueryEngineTool tools = [ QueryEngineTool.from_defaults( query_engine=sql_engine, description="查询销售、客户、产品结构化数据,支持聚合统计。", ), QueryEngineTool.from_defaults( query_engine=doc_engine, description="查询产品手册、技术文档、Wiki等非结构化内容。", ), ] agent_worker = FunctionCallingAgentWorker.from_tools( tools, llm=llm, max_iterations=8, verbose=True, ) agent = agent_worker.as_agent()

它的运行机制可以通俗地理解为:LLM拿到用户任务后,先想“要解决这个问题需要哪些信息”,然后调用第一个工具,拿到结果,再判断信息够不够,不够就继续调下一个工具,直到拼出完整答案。传统程序靠if-else写分支,Agent靠LLM动态决策分支。

5.2 一个多文档摸查Agent的构建片段

我做过一个比较典型的案例,输入是若干份技术评估报告,用户不是问某一篇报告的内容,而是要横向比较“哪份方案的成本最低、风险最大、交付周期最短”。这属于跨文档归纳任务,单靠检索很难一次完成,用Agent就顺很多。

我的做法是给Agent注册两个工具:一个是“按文档名检索特定报告内容”,另一个是“跨文档汇总比较”。Agent会先分别调第一类工具拿到每份报告的关键段落,再调用第二类工具做汇总生成。过程中它的轨迹类似于:

  1. 识别问题需要比较三份报告。
  2. 调用工具A,检索第一份报告的成本和风险段。
  3. 调用工具A,检索第二份报告的成本和风险段。
  4. 调用工具A,检索第三份报告的成本和风险段。
  5. 调用工具B,把三段信息综合成对比结论。

这里面最关键的是每个工具的描述要足够清楚地告诉LLM“这个工具能干什么、不能干什么”。比如“工具A只能单篇检索,不能跨文档对比。跨文档对比请用工具B”。限制条件写得越明确,Agent跑偏的概率越低。

5.3 生产环境里我反复遇到的三个Agent坑

Agent看起来很美好,一旦上线,坑也不少。我根据自己的实践列三个最常遇到的。

第一,死循环。LLM可能反复调用同一个工具,返回结果还是一样,然后它继续调用。这通常是因为工具返回的信息不含“任务已经解决”的信号。我的解决方式是设硬性的迭代上限,比如8次,同时在每轮工具结果里加一个简短的“已找到关键信息”或“仍缺少信息”的状态说明,帮助LLM判断何时停止。

第二,上下文膨胀。Agent把多轮工具结果都塞进了对话历史,每调用一次工具,token占用就涨一大截。跑到第6、7轮时,上下文窗口可能就被塞满了,后面的决策质量直线下降。我的经验是:工具返回长文档时先做裁剪,只保留与当前任务最相关的段落;更狠一点的做法是,超过三轮后要求LLM输出阶段性摘要,把前面内容压缩掉。

第三,工具权限过大。Agent本身没有善恶判断,它只负责完成目标。如果你把删除文件、写外部API等危险能力也包装成工具,一旦用户问题被提示词注入,后果很难收拾。我的原则是:Agent能看到的工具必须是最小权限集合,查询类Agent只给只读工具。永远不要让Agent在无人工确认的情况下执行有副作用的操作。

6. 第五类:拿LLM评估LLM——让输出质量可度量

6.1 检索评估里“LLM裁判”的评判逻辑

前面四个应用都是让LLM去“做事”,第五个应用恰好反过来:让LLM去“挑错”。一个RAG系统上线之前,你不光要知道答案能不能生成,还要知道答案是不是“忠实于证据”的。坏的情况是检索到的文档本身就不相关,LLM硬生生编了一个听上去合理的回答。这种情况人工排查效率低,用LLM当裁判来做自动评估就成了刚需。

LlamaIndex里有两个我常用的评估器:FaithfulnessEvaluator和RelevancyEvaluator。前者检查“回答是否忠实地建立在检索上下文上,而不是凭空捏造”,后者检查“回答是否真正回应了用户的问题”。我一般把它们串起来用:

from llama_index.core.evaluation import ( FaithfulnessEvaluator, RelevancyEvaluator, ) faithfulness = FaithfulnessEvaluator(llm=llm) relevancy = RelevancyEvaluator(llm=llm) eval_result = await faithfulness.evaluate_response( query=query, response=response, )

这两个评估器的逻辑都是让LLM以标准Prompt判断,输出是/否和理由。它们的价值在于可以批量跑评测集,不用人工一条条看。但要注意,它们本质上是另一个LLM的主观判断,同样有可能出错。所以我从来不把单一的LLM裁判分数当作绝对标准,而是当作筛选工具:分数低的直接看理由,分数高的抽检确认。

6.2 自动合成评估数据与提升指标

没有测试集就谈不上系统优化。手工标一条Q-A对成本高、速度慢,所以很多团队会采用合成数据的方式生成评测集。具体做法是拿一批真实的领域文档,让一个强LLM在阅读文档后生成“问题-标准答案-参考来源”的组合。这个组合自动覆盖了不同难度的查询,之后再拿你的RAG系统去跑,看答案能不能覆盖到参考来源,以及答案的相关性和忠实度如何。

我自己常用的做法是:问题分成三类,简单抽取型、归纳总结型、多跳推理型。分别统计通过率,就能知道你的检索链路短板在哪。比如简单抽取型通过率高,但多跳推理型通过率很低,说明当前检索召回的多是单一来源片段,缺少跨文档组合能力。这时候就该考虑上Agent编排或者知识图谱来补充多跳检索。

合成数据也有一个明显问题:LLM生成的测试问题经常过于规整,不像真实用户的表达。比如用户会问“之前聊的那个事情进展怎么样”,而合成问题往往是完整的书面语。所以合成评估集要和少量真实用户问题混用,比例大概可以控制在“真实问题三成、合成问题七成”。完全没有真实问题的评测集,指标再好看,上线也可能翻车。

6.3 评估器也要被校验:如何防止LLM裁判失真

LLM裁判同样会偏好某种表达风格,比如它可能偏爱更长的答案、偏爱列点式回答、甚至偏爱使用特定连接词的句子。这些偏好会导致评估分数和人工判断不一致。我在一个项目中就遇到过:忠实度评估器几乎给所有结构化列点回答打了满分,仔细看理由才发现,它把“回答格式规范”当成了“忠实”。

解决这类问题,我的经验是分三步。第一,小范围人工标注一批问答对,比如100条,把人工分数和LLM裁判分数对比,找出系统性的偏差;第二,如果发现裁判对长度敏感,就在Prompt里明确约束“忽略答案长度,只看是否基于上下文”;第三,最终指标建议综合多个评估器,而不是只信一个分数,比如同时看Faithfulness、Relevancy和正确答案语义相似度三者的加权结果。

还有一点是 Prompt 中的评价标准要尽可能具体。让LLM判断“是否相关”时,给一个例子比给十句抽象定义都有效。“比如查询中问到退款政策,而回答只介绍了商品规格,则判定为不相关”,这种示例能明显降低裁判打分的波动。所有评估器上线前,都值得先拿几十条人工标注样本把标准对齐一遍。

到现在我自己的项目里已经习惯把这五个应用编进同一条流水线:数据入库时让LLM抽取元数据,查询入口让LLM路由和改写,遇到结构化需求就让LLM生成SQL或图谱查询,复杂任务交给Agent编排,最后再开一层自动评估来盯着整体质量。每一步都单独调优过,但真正让系统稳定的,是它们在同一套配置里彼此协作。如果你正在打算把LlamaIndex落地到真实业务,我建议别急着一次性全铺开,先选当前最痛的环节切入:检索不准就先做查询理解和元数据提取,答案老出错就先上评估层。跑起来再逐步加后面的能力,这样每一步的收益都看得见,也更容易说服团队继续投入。

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

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

立即咨询