为网站添加 AI 搜索功能:语义搜索与 RAG 实现指南
传统网站搜索依赖关键词匹配,用户必须使用精确的词汇才能找到相关内容。AI 语义搜索可以理解用户的真实意图,即使表达方式不同也能返回相关结果。
语义搜索 vs 关键词搜索
| 特性 | 关键词搜索 | AI 语义搜索 |
|---|---|---|
| 匹配方式 | 字面匹配 | 语义理解 |
| 拼写错误 | 不支持 | 自动纠错 |
| 同义词 | 需手动配置 | 自动理解 |
| 自然语言 | 不支持 | 完全支持 |
| 实现复杂度 | 低 | 中-高 |
| 搜索质量 | ⭐⭐ | ⭐⭐⭐⭐ |
技术架构
核心组件
- 嵌入模型(Embedding Model):将文本转换为向量
- 向量数据库:存储和检索向量
- LLM 生成回答(可选):将检索结果转换为自然语言回答
实现方案
方案一:基于向量数据库的语义搜索(推荐)
from openai import OpenAI
import chromadb
client = OpenAI()
chroma_client = chromadb.PersistentClient(path="./chroma_db")
collection = chroma_client.get_or_create_collection("website_content")
# 1. 索引文档
def index_content(docs):
for i, doc in enumerate(docs):
response = client.embeddings.create(
model="text-embedding-3-small",
input=doc["text"]
)
collection.add(
embeddings=[response.data[0].embedding],
documents=[doc["text"]],
metadatas=[{"title": doc["title"], "url": doc["url"]}],
ids=[f"doc_{i}"]
)
# 2. 搜索
def search(query, n_results=5):
response = client.embeddings.create(
model="text-embedding-3-small",
input=query
)
results = collection.query(
query_embeddings=[response.data[0].embedding],
n_results=n_results
)
return results
方案二:RAG 搜索(检索 + 生成)
在语义搜索基础上,加入 LLM 生成回答:
def rag_search(query):
# 1. 检索相关内容
context_docs = search(query)
context = "\n\n".join(context_docs["documents"][0])
# 2. 生成回答
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": f"基于以下内容回答用户问题。如果内容不足以回答,请如实告知。\n\n相关内容:\n{context}"},
{"role": "user", "content": query}
]
)
return response.choices[0].message.content
前端集成
// 搜索前端组件
class AISearch {
constructor(inputEl, resultEl) {
this.input = inputEl;
this.results = resultEl;
this.debounceTimer = null;
this.input.addEventListener('input', (e) => {
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.search(e.target.value);
}, 300);
});
}
async search(query) {
if (query.length < 2) return;
const response = await fetch('/api/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
const data = await response.json();
this.renderResults(data);
}
renderResults(data) {
this.results.innerHTML = data.map(item => `
<a href="${item.url}" class="search-result">
<h4>${item.title}</h4>
<p>${item.excerpt}</p>
</a>
`).join('');
}
}
向量数据库选择
| 数据库 | 类型 | 托管选项 | 免费额度 |
|---|---|---|---|
| Chroma | 嵌入式 | 自托管 | 完全免费 |
| Pinecone | 托管服务 | SaaS | 有免费层 |
| Weaviate | 自托管/云 | SaaS/自托管 | 有免费层 |
| Qdrant | 自托管/云 | SaaS/自托管 | 有免费层 |
| pgvector | PostgreSQL 扩展 | 自托管 | 完全免费 |
16IDC 观察
AI 语义搜索可以让网站的内容价值被更充分地发现。对于内容丰富的网站(文档、博客、知识库),语义搜索的用户满意度通常比传统搜索高 40-60%。建议从 Chroma 或 pgvector 开始,它们免费且易于集成。