告别RAG新手村!吃透系列(七):Advanced RAG之查询分解,解锁高阶检索能力!
在 RAG 技术落地过程中,Naive RAG往往在面对复杂问题时显得力不从心 ——当用户提出 “对比不同行业RAG落地策略的差异,并分析医疗领域实施难点及解决方案” 这类多维度查询时,单轮检索难以精准覆盖所有核心问题,容易出现信息遗漏或检索偏差,最终导致生成答案逻辑断裂、相关性不足。而查询分解技术作为 Advanced RAG 预检索阶段的关键优化手段,通过将复杂查询拆解为简单子任务,实现精准检
在 RAG 技术落地过程中,Naive RAG往往在面对复杂问题时显得力不从心 ——当用户提出 “对比不同行业RAG落地策略的差异,并分析医疗领域实施难点及解决方案” 这类多维度查询时,单轮检索难以精准覆盖所有核心问题,容易出现信息遗漏或检索偏差,最终导致生成答案逻辑断裂、相关性不足。而查询分解技术作为 Advanced RAG 预检索阶段的关键优化手段,通过将复杂查询拆解为简单子任务,实现精准检索与逻辑化生成的闭环,成为解决这一痛点的核心方案。
一、什么是查询分解技术
查询分解技术本质是借助LLM的逻辑推理能力,将用户的复杂原始查询,按照语义关联与逻辑层次拆解为多个独立可解的子查询,通过分别完成每个子查询的检索与回答,最终整合所有子结果形成完整答案的技术手段。其核心逻辑围绕 “化繁为简、分而治之” 展开,精准命中Advanced RAG “提升检索精度与生成质量” 的核心目标。
从信息流动视角来看,它在RAG流程中承担着 “意图精准解析” 的关键角色:原始查询往往包含多个隐含需求,直接检索易因语义范围过宽或逻辑链条过长导致召回偏差,而查询分解通过拆分出 “行业 RAG 落地策略分类”、“各行业策略差异点提炼”、“医疗领域实施难点梳理”、“医疗场景解决方案汇总” 等子查询,将模糊的用户意图转化为系统可精准处理的具体任务指令,为后续检索环节提供明确方向。
与基础查询优化手段相比,查询分解更侧重 “逻辑解构” 而非简单的语义扩展:查询改写仅对原始问题进行表述优化,查询扩展是增加关联词汇丰富检索维度,而查询分解直接深入查询的逻辑内核,拆分后的子查询既相互独立又存在内在关联,共同构成原始问题的完整答案框架,从根源上解决复杂问题的检索碎片化问题。
二、为什么需要查询分解
Naive RAG在处理复杂查询时的短板,正是查询分解技术的核心价值所在,具体可概括为三大痛点破解:
1. 解决检索范围模糊,提升召回精准度
Naive RAG 对复杂长查询的检索依赖单一向量匹配,难以覆盖多维度需求,容易出现 “漏检关键信息” 或 “召回无关内容” 的问题。例如面对 “如何搭建支持法律条款解读的 Advanced RAG 系统,需包含哪些技术模块及落地步骤”,直接检索可能仅返回部分技术模块介绍,遗漏落地步骤或场景适配细节;而分解为 “法律领域 RAG 核心技术模块”、“法律场景检索优化方案”、“Advanced RAG 落地实施步骤” 等子查询后,可定向召回各维度精准信息,检索精准度显著提升。
2. 化解逻辑推理不足,强化答案连贯性
复杂问题的答案往往需要多步骤逻辑推导,Naive RAG 缺乏对查询逻辑的拆解能力,生成答案易出现逻辑断层。查询分解通过按逻辑层次拆分查询,让每个子查询的应答形成独立逻辑单元,整合后自然呈现清晰的推理链条。以 “分析 Advanced RAG 相比 Naive RAG 的优化点,及其在客服机器人场景的应用优势” 为例,拆解为 “Naive RAG 核心局限”、“Advanced RAG 关键优化方向”、“客服场景 RAG 核心需求”、“进阶方案应用优势” 子查询后,答案会遵循 “问题 - 优化 - 需求 - 优势” 的逻辑展开,连贯性与说服力大幅提升。
3. 适配长文档与多源知识,降低信息过载风险
在处理长文档或多源知识库检索时,基础 RAG 易因上下文过长导致关键信息被稀释。查询分解后的子查询聚焦单一知识点,可针对性检索对应文档片段,避免无关信息干扰。例如检索长文档中 “RAG 全链路优化策略” 时,拆解为 “预检索阶段优化手段”、“检索阶段升级方案、”“检索后处理技巧” 子查询,能分别定位各环节内容,既提升检索效率,又减少 LLM 生成时的上下文过载问题。
三、查询分解技术实施要点:从拆解到整合的全流程
查询分解并非简单的问题拆分,需遵循一定原则与流程,才能确保子查询的合理性与最终答案的完整性,核心实施步骤可分为三步:
1. 精准拆解:遵循三大原则,保障子查询有效性
查询问题拆解环节是技术核心,需依托 LLM 实现结构化输出,同时遵循以下原则:
- 独立性原则:每个子查询需聚焦单一知识点,可独立完成检索与应答,避免子问题交叉重叠;
- 完整性原则:所有子查询共同覆盖原始问题的全部需求,无核心信息遗漏;
- 逻辑性原则:子查询拆解需符合人类认知逻辑,按 “总 - 分”、“先因后果”、“从基础到进阶” 等层次排序,便于后续答案整合。
2. 定向检索:子查询并行处理,提升检索效率
查询问题拆解完成后,将各子查询分别输入检索模块执行独立检索,可采用并行处理方式缩短检索耗时。此环节可结合 Advanced RAG 的其他检索优化技术,如为不同领域的子查询配置专属知识库路由(如医疗子查询路由至专业医疗数据库),搭配 RAG-Fusion 或重排序技术进一步提升子查询的检索精度,确保每个子查询都能召回最相关的核心信息。
3. 整合生成:逻辑重组,输出完整答案
获取所有子查询的检索结果与对应应答后,需再次调用 LLM 按原始问题的逻辑需求,将子结果进行重组、归纳与深化,形成逻辑连贯、内容完整的最终答案。整合过程中需注意保留各子查询应答的核心要点,同时消除重复信息,确保答案既全面又简洁,实现 “子查询应答→逻辑整合→完整答案” 的闭环。
四、实战案例:基于 LangChain 1.0.7 的气候 - 农业影响 RAG 系统(Decomposition 技术落地)
以下案例以「气候对农业的影响」为核心场景,基于 LangChain 1.0.7 版本实现完整的查询分解(Decomposition)流程,包含环境搭建、数据准备、拆解逻辑、Pipeline 构建全步骤,代码可直接复制运行,适配复杂农业场景查询需求(如 “分析不同气候因子对小麦产量的影响,及应对干旱的农业技术方案”)。
1.案例背景与核心需求
农业生产中,用户常提出多维度复杂查询,例如:
- “对比高温、降水异常对玉米生长的影响差异,列举华北地区应对策略”
- “分析厄尔尼诺现象对南方水稻种植的影响,包含播种期调整与病虫害防治方案”这类查询需覆盖 “气候因子分类、作物影响机制、区域适配策略” 等多个子需求,Naive RAG 难以精准响应,需通过 Decomposition 技术将用户查询拆解为独立子查询,实现精准检索与逻辑整合。
2. 环境准备与依赖安装
首先安装所需依赖包,指定对应版本确保兼容性:
# 核心依赖(严格锁定LangChain 1.0.7)
uv add langchain==1.0.7 langchain-deepseek langchain-community
# 向量存储与嵌入模型
uv add chromadb==0.4.24
# 数据处理依赖
uv add pandas==2.1.4
3. 数据准备:农业气候影响数据集构建
采用公开农业气候数据 + 自定义结构化数据,包含 3 类核心内容:
- 气候因子(高温、降水、干旱、厄尔尼诺等)对主要作物(小麦、玉米、水稻)的影响机制;
- 不同区域(华北、南方、西北)的气候特征与农业适配策略;
- 应对极端气候的农业技术(灌溉、品种改良、种植模式调整等)。
4. 初始化组件:文档加载与向量存储
加载知识库数据并完成向量嵌入存储,为检索提供基础:
import pandas as pd
from langchain_core.documents import Document
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import DashScopeEmbeddings
# 加载本地农业气候数据集
def load_agri_data(file_path="agri_climate_data.csv"):
df = pd.read_csv(file_path)
# 转换为LangChain Document对象(content为检索核心,meta为辅助信息)
documents = [
Document(
page_content=row["content"],
metadata={"meta_info": row["meta"]}
) for _, row in df.iterrows()
]
return documents
# 初始化嵌入模型
embeddings = embeddings = DashScopeEmbeddings(
model="text-embedding-v4",
dashscope_api_key="请输入你的API KEY")
# 构建向量数据库(本地持久化,下次可直接加载)
documents = load_agri_data()
vector_db = Chroma.from_documents(
documents=documents,
embedding=embeddings,
persist_directory="./agri_climate_chroma_db" # 本地存储路径
)
vector_db.persist()
print(f"向量数据库构建完成,共存储{len(documents)}条农业气候数据")
5. 定义提示词模板:实现结构化查询拆解
设计提示词模板引导 LLM 完成精准拆解,明确拆解原则与输出格式:
from langchain.chat_models import init_chat_model
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
import os
from dotenv import load_dotenv
# 初始化LLM(LangChain 1.0.7适配方式)
llm = model = init_chat_model(model="deepseek-chat", temperature=0.1)
# 定义查询分解提示词模板(明确拆解规则与输出格式)
decomposition_prompt = PromptTemplate(
template="""
你是农业气候领域的查询拆解专家,需将用户的复杂查询拆分为3-5个独立可解的子查询,需满足以下要求:
1. 每个子查询聚焦单一知识点(如“高温对玉米的影响”“南方水稻抗旱技术”),可独立检索获取答案;
2. 所有子查询需完整覆盖原始查询的全部需求,无核心信息遗漏;
3. 按“气候因子→作物影响→区域适配→应对策略”的逻辑顺序排列子查询;
4. 输出格式为纯文本列表,每条子查询前加序号(1. 2. 3. ...),无需额外解释。
原始复杂查询:{original_query}
拆解后的子查询:
""",
input_variables=["original_query"]
)
# 构建查询分解链(LangChain 1.0+ Chain语法)
decomposition_chain = decomposition_prompt | llm | StrOutputParser()
# 测试查询分解效果
original_query = "对比高温和降水异常对华北地区玉米产量的影响差异,列举针对性的田间管理技术方案"
decomposed_queries = decomposition_chain.invoke({"original_query": original_query})
print("拆解后的子查询:")
print(decomposed_queries)
# 输出示例:
# 1. 高温对华北地区玉米产量的影响机制
# 2. 降水异常对华北地区玉米产量的影响机制
# 3. 高温与降水异常对华北玉米产量影响的差异对比
# 4. 应对华北地区玉米高温危害的田间管理技术
# 5. 应对华北地区玉米降水异常的田间管理技术
6. 搭建 Pipeline:完成拆解 - 检索 - 整合全流程
整合拆解、检索、生成组件,构建完整处理流水线:
from langchain_core.runnables import RunnablePassthrough
# 初始化检索器(从向量数据库中检索相关文档)
retriever = vector_db.as_retriever(
search_kwargs={"k": 2} # 每个子查询返回Top2相关文档
)
# 定义子查询检索与应答链(子查询→检索→生成子答案)
def get_sub_answer(sub_query):
# 检索子查询相关文档
retrieved_docs = retriever.invoke(sub_query)
doc_content = "\n".join([doc.page_content for doc in retrieved_docs])
# 生成子查询答案的提示词
sub_answer_prompt = PromptTemplate(
template="""基于以下农业气候数据,简洁准确回答问题:
{context}
问题:{sub_query}
答案(不超过3句话,聚焦核心信息):
""",
input_variables=["context", "sub_query"]
)
# 构建子应答链
sub_answer_chain = sub_answer_prompt | llm | StrOutputParser()
return sub_answer_chain.invoke({"context": doc_content, "sub_query": sub_query})
# 定义最终答案整合链(子答案→逻辑整合)
def integrate_sub_answers(original_query, sub_queries, sub_answers):
# 整合提示词:按原始查询逻辑重组子答案
integrate_prompt = PromptTemplate(
template="""以下是原始问题的子查询及对应答案,请整合为逻辑连贯、结构清晰的完整回答:
原始问题:{original_query}
子查询与答案:
{sub_queries_answers}
整合要求:
1. 按原始问题的逻辑顺序展开,避免子答案堆砌;
2. 突出核心差异与针对性方案,语言符合农业技术场景;
3. 保持专业且易懂,无需额外添加无关信息。
完整回答:
""",
input_variables=["original_query", "sub_queries_answers"]
)
# 格式化子查询与答案
sub_queries_answers = "\n".join([
f"{idx+1}. 子查询:{sub_queries[idx]}\n答案:{sub_answers[idx]}"
for idx in range(len(sub_queries))
])
# 构建整合链
integrate_chain = integrate_prompt | llm | StrOutputParser()
return integrate_chain.invoke({
"original_query": original_query,
"sub_queries_answers": sub_queries_answers
})
# 执行完整流程
def run_decomposition_rag(original_query):
# 步骤1:拆解原始查询
decomposed_str = decomposition_chain.invoke({"original_query": original_query})
sub_queries = [
q.strip() for q in decomposed_str.split("\n")
if q.strip().startswith(("1.", "2.", "3.", "4.", "5."))
]
# 去除序号前缀(如"1. ")
sub_queries = [q.split(". ", 1)[1] for q in sub_queries]
# 步骤2:逐个处理子查询(检索+生成子答案)
sub_answers = [get_sub_answer(q) for q in sub_queries]
print("子查询处理完成,共生成{}个子答案".format(len(sub_answers)))
# 步骤3:整合子答案生成最终结果
final_answer = integrate_sub_answers(original_query, sub_queries, sub_answers)
return final_answer
# 测试完整流程
if __name__ == "__main__":
original_query = "对比高温和降水异常对华北地区玉米产量的影响差异,列举针对性的田间管理技术方案"
final_result = run_decomposition_rag(original_query)
print("\n最终回答:")
print("="*50)
print(final_result)
完整的代码如下:
import pandas as pd
from langchain.chat_models import init_chat_model
from langchain_core.documents import Document
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import DashScopeEmbeddings
# 加载本地农业气候数据集
def load_agri_data(file_path="agri_climate_data.csv"):
df = pd.read_csv(file_path)
# 转换为LangChain Document对象(content为检索核心,meta为辅助信息)
documents = [
Document(
page_content=row["content"],
metadata={"meta_info": row["meta"]}
) for _, row in df.iterrows()
]
return documents
embeddings = DashScopeEmbeddings(
model="text-embedding-v4", dashscope_api_key="请输入你的API KEY"
)
# 构建向量数据库(本地持久化,下次可直接加载)
documents = load_agri_data()
vector_db = Chroma.from_documents(
documents=documents,
embedding=embeddings,
persist_directory="./agri_climate_chroma_db" # 本地存储路径
)
vector_db.persist()
print(f"向量数据库构建完成,共存储{len(documents)}条农业气候数据")
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
import os
from dotenv import load_dotenv
# 初始化LLM(LangChain 1.0.7适配方式)
llm = model = init_chat_model(model="deepseek-chat", temperature=0.1)
# 定义查询分解提示词模板(明确拆解规则与输出格式)
decomposition_prompt = PromptTemplate(
template="""
你是农业气候领域的查询拆解专家,需将用户的复杂查询拆分为3-5个独立可解的子查询,需满足以下要求:
1. 每个子查询聚焦单一知识点(如“高温对玉米的影响”“南方水稻抗旱技术”),可独立检索获取答案;
2. 所有子查询需完整覆盖原始查询的全部需求,无核心信息遗漏;
3. 按“气候因子→作物影响→区域适配→应对策略”的逻辑顺序排列子查询;
4. 输出格式为纯文本列表,每条子查询前加序号(1. 2. 3. ...),无需额外解释。
原始复杂查询:{original_query}
拆解后的子查询:
""",
input_variables=["original_query"]
)
# 构建查询分解链(LangChain 1.0+ Chain语法)
decomposition_chain = decomposition_prompt | llm | StrOutputParser()
# 测试查询分解效果
original_query = "对比高温和降水异常对华北地区玉米产量的影响差异,列举针对性的田间管理技术方案"
decomposed_queries = decomposition_chain.invoke({"original_query": original_query})
print("拆解后的子查询:")
print(decomposed_queries)
# 输出示例:
# 1. 高温对华北地区玉米产量的影响机制
# 2. 降水异常对华北地区玉米产量的影响机制
# 3. 高温与降水异常对华北玉米产量影响的差异对比
# 4. 应对华北地区玉米高温危害的田间管理技术
# 5. 应对华北地区玉米降水异常的田间管理技术
from langchain_core.runnables import RunnablePassthrough
# 初始化检索器(从向量数据库中检索相关文档)
retriever = vector_db.as_retriever(
search_kwargs={"k": 2} # 每个子查询返回Top2相关文档
)
# 定义子查询检索与应答链(子查询→检索→生成子答案)
def get_sub_answer(sub_query):
# 检索子查询相关文档
retrieved_docs = retriever.invoke(sub_query)
doc_content = "\n".join([doc.page_content for doc in retrieved_docs])
# 生成子查询答案的提示词
sub_answer_prompt = PromptTemplate(
template="""基于以下农业气候数据,简洁准确回答问题:
{context}
问题:{sub_query}
答案(不超过3句话,聚焦核心信息):
""",
input_variables=["context", "sub_query"]
)
# 构建子应答链
sub_answer_chain = sub_answer_prompt | llm | StrOutputParser()
return sub_answer_chain.invoke({"context": doc_content, "sub_query": sub_query})
# 定义最终答案整合链(子答案→逻辑整合)
def integrate_sub_answers(original_query, sub_queries, sub_answers):
# 整合提示词:按原始查询逻辑重组子答案
integrate_prompt = PromptTemplate(
template="""以下是原始问题的子查询及对应答案,请整合为逻辑连贯、结构清晰的完整回答:
原始问题:{original_query}
子查询与答案:
{sub_queries_answers}
整合要求:
1. 按原始问题的逻辑顺序展开,避免子答案堆砌;
2. 突出核心差异与针对性方案,语言符合农业技术场景;
3. 保持专业且易懂,无需额外添加无关信息。
完整回答:
""",
input_variables=["original_query", "sub_queries_answers"]
)
# 格式化子查询与答案
sub_queries_answers = "\n".join([
f"{idx + 1}. 子查询:{sub_queries[idx]}\n答案:{sub_answers[idx]}"
for idx in range(len(sub_queries))
])
# 构建整合链
integrate_chain = integrate_prompt | llm | StrOutputParser()
return integrate_chain.invoke({
"original_query": original_query,
"sub_queries_answers": sub_queries_answers
})
# 执行完整流程
def run_decomposition_rag(original_query):
# 步骤1:拆解原始查询
decomposed_str = decomposition_chain.invoke({"original_query": original_query})
sub_queries = [
q.strip() for q in decomposed_str.split("\n")
if q.strip().startswith(("1.", "2.", "3.", "4.", "5."))
]
# 去除序号前缀(如"1. ")
sub_queries = [q.split(". ", 1)[1] for q in sub_queries]
# 步骤2:逐个处理子查询(检索+生成子答案)
sub_answers = [get_sub_answer(q) for q in sub_queries]
print("子查询处理完成,共生成{}个子答案".format(len(sub_answers)))
# 步骤3:整合子答案生成最终结果
final_answer = integrate_sub_answers(original_query, sub_queries, sub_answers)
return final_answer
# 测试完整流程
if __name__ == "__main__":
original_query = "对比高温和降水异常对华北地区玉米产量的影响差异,列举针对性的田间管理技术方案"
final_result = run_decomposition_rag(original_query)
print("\n最终回答:")
print("=" * 50)
print(final_result)
运行效果如下所示:



