为网站添加 AI 搜索功能:语义搜索与 RAG 实现指南

传统网站搜索依赖关键词匹配,用户必须使用精确的词汇才能找到相关内容。AI 语义搜索可以理解用户的真实意图,即使表达方式不同也能返回相关结果。

语义搜索 vs 关键词搜索

特性 关键词搜索 AI 语义搜索
匹配方式 字面匹配 语义理解
拼写错误 不支持 自动纠错
同义词 需手动配置 自动理解
自然语言 不支持 完全支持
实现复杂度 中-高
搜索质量 ⭐⭐ ⭐⭐⭐⭐

技术架构

核心组件

  1. 嵌入模型(Embedding Model):将文本转换为向量
  2. 向量数据库:存储和检索向量
  3. 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 开始,它们免费且易于集成。