从零搭一个AI搜索:原理、架构到可运行源码全讲透
AI搜索 新手入门指南|附源码
在过去很长一段时间里,我们习惯使用传统搜索引擎来获取信息:输入关键词,打开多个网页,对比内容,最后自己总结答案。但随着大语言模型、向量数据库、语义检索等技术的发展,“AI搜索”正在成为一种更高效的信息获取方式。
AI搜索并不是简单地把搜索框换成聊天框,它的核心变化在于:系统不再只按照关键词匹配网页,而是能够理解用户问题的语义,检索相关资料,并结合大模型生成更自然、更直接、更有上下文的回答。
本文将从新手角度出发,系统介绍AI搜索的基本概念、核心原理、技术架构、应用场景,并提供一个可运行的简化版AI搜索源码示例,帮助你快速入门。
一、什么是AI搜索?
AI搜索,通常指结合人工智能能力的新一代搜索系统。它可以理解用户的自然语言问题,从海量数据中找到相关信息,并通过大语言模型生成结构化、可读性强的答案。
传统搜索更像是“找网页”,而AI搜索更像是“找答案”。
举个例子:
如果你在传统搜索引擎中输入:
如何提高Python代码运行速度?
搜索引擎通常会返回一批网页链接,你需要逐个点进去阅读。
而AI搜索可能会直接回答:
提高Python代码运行速度可以从算法优化、数据结构选择、使用内置函数、减少循环、使用NumPy、使用缓存、并行计算等方面入手。对于计算密集型任务,可以考虑Cython或Rust扩展;对于IO密集型任务,可以使用异步编程。
这就是AI搜索带来的体验变化。
二、AI搜索和传统搜索有什么区别?
AI搜索并不是完全取代传统搜索,而是在传统搜索基础上加入了语义理解、内容总结和智能问答能力。
| 对比维度 | 传统搜索 | AI搜索 |
|---|---|---|
| 输入方式 | 关键词为主 | 自然语言问题 |
| 检索方式 | 关键词匹配、倒排索引 | 关键词检索 + 语义向量检索 |
| 输出结果 | 网页链接列表 | 直接答案 + 引用来源 |
| 用户成本 | 需要自己筛选和总结 | 系统帮助总结 |
| 上下文理解 | 较弱 | 较强 |
| 适用场景 | 查找网页、导航、资讯 | 问答、知识库、资料总结、企业搜索 |
例如,用户输入:
帮我总结一下公司请假制度里年假的规定
传统搜索通常只能根据“公司 请假制度 年假”这些关键词查找相关文档。
AI搜索则可以理解用户真正想要的是“从制度文档中提取年假规则并总结”,因此可以返回更加精准的结果。
三、AI搜索的核心原理
一个典型的AI搜索系统,通常包含以下几个关键步骤:
- 数据采集
- 文档切分
- 向量化
- 向量存储
- 用户问题向量化
- 相似度检索
- 大模型生成回答
- 返回答案与引用来源
下面逐步解释。
四、数据采集:AI搜索的基础
AI搜索首先需要有数据来源。数据可以来自:
- 网页内容
- PDF文档
- Word文档
- Markdown文档
- 数据库
- 企业内部知识库
- FAQ问答
- 产品说明书
- 技术文档
- 客服对话记录
对于企业内部AI搜索来说,数据质量非常重要。如果原始文档混乱、重复、过期,即使后续模型很强,也很难得到可靠答案。
常见的数据处理工作包括:
- 去除HTML标签
- 删除重复内容
- 清洗乱码
- 保留标题层级
- 提取正文
- 删除广告、导航、页脚
- 标记文档来源
- 记录更新时间
AI搜索不是魔法,它的效果很大程度取决于数据质量。
五、文档切分:为什么要把长文档切成小块?
大语言模型通常有上下文长度限制,向量检索也不适合直接处理非常长的文档。因此,在构建AI搜索系统时,我们通常需要把长文档切分成多个较小的文本片段。
例如,一篇50000字的产品手册可以切成若干段,每段500到1000字。
常见切分方式包括:
1. 固定长度切分
按照固定字符数或Token数切分,例如每段800字。
优点是实现简单,缺点是可能把一个完整语义切断。
2. 按标题切分
根据Markdown标题、HTML标题或Word标题进行切分。
优点是语义较完整,适合技术文档、产品说明书、制度文档。
3. 按段落切分
根据自然段落分割,再合并成适当长度。
这种方式比较常用,能够在语义完整和长度控制之间取得平衡。
4. 滑动窗口切分
切分时保留一部分重叠内容。例如每段800字,相邻两段重叠100字。
这样可以减少信息断裂带来的检索失败。
六、向量化:让机器理解语义
AI搜索的关键技术之一是“向量化”。
所谓向量化,就是把文本转换成一组数字。例如:
“如何申请年假?” -> [0.12, -0.35, 0.88, ...]
“年假申请流程是什么?” -> [0.10, -0.31, 0.86, ...]
如果两个句子的语义相近,它们对应的向量在空间中的距离也会比较近。
这就是语义搜索的基础。
传统关键词搜索可能认为“申请年假”和“休带薪假流程”差别较大,因为关键词不完全一致。但向量检索可以判断它们语义接近,因此能够找到相关内容。
常见的向量模型包括:
- OpenAI Embeddings
- text-embedding模型
- BGE系列模型
- E5系列模型
- sentence-transformers
- 各类国产Embedding模型
七、向量数据库:存储和检索语义信息
文本向量生成后,需要存储起来,并支持快速相似度搜索。这时就需要向量数据库。
常见向量数据库包括:
- FAISS
- Milvus
- Chroma
- Weaviate
- Qdrant
- Elasticsearch Vector Search
- PostgreSQL pgvector
如果是学习和小型项目,可以使用FAISS或Chroma。如果是企业级服务,可以考虑Milvus、Qdrant或Elasticsearch。
向量数据库通常会保存两类信息:
- 文本向量
- 文本元数据
元数据包括:
- 文档ID
- 文档标题
- 文档来源
- 原文片段
- 创建时间
- 更新时间
- 权限信息
AI搜索返回答案时,通常还会展示引用来源,这就依赖于元数据。
八、RAG:AI搜索最常见的技术架构
AI搜索中非常重要的一个概念是RAG。
RAG的全称是:
Retrieval-Augmented Generation
检索增强生成
它的核心思想是:先检索,再生成。
也就是说,大模型不是完全依赖自身记忆回答问题,而是先从知识库中检索相关内容,再基于检索结果生成答案。
RAG流程如下:
用户问题
↓
问题向量化
↓
向量数据库检索相关文档片段
↓
把问题和检索片段一起交给大模型
↓
大模型生成答案
↓
返回答案和引用来源
RAG的优势很明显:
- 可以接入私有知识库
- 可以减少模型幻觉
- 可以更新知识,无需重新训练模型
- 可以提供引用来源
- 成本低于微调模型
- 适合企业落地
例如,企业内部AI搜索系统可以把员工手册、报销制度、产品文档、客服知识库全部接入RAG系统,员工只需要用自然语言提问即可获得答案。
九、AI搜索的常见应用场景
1. 企业知识库搜索
员工可以直接提问:
出差住宿标准是多少?
系统从公司制度文档中检索相关条款,并生成简洁答案。
2. 技术文档问答
开发者可以提问:
这个SDK如何配置鉴权?
AI搜索可以从API文档中找到鉴权章节,并总结配置步骤。
3. 客服智能问答
用户提问:
订单退款多久到账?
系统从售后政策和订单规则中检索答案,辅助客服或直接回复用户。
4. 法律法规检索
律师或合规人员可以提问:
劳动合同解除需要提前多久通知?
AI搜索可以从法律法规文本中检索相关条款并给出引用。
5. 学术论文搜索
研究人员可以提问:
最近有哪些关于多模态大模型评测的研究?
系统可以检索论文摘要,并总结研究方向。
6. 个人资料库助手
你可以把自己的笔记、PDF、网页收藏、读书摘录放进知识库,然后通过AI搜索快速查询。
十、一个最小可用的AI搜索系统需要什么?
新手入门时,不建议一开始就搭建复杂系统。你可以先实现一个最小版本,包含以下功能:
- 读取本地文档
- 文档切分
- 文本向量化
- 向量检索
- 根据检索结果生成回答
为了降低上手难度,下面提供一个基于Python的简化版AI搜索示例。
技术选型:
- Python
- sentence-transformers:生成文本向量
- FAISS:向量检索
- OpenAI兼容接口:生成回答
你也可以把大模型接口替换为其他兼容服务。
十一、项目结构
建议项目结构如下:
ai-search-demo/
├── data/
│ └── knowledge.txt
├── index.faiss
├── chunks.json
├── build_index.py
├── search.py
├── requirements.txt
└── README.md
其中:
data/knowledge.txt:你的知识库文本build_index.py:构建向量索引search.py:执行AI搜索index.faiss:保存的FAISS索引chunks.json:保存文本片段requirements.txt:依赖文件
十二、安装依赖
创建 requirements.txt:
faiss-cpu==1.8.0
sentence-transformers==3.0.1
numpy==1.26.4
openai==1.35.10
安装依赖:
pip install -r requirements.txt
如果你使用的是Apple Silicon芯片或某些特殊环境,FAISS安装可能会遇到问题,可以改用Chroma或Qdrant。
十三、准备知识库文件
创建文件:
data/knowledge.txt
示例内容:
公司年假制度:
员工连续工作满一年后,可以享受带薪年假。累计工作已满1年不满10年的,年休假5天;已满10年不满20年的,年休假10天;已满20年的,年休假15天。员工申请年假需要提前三天在系统中提交申请,并经过直属主管审批。
公司报销制度:
员工因公出差产生的交通费、住宿费和餐饮补贴,可以按照公司规定进行报销。报销时需要上传正规发票,并填写费用说明。单笔超过5000元的报销需要部门负责人和财务负责人共同审批。
远程办公制度:
员工每周最多可以申请两天远程办公。申请远程办公需要提前一天提交申请,并确保工作时间在线。涉及保密项目的员工,需要经过项目负责人额外审批。
真实项目中,你可以把多个文档合并,或者分别读取多个文件。
十四、源码一:构建向量索引
创建 build_index.py:
import os
import json
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
DATA_PATH = "data/knowledge.txt"
INDEX_PATH = "index.faiss"
CHUNKS_PATH = "chunks.json"
MODEL_NAME = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
def read_text(file_path: str) -> str:
"""读取文本文件"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"文件不存在: {file_path}")
with open(file_path, "r", encoding="utf-8") as f:
return f.read()
def split_text(text: str, chunk_size: int = 300, overlap: int = 50):
"""
简单滑动窗口切分文本。
参数:
- chunk_size: 每个文本块最大字符数
- overlap: 相邻文本块重叠字符数
"""
text = text.replace("\r\n", "\n").strip()
chunks = []
start = 0
while start < len(text):
end = start + chunk_size
chunk = text[start:end].strip()
if chunk:
chunks.append(chunk)
start = end - overlap
if start < 0:
start = 0
if start >= len(text):
break
return chunks
def build_index():
print("正在读取知识库...")
text = read_text(DATA_PATH)
print("正在切分文档...")
chunks = split_text(text)
print(f"文本块数量: {len(chunks)}")
print("正在加载向量模型...")
model = SentenceTransformer(MODEL_NAME)
print("正在生成文本向量...")
embeddings = model.encode(
chunks,
convert_to_numpy=True,
normalize_embeddings=True
)
embeddings = embeddings.astype("float32")
dimension = embeddings.shape[1]
print(f"向量维度: {dimension}")
print("正在构建FAISS索引...")
index = faiss.IndexFlatIP(dimension)
index.add(embeddings)
print("正在保存索引...")
faiss.write_index(index, INDEX_PATH)
with open(CHUNKS_PATH, "w", encoding="utf-8") as f:
json.dump(chunks, f, ensure_ascii=False, indent=2)
print("索引构建完成!")
if __name__ == "__main__":
build_index()
运行:
python build_index.py
运行完成后,你会看到生成:
index.faiss
chunks.json
十五、源码二:执行AI搜索
创建 search.py:
import json
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
from openai import OpenAI
INDEX_PATH = "index.faiss"
CHUNKS_PATH = "chunks.json"
MODEL_NAME = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
# 如果你使用OpenAI官方接口,base_url可以不填
# 如果你使用兼容OpenAI格式的模型服务,可以配置base_url
client = OpenAI(
api_key="你的API_KEY",
# base_url="https://你的模型服务地址/v1"
)
def load_chunks():
with open(CHUNKS_PATH, "r", encoding="utf-8") as f:
return json.load(f)
def retrieve(query: str, top_k: int = 3):
"""从向量库中检索与问题最相关的文本块"""
chunks = load_chunks()
index = faiss.read_index(INDEX_PATH)
model = SentenceTransformer(MODEL_NAME)
query_embedding = model.encode(
[query],
convert_to_numpy=True,
normalize_embeddings=True
).astype("float32")
scores, indices = index.search(query_embedding, top_k)
results = []
for score, idx in zip(scores[0], indices[0]):
if idx == -1:
continue
results.append({
"score": float(score),
"content": chunks[idx]
})
return results
def build_prompt(query: str, contexts):
"""构造提示词,让大模型基于检索内容回答"""
context_text = "\n\n".join(
[f"资料{i + 1}:\n{item['content']}" for i, item in enumerate(contexts)]
)
prompt = f"""
你是一个严谨的AI搜索助手。请根据下面提供的资料回答用户问题。
要求:
1. 只能根据资料内容回答,不要编造。
2. 如果资料中没有答案,请明确说明“资料中没有找到相关信息”。
3. 回答要简洁、准确、有条理。
4. 如有必要,可以用列表形式回答。
用户问题:
{query}
参考资料:
{context_text}
请给出答案:
"""
return prompt
def generate_answer(query: str, contexts):
prompt = build_prompt(query, contexts)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "你是一个专业、可靠的企业知识库问答助手。"
},
{
"role": "user",
"content": prompt
}
],
temperature=0.2
)
return response.choices[0].message.content
def ai_search(query: str):
contexts = retrieve(query)
print("\n检索到的相关资料:")
for i, item in enumerate(contexts):
print(f"\n[{i + 1}] 相似度:{item['score']:.4f}")
print(item["content"])
answer = generate_answer(query, contexts)
print("\nAI回答:")
print(answer)
if __name__ == "__main__":
while True:
query = input("\n请输入你的问题,输入exit退出:")
if query.lower() in ["exit", "quit"]:
break
ai_search(query)
运行:
python search.py
输入问题:
年假需要提前多久申请?
可能得到回答:
根据资料,员工申请年假需要提前三天在系统中提交申请,并经过直属主管审批。
十六、代码说明
上面的代码实现了一个非常基础的RAG版AI搜索系统。
1. 构建索引阶段
build_index.py负责:
- 读取知识库文本
- 把文本切成多个chunk
- 使用Embedding模型生成向量
- 把向量写入FAISS索引
- 把原始文本块保存为JSON
这一步一般不需要每次用户搜索时都执行,只需要在文档更新时重新构建或增量更新索引。
2. 查询阶段
search.py负责:
- 接收用户问题
- 把问题转换成向量
- 在FAISS中查找最相近的文本块
- 把检索结果和问题一起发送给大模型
- 输出最终答案
这就是最基本的AI搜索流程。
十七、为什么要让大模型基于资料回答?
如果直接把问题交给大模型,模型可能会根据训练数据回答,但它不一定知道你的私有文档内容,也可能产生幻觉。
例如你问:
公司远程办公每周最多几天?
如果模型没有你的公司制度,它只能猜测。
但RAG会先检索公司制度中的相关内容,再让模型基于资料回答:
员工每周最多可以申请两天远程办公。
这样答案更加可靠,也更适合企业场景。
十八、新手常见问题
1. 为什么检索结果不准确?
可能原因包括:
- 文档切分太大或太小
- 向量模型效果不好
- 查询问题过于模糊
- 知识库内容质量差
- 文档中缺少相关答案
- top_k设置不合理
- 没有结合关键词检索
解决方法:
- 优化切分策略
- 更换更强的Embedding模型
- 增加关键词召回
- 使用重排序模型
- 清洗知识库
- 给文档添加标题和元数据
2. 为什么AI会胡编?
可能原因包括:
- Prompt约束不够
- 检索内容不相关
- 大模型温度过高
- 没有要求模型只基于资料回答
- 问题超出知识库范围
解决方法:
- 降低temperature
- 在Prompt中明确要求“不知道就说不知道”
- 展示引用来源
- 对检索结果设置相似度阈值
- 使用更可靠的大模型
3. 是否必须使用向量数据库?
不一定。
如果数据量很小,可以直接在内存中计算相似度。但当数据达到数万、数百万文本块时,就需要FAISS、Milvus、Qdrant等向量数据库来提升检索效率。
4. AI搜索需要微调模型吗?
大多数场景不需要。
RAG通常比微调更适合知识库问答,因为知识经常变化。微调更适合改变模型风格、格式或特定任务能力,而不是注入大量动态知识。
十九、如何进一步优化AI搜索?
当你完成最小版本后,可以继续优化以下方向。
1. 混合检索
单纯向量检索有时会漏掉关键词非常关键的问题。例如产品型号、错误码、订单号、法规条款编号等,更适合关键词检索。
因此可以结合:
- BM25关键词检索
- 向量语义检索
然后合并结果。
这就是混合检索。
2. 重排序
第一阶段检索通常追求召回率,可能会返回一些不够精准的内容。重排序模型可以对候选文档重新打分,把最相关的内容排到前面。
常见流程:
用户问题
↓
召回Top 20
↓
重排序模型重新排序
↓
取Top 3给大模型
3. 增加引用来源
优秀的AI搜索系统不仅要给答案,还要告诉用户答案来自哪里。
例如:
答案:员工申请年假需要提前三天提交申请。
引用来源:
- 《公司年假制度》第1段
这样可以提高可信度,也方便用户核验。
4. 权限控制
企业知识库中,不同员工能查看的文档可能不同。
例如:
- 普通员工不能查看财务敏感数据
- 销售不能查看研发内部设计文档
- 外包人员不能查看客户合同
因此AI搜索需要在检索阶段加入权限过滤,不能只在前端隐藏结果。
5. 文档更新机制
真实系统中,文档会经常更新。
你需要考虑:
- 新文档如何入库
- 旧文档如何删除
- 文档修改后如何重新向量化
- 如何避免重复内容
- 如何记录版本
- 如何定时同步数据源
6. 结果评估
AI搜索上线前需要评估效果。
可以准备一批测试问题,人工标注标准答案,然后评估:
- 检索命中率
- 答案准确率
- 幻觉率
- 引用正确率
- 响应时间
- 用户满意度
没有评估,就很难持续优化。
二十、生产级AI搜索架构建议
如果你想把Demo升级为生产系统,可以考虑如下架构:
数据源
↓
数据清洗服务
↓
文档切分服务
↓
Embedding服务
↓
向量数据库 / 搜索引擎
↓
检索服务
↓
重排序服务
↓
大模型服务
↓
API服务
↓
Web前端 / 企业微信 / 飞书 / 钉钉
生产系统还需要关注:
- 日志记录
- 用户反馈
- 异常重试
- 流式输出
- 缓存
- 成本控制
- 并发处理
- 数据安全
- 权限控制
- 内容审计
- 灰度发布
AI搜索看似只是一个问答框,背后其实是完整的信息检索和生成系统。
二十一、适合新手的学习路线
如果你是刚接触AI搜索,可以按照下面路线学习:
第一阶段:理解基础概念
重点掌握:
- 大语言模型
- Embedding
- 向量
- 相似度
- RAG
- Prompt
第二阶段:完成一个Demo
目标是跑通流程:
- 文档读取
- 文档切分
- 向量生成
- 向量检索
- 大模型回答
不必一开始追求复杂架构。
第三阶段:优化检索效果
学习:
- chunk切分策略
- BM25
- 混合检索
- rerank重排序
- query rewrite查询改写
第四阶段:工程化落地
学习:
- FastAPI
- Docker
- 向量数据库
- 异步任务
- 数据同步
- 权限系统
- 日志监控
第五阶段:评估和迭代
学习:
- 构建测试集
- 人工评估
- 自动评估
- 用户反馈闭环
- A/B测试
二十二、总结
AI搜索的本质,是把“搜索”和“生成”结合起来:先从知识库中找到相关资料,再让大模型基于资料生成答案。
对于新手来说,理解以下几点非常重要:
- AI搜索不是单纯调用大模型
- 高质量数据是效果基础
- 文档切分会显著影响检索质量
- Embedding让语义检索成为可能
- 向量数据库用于高效相似度搜索
- RAG是目前最主流的AI搜索架构
- 生产级系统需要关注权限、安全、评估和更新机制
本文提供的源码虽然简单,但已经包含AI搜索的核心流程。你可以在此基础上继续扩展,例如支持PDF解析、网页抓取、多文档管理、混合检索、引用来源、Web界面和权限控制。
如果你想真正掌握AI搜索,最好的方式不是只看概念,而是亲手搭建一个小系统。先让它跑起来,再逐步优化检索质量、回答质量和用户体验。
当你完成第一个AI搜索Demo后,你会发现:大语言模型真正有价值的地方,不只是聊天,而是连接你的数据,成为一个能够理解、检索、总结和辅助决策的智能入口。