大家好,我是你们的AI技术侃侃而谈小能手。今天我们来聊聊RAG(Retrieval-Augmented Generation)这个AI圈的“记忆力补脑丸”,以及它最近新晋的“脑白金”——Contextual Chunk Headers(CCH)。别眨眼,这可是让大模型“查资料”能力质变的秘密武器!
先来个小科普。RAG是什么?简单说,就是给大模型加个“外挂”,让它在回答问题前,先去知识库里“翻翻书”,查查资料,然后再作答。这样一来,模型的“胡说八道”概率大大降低,事实准确率蹭蹭上涨。
但!理想很丰满,现实很骨感。RAG的“检索”环节,常常因为“切块”方式太粗暴,把上下文割裂得七零八落,导致模型检索到的内容“前言不搭后语”,答非所问。你问“Explainable AI是什么”,它给你扔来一段“AI历史发展”,你说气不气?
于是,Contextual Chunk Headers(CCH)横空出世。它的核心思想很简单:每个知识块(chunk)前面都加个“高大上”的标题(header),比如“第3章:AI的可解释性”,或者“隐私保护与AI伦理”。这样,检索时不仅看内容,还能看标题,检索的相关性和准确率直接起飞!
想象一下,你去图书馆找资料,是不是先看目录?CCH就是给每个知识块都加了个“迷你目录”,让大模型检索时不再“瞎蒙”,而是“有的放矢”。
说了这么多,咱们来点硬货,手把手带你撸一遍CCH的完整流程。别担心,代码有,原理讲,细节全,风趣不掉线!
首先,我们得有“知识库”。假设你有一份AI相关的PDF文档(比如《AI信息宝典》),我们要把它的内容抽出来。
import fitz # PyMuPDF
def extract_text_from_pdf(pdf_path):
mypdf = fitz.open(pdf_path)
all_text = ""
for page_num in range(mypdf.page_count):
page = mypdf[page_num]
text = page.get_text("text")
all_text += text
return all_text
是不是很简单?一行一页,文本全到手。
传统RAG切块,直接按字数分段,像切香肠一样。CCH则是“切香肠+贴标签”——每块内容前面都要有个“上下文头衔”。
你说,手动给每块写标题?累死谁啊!当然要用大模型自动生成:
def generate_chunk_header(chunk, model="meta-llama/Llama-3.2-3B-Instruct"):
system_prompt = "Generate a concise and informative title for the given text."
response = client.chat.completions.create(
model=model,
temperature=0,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": chunk}
]
)
return response.choices[0].message.content.strip()
def chunk_text_with_headers(text, n, overlap):
chunks = []
for i in range(0, len(text), n - overlap):
chunk = text[i:i + n]
header = generate_chunk_header(chunk)
chunks.append({"header": header, "text": chunk})
return chunks
举个栗子:
Header: "AI的起源与发展"
Content: "人工智能(AI)是指……"
每块内容都带着“身份证”,检索时一目了然。
有了“头衔”的知识块,下一步就是“向量化”——把文本和标题都变成“数字向量”,方便后续用“余弦相似度”来检索。
def create_embeddings(text, model="BAAI/bge-en-icl"):
response = client.embeddings.create(
model=model,
input=text
)
return response.data[0].embedding
每个chunk的正文和header都要各自生成embedding,后面检索时“双保险”。
用户一发问,先把问题也向量化,然后和所有知识块的正文、标题分别算相似度,最后取平均,选出最相关的Top-K块。
def cosine_similarity(vec1, vec2):
return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
def semantic_search(query, chunks, k=5):
query_embedding = create_embeddings(query)
similarities = []
for chunk in chunks:
sim_text = cosine_similarity(np.array(query_embedding), np.array(chunk["embedding"]))
sim_header = cosine_similarity(np.array(query_embedding), np.array(chunk["header_embedding"]))
avg_similarity = (sim_text + sim_header) / 2
similarities.append((chunk, avg_similarity))
similarities.sort(key=lambda x: x[1], reverse=True)
return [x[0] for x in similarities[:k]]
这样,检索结果不再“牛头不对马嘴”,而是“对症下药”。
检索到相关知识块后,把它们拼成上下文,丢给大模型生成回答。但要“约法三章”:
只许根据检索到的内容作答
没查到就老实说“我不知道”
system_prompt = "你是一个AI助手,只能根据给定上下文回答。如果无法直接从上下文得出答案,请回复:'我没有足够的信息回答。'"
def generate_response(system_prompt, user_message, model="meta-llama/Llama-3.2-3B-Instruct"):
response = client.chat.completions.create(
model=model,
temperature=0,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message}
]
)
return response
用户问:“Explainable AI是什么?为什么重要?”
检索到的chunk header和内容如下:
Header: "AI的可解释性与信任构建"
Content: "Explainable AI(XAI)技术旨在让AI决策过程更透明……"
大模型就能“有理有据”地回答,而不是“信口开河”。
最后,怎么知道AI答得好不好?当然是让AI自己“阅卷”!
evaluate_system_prompt = """你是一个智能评测系统。
根据上下文评估AI助手的回答:
- 非常接近标准答案,得1分
- 部分正确,得0.5分
- 错误,得0分
只返回分数(0, 0.5, 1)。"""
def evaluate_response(query, ai_response, true_answer):
evaluation_prompt = f"""
用户问题: {query}
AI回答: {ai_response}
标准答案: {true_answer}
{evaluate_system_prompt}
"""
evaluation_response = generate_response(evaluate_system_prompt, evaluation_prompt)
return evaluation_response.choices[0].message.content
这样,整个RAG+ CCH流程就闭环了:
数据进->切块加头衔->向量化->检索->生成->评测,一条龙服务!
你可能会问:CCH到底有多大用?
实测下来,CCH能显著提升检索的相关性和准确率。尤其是面对结构化文档、长文档、章节分明的资料时,CCH让模型“找对书、翻对页、答对题”,极大减少“答非所问”的尴尬。
举个生活中的例子:
没有CCH,像是你去图书馆找“AI伦理”,结果翻到“AI历史”,一脸懵逼。
有了CCH,直接定位到“第20章:AI伦理与信任”,效率爆表!
标题生成要简明扼要:别让LLM写成“800字小作文”,标题越精炼越好。
chunk大小和overlap要调优:太小丢上下文,太大检索慢,overlap能防止“断章取义”。
header和正文embedding都要用:双保险,相关性更高。
评测要自动化:用AI评AI,省时省力,闭环迭代。
CCH让RAG如虎添翼,未来还有更多玩法:
多级header:不仅有章节标题,还能有小节、小小节,层层递进。
多模态header:图片、表格也能加“头衔”,检索更丰富。
动态header生成:根据用户query动态调整header粒度,检索更智能。
RAG+ CCH的组合,正在让大模型的“知识检索”能力越来越像人类。未来,AI助手不再是“张口就来”的段子手,而是“有理有据”的百科全书。
如果你也想让自己的RAG系统“脑洞大开”,不妨试试CCH这剂“脑白金”!
最后,欢迎留言讨论:你觉得CCH还有哪些创新玩法?你在RAG落地中遇到过哪些“神坑”?
关注我,带你玩转AI最前沿,技术干货、实战经验、行业八卦,一网打尽!