大模型应用开发中的高级 RAG 技术
最近一直在探索 RAG 相关的技术,并且分析了 langchain 和 llamaindex 相关技术实现,现在总结和分享一些自己的经验。
RAG 前沿进展
我们借助下面论文中的截图,来说明目前 RAG 技术的进展。
Retrieval-Augmented Generation for Large Language Models: A Survey

除了在用户的输入 query 上做文章外,还有更多的操作是进行后处理,比如多路召回和重排序。而且最新的技术也增加了很多新模块,比如 self-RAG 这篇文章就引入了自我性,通过训练一个新的 LLM 去自适应地按需检索段落,并生成和反映检索到的段落和它自己的生成结果。但这个方法的流程太长,是否适合线上的实际环境,需要真实场景的验证。
从 langchain 以及 llama 的实现,以及论文中提及到内容,这次分享 RAG 的高阶技术分为了三个大模块:
一个是Query Transformation,也就是针对用户 query 的相关操作; 第二个是Agent技术,本质上利用大模型的能力去调用函数来实现更复杂的功能; 第三个是Post-process 也就是后处理,在我们检索到上下文之后,可以使用一些后处理的方法去对数据进行处理,以便得到更优质的上下文信息。
像重排序、多路召回技术这些都比较常见了,就不再做过多的阐述。
Query Transformation
query transformation 主要就是利用各种技巧和大模型的能力,去对用户的 query 进行改写,转换等操作,丰富 query 的语义信息。
Query Rewrite
因为对于 LLM 而言,原始查询不可能总是最佳检索,尤其是在现实世界中,我们首先提示 LLM 重写查询,然后进行检索增强阅读。这个技术可以参考下面 langchain 中的示例,本质还是使用了提示词工程,去编写改写的提示词,这部分提示词也是可以优化的地方。
template = """Provide a better search query for \
web search engine to answer the given question, end \
the queries with '**'. Question: \
{x} Answer:"""
rewrite_prompt = ChatPromptTemplate.from_template(template)
def _parse(text):
return text.strip("**")
distracted_query = "man that sam bankman fried trial was crazy! what is langchain?"
rewriter = rewrite_prompt | ChatOpenAI(temperature=0) | StrOutputParser() | _parse
rewriter.invoke({"x": distracted_query})
MultiQuery
本质上是 query rewrite 的改进版,可以同时生成 n 个和用户 query 相似的 query,然后同时进行检索,这样能确保召回的内容尽可能的符合原始 query。具体可以参考下面的代码,需要 langchian 的最新版本。
from langchain.retrievers.multi_query MultiQueryRetriever
langchain_openai ChatOpenAI
question =
llm = ChatOpenAI(temperature=)
retriever_from_llm = MultiQueryRetriever.from_llm(
retriever=vectordb.as_retriever(), llm=llm
)