通过上述流程,即可实现复杂查询的拆解、精准检索与整合生成,最终输出逻辑清晰、内容完整的答案,直观展现提示词分解技术在实际场景中的应用效果。
五、技术优势与应用边界:理性看待查询分解的价值
1. 核心优势:适配 Advanced RAG 的精准优化需求
- 检索精度显著提升:拆解后的子查询聚焦单一需求,可过滤 70% 以上的无关检索信息,大幅降低召回偏差;
- 生成逻辑更连贯:按逻辑拆解的子结果为答案提供清晰框架,避免生成内容碎片化,提升答案可读性与说服力;
- 适配复杂场景:完美支撑多维度推理、长文档检索、多源知识库查询等 Advanced RAG 核心应用场景,拓展 RAG 技术的落地边界。
2. 应用边界:明确适用场景与局限
- 适用场景:侧重需要多步骤推理的复杂查询场景,如行业方案对比、领域难点分析、多维度知识汇总等,典型落地场景包括医疗诊断辅助、法律条款解读、企业级知识库问答、在线教育复杂知识点答疑等;
- 局限说明:对于简单查询(如 “RAG 的核心流程是什么”)无需拆解,反而会增加流程复杂度;同时依赖 LLM 的拆解能力,若 LLM 逻辑推理不足,可能出现子查询遗漏或拆分不合理的情况,需搭配优质提示词模板或结构化输出工具优化。
六、总结:查询分解 ——Advanced RAG 的复杂查询破解密钥
在 RAG 技术从基础版向 Advanced 版升级的过程中,查询分解技术以 “逻辑解构” 为核心,通过将复杂查询转化为精准子任务,打通了 “用户意图 - 精准检索 - 逻辑生成” 的关键链路,有效解决了Naive RAG 检索模糊、推理不足、信息过载等核心痛点。其本质是借助 LLM 的推理能力赋能检索环节,让 RAG 系统不仅能 “找得到信息”,更能 “理得清逻辑”,为复杂场景下的 RAG 落地提供了关键支撑。
随着 RAG 技术向模块化、智能化演进,查询分解技术也将与查询路由、重排序、上下文蒸馏等技术深度融合,进一步提升复杂问题的处理能力。对于开发者而言,掌握查询分解的实现逻辑与落地技巧,既是 Advanced RAG 技术实践的核心要点,也是提升 RAG 系统实用价值的关键方向,助力在各行业复杂场景中实现更优质的检索增强生成效果。
那么,如何系统的去学习大模型LLM?
作为一名深耕行业的资深大模型算法工程师,我经常会收到一些评论和私信,我是小白,学习大模型该从哪里入手呢?我自学没有方向怎么办?这个地方我不会啊。如果你也有类似的经历,一定要继续看下去!这些问题啊,也不是三言两语啊就能讲明白的。
所以我综合了大模型的所有知识点,给大家带来一套全网最全最细的大模型零基础教程。在做这套教程之前呢,我就曾放空大脑,以一个大模型小白的角度去重新解析它,采用基础知识和实战项目相结合的教学方式,历时3个月,终于完成了这样的课程,让你真正体会到什么是每一秒都在疯狂输出知识点。
由于篇幅有限,⚡️ 朋友们如果有需要全套 《2025全新制作的大模型全套资料》,扫码获取~
👉大模型学习指南+路线汇总👈
我们这套大模型资料呢,会从基础篇、进阶篇和项目实战篇等三大方面来讲解。

👉①.基础篇👈
基础篇里面包括了Python快速入门、AI开发环境搭建及提示词工程,带你学习大模型核心原理、prompt使用技巧、Transformer架构和预训练、SFT、RLHF等一些基础概念,用最易懂的方式带你入门大模型。
👉②.进阶篇👈
接下来是进阶篇,你将掌握RAG、Agent、Langchain、大模型微调和私有化部署,学习如何构建外挂知识库并和自己的企业相结合,学习如何使用langchain框架提高开发效率和代码质量、学习如何选择合适的基座模型并进行数据集的收集预处理以及具体的模型微调等等。
👉③.实战篇👈
实战篇会手把手带着大家练习企业级的落地项目(已脱敏),比如RAG医疗问答系统、Agent智能电商客服系统、数字人项目实战、教育行业智能助教等等,从而帮助大家更好的应对大模型时代的挑战。
👉④.福利篇👈
最后呢,会给大家一个小福利,课程视频中的所有素材,有搭建AI开发环境资料包,还有学习计划表,几十上百G素材、电子书和课件等等,只要你能想到的素材,我这里几乎都有。我已经全部上传到CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
相信我,这套大模型系统教程将会是全网最齐全 最易懂的小白专用课!!
更多推荐



所有评论(0)