你好,我是方可乐。
一个正在深耕AI编程的30+的AI应用开发工程师。
用AI编程开发过Web应用网站,浏览器插件,微信小程序,AI智能体,RAG系统。
关注公众号&添加微信:ThinkFun666
领取【AI编程资料包】
去年6月份,我做了一个连自己都觉得疯狂的决定:裸辞,All in AI。
现在已经换赛道成功,继续在工作中探索。
在上一课,我分享了如何把公司规章制度放进知识库,跑通了一个最小可用的 RAG 系统。
爱动脑子的同学,应该会开始想一些比较实际的问题了:
如果我有一份 100 页的 PDF,公司所有规章制度都在里面,是不是直接丢给 embedding 就行?
答案是:不行。
这么长的东西必须先切分,不然向量模型扛不住。
为什么要切分?
切分是 RAG 的第一步,主要原因有三个:
-
1. 向量模型有 token 长度限制 比如 OpenAI 的 text-embedding-3-small最多支持 8192 tokens,太长直接丢进去就不行,当场报错给你看。 -
2. 提高检索精度 用户问“请假规定”,我们希望检索出“请假需提前 3 天申请”,而不是整整一页“考勤制度+请假制度”的混合内容。 -
3. 减少大模型负担 检索出来的块更小、更干净,传给 LLM 的上下文更专注,答案自然也更可靠。
所以切分是效果好坏的关键因素。
LangChain 的切分方式与应用场景
LangChain 内置了多种切分器,不同文档类型用法不一样,具体场景用到的适合,可以拿这个表参考下怎么做选型:
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
案例
老规矩,上代码,新建文件14_rag_split_context.py
这节课的举例,用 10 条规章制度来演示几种常见切分:
from langchain.schema import Document
from langchain.text_splitter import (
CharacterTextSplitter,
RecursiveCharacterTextSplitter,
TokenTextSplitter,
MarkdownHeaderTextSplitter
)
# 模拟规章制度文档
raw_text = """
# 公司规章制度
## 考勤制度
1. 员工必须每天打卡。
2. 上班期间禁止使用私人手机。
## 请假制度
3. 员工请假需提前 3 天申请。
4. 公司提供每年 10 天带薪年假。
## 行为规范
5. 办公室内禁止吸烟。
6. 员工需遵守信息安全规范。
## 培训制度
7. 员工每季度需完成一次培训课程。
"""
doc = Document(page_content=raw_text, metadata={"source": "company_policy"})
# 1. 固定长度切分
char_splitter = CharacterTextSplitter(chunk_size=50, chunk_overlap=0)
docs_char = char_splitter.split_documents([doc])
# 2. 递归切分
rec_splitter = RecursiveCharacterTextSplitter(chunk_size=50, chunk_overlap=0)
docs_rec = rec_splitter.split_documents([doc])
# 3. Token 切分
tok_splitter = TokenTextSplitter(chunk_size=30, chunk_overlap=10)
docs_tok = tok_splitter.split_documents([doc])
# 4. Markdown 层级切分
headers_to_split_on = [("#", "header1"), ("##", "header2")]
md_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
docs_md = md_splitter.split_text(raw_text)
print("\n=== 固定长度切分 ===")
for d in docs_char:
print(d.page_content)
print("\n=== 递归切分 ===")
for d in docs_rec:
print(d.page_content)
print("\n=== Token 切分 ===")
for d in docs_tok:
print(d.page_content)
print("\n=== Markdown 层级切分 ===")
for d in docs_md:
print(d.page_content, d.metadata)
下面看看运行效果:
在具体的业务中,很难有一个切分策略能够覆盖所有的文档,更多的是见招拆招,灵活切换。
对AI应用开发感兴趣的同学,欢迎加微信申请入群交流学习。
想要学习AI应用开发的同学,可以参照我的代码跑起来,举一反三,一天一个脚印的进步,我相信,会足够坚实。
接下来100天,我会记录从Java程序员到AI应用开发工程师的完整转型路:每一个困惑、每一次突破、每一个真实瞬间。
当前是32/100。
如果你也想了解AI应用开发到底是什么,如果你也在考虑转型但还在犹豫,那就跟着我的记录,一起探索。
继续折腾中,有问题随时交流 🤝
微信号:ThinkFun666
我的免费AI编程交流群,欢迎加入讨论AI编程玩法(说明需求和来意,申请入群)
推荐阅读:
我就喜欢干这种傻事!为什么转型AI应用开发,我不建议你直接从看书开始学起?

