# 通过抓取网站构建聊天机器人知识库：爬取、分块、引用

一个支持机器人只有在输入优质内容时才能表现出色。通过爬取您自己的网站——文档、常见问题解答、帮助中心——来清理markdown并将其分块以便检索。这是保持答案有依据和引用的流程。

一个支持聊天机器人只有在输入优质内容时才能表现出色，而最好的输入通常是您自己的网站——您已经维护的文档、常见问题解答和帮助中心文章。问题在于机器人无法像人一样阅读网站；它需要干净、分块、可检索的文本，并在每个部分附上来源。这个指南是完整的流程：爬取网站到markdown，分块，将其嵌入向量存储，并在查询时检索引用的上下文——一个随着网站变化而保持准确的知识库。

## 为什么选择RAG而不是微调

您可以在您的内容上微调一个模型，但对于支持机器人来说，这不是合适的工具：重新训练速度慢、成本高，并且一旦您编辑文档就会过时。检索增强生成（RAG）将知识保留在模型之外——将您的内容分块、嵌入，并在提问时检索最相关的部分并将其作为上下文提供给模型。更新文档，重新爬取，机器人的知识也随之更新。需求是真实存在的：根据KPMG的研究，聊天机器人市场预计到2030年将以23.3%的年复合增长率增长，69%的人已经使用聊天机器人，斯坦福和麻省理工学院对5,179名支持代理的研究显示，生成式AI辅助平均提高了14%的生产力——对于最新的代理则提高了35%。

## 步骤1：爬取网站到干净的markdown

将原始HTML输入到RAG流程中会因导航、cookie横幅和脚本标签而污染它。相反，直接爬取到markdown——它保留了标题、列表和表格，同时去掉了展示噪音，这正是LLM最适合摄取的内容。具有爬取模式的[Scraper API](https://quantumproxies.io/scraper-api)可以遍历网站并将每个页面返回为干净的markdown：

```python
import time
import requests

API = "https://api.quantumproxies.io/v1/scraper/crawl"
HEAD = {"Authorization": "Bearer YOUR_API_KEY"}

# the crawl runs as a background job: start it, then poll until it is done
job = requests.post(
    API,
    json={"url": "https://docs.example.com", "limit": 300, "format": "markdown"},
    headers=HEAD,
    timeout=120,
).json()["payload"]

pages, since = [], 0
while True:
    job = requests.get(f"{API}/{job['id']}", params={"since": since},
                       headers=HEAD, timeout=120).json()["payload"]
    pages += [{"url": p["url"], "markdown": p.get("content", "")} for p in job["pages"]]
    since = job["nextCursor"]
    if job["status"] != "running" and not job["hasMore"]:
        break
    time.sleep(10)
# pages: each {"url": ..., "markdown": ...}
```

爬取您自己的网站很简单；爬取受地理或速率限制的文档时，选择正确的IP进行路由很重要，以便爬取完成而不是中途停滞。以markdown为先的原则与[为LLM提供新鲜网络数据](https://quantumproxies.io/blog/feeding-llms-fresh-web-data-2026)的原则相同。

## 步骤2：按标题分块，保留来源

不要嵌入整页——检索在聚焦的块上效果最好。将每个页面按其标题拆分，以便每个块都是一个连贯的主题，并在每个块上附上来源URL，以便您以后可以引用。这也是一个好的来源文档发挥作用的地方：具有清晰标题的文章，每个标题一个想法，并在文本中重述问题的块远比一大段文字（机器人无法推断出人类会理解的上下文）要好：

```python
def chunk_markdown(md, source_url):
    chunks, cur = [], {"heading": "", "text": ""}
    for line in md.splitlines():
        if line.startswith("#"):
            if cur["text"].strip():
                chunks.append({**cur, "source": source_url})
            cur = {"heading": line.lstrip("# ").strip(), "text": ""}
        else:
            cur["text"] += line + "\n"
    if cur["text"].strip():
        chunks.append({**cur, "source": source_url})
    return chunks

all_chunks = [c for p in pages for c in chunk_markdown(p["markdown"], p["url"])]
```

![把网站变成客服机器人的 RAG 流水线：将网站爬取为干净的 markdown，按标题把每个页面切块并附上来源 URL，把这些块嵌入向量数据库，查询时检索最相关的四块并加以引用；卡片展示了每个块携带的信息：标题、正文、来源和抓取日期。](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335216/blog/generated/qp-b9-090-diag1.png)
*在查询时检索引用的块，而不是将整个网站塞入提示中——有依据且可检查。*

## 步骤3：嵌入、存储并通过引用检索

将每个块嵌入到一个向量中，并将其与来源URL作为元数据插入到向量数据库中。在查询时，嵌入用户的问题，提取最匹配的前几个，并将其文本作为上下文传递给模型——并显示来源链接，以便答案可检查，而不是一个黑箱：

```python
# index each chunk with its source as metadata
for c in all_chunks:
    vec = embed(c["heading"] + "\n" + c["text"])
    index.upsert(id=uid(c), values=vec,
                 metadata={"source": c["source"], "text": c["text"]})

# at query time: retrieve, ground, and cite
hits = index.query(embed(user_question), top_k=4)
context = "\n\n".join(h.metadata["text"] for h in hits)
citations = list({h.metadata["source"] for h in hits})
answer = llm(f"Answer using only this context:\n{context}", question=user_question)
```

将模型固定在检索到的上下文中——并告诉它仅从该上下文中回答——这就是防止支持机器人自信地编造政策的原因。引用有双重作用：它们让用户可以验证，并让您发现机器人何时在寻找错误的文档。有关更深入的机制，我们关于[RAG流程不陈旧](https://quantumproxies.io/blog/fresh-web-data-rag-pipelines)的指南进一步探讨了分块和检索。

## 步骤4：刷新，否则它会腐烂

知识库是一个活的东西。文档被重写，价格变化，新文章出现——而一个从上个月的爬取中回答的机器人会自信地给出错误答案。安排重新爬取，比较每个页面与其上一个版本，并仅重新嵌入更改的部分，以便刷新保持低成本。在每个块上保留一个获取日期，以便您始终知道答案来源的最新程度。如果您宁愿消费一个托管的、始终新鲜的供稿，而不是自己运行爬取和刷新，[为LLM构建的网络数据](https://quantumproxies.io/web-data-for-llms)负责收集方面。

![斯坦福大学和 MIT 对 5,179 名客服人员研究的柱状图：生成式 AI 辅助让生产率平均提升 14%，对最新入职的客服提升 35%；卡片显示，据 KPMG 研究，69% 的人已经在使用聊天机器人，预计到 2030 年聊天机器人市场的年复合增长率为 23.3%。](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335216/blog/generated/qp-b9-090-diag2.png)
*支持机器人的转变正在进行中；一个有依据、有引用的知识库是使其值得信赖的原因。*

[爬取任何网站到干净的markdown供您的机器人使用](https://quantumproxies.io/scraper-api)

## 常见问题解答

### 如何从网站构建聊天机器人知识库？

爬取网站以获得干净的markdown，将每个页面拆分为基于标题的块并附上来源URL，将这些块嵌入到向量数据库中，并在查询时检索最相关的块以支持模型的答案。安排重新爬取以保持其最新。这种RAG方法意味着编辑文档可以更新机器人的知识而无需重新训练。

### 我需要在我的内容上训练一个模型吗？

不需要——对于支持机器人来说，您不应该这样做。微调速度慢、成本高，并且每当您的内容发生变化时就会过时。检索增强生成将知识保存在模型外部的向量存储中，因此机器人始终从当前爬取中回答。只有在内容更改时才重新爬取和重新嵌入，这比重新训练便宜得多。

### 为什么要爬取到markdown而不是HTML？

原始HTML携带导航、广告、cookie横幅和脚本，这些都会增加噪音并浪费您的嵌入预算。Markdown保留了有意义的结构——标题、列表、表格——同时去掉了展示层，这正是LLM最干净地摄取的内容。更干净的输入意味着更相关的检索和更少的混淆答案。机器人也无法读取图像或视频，因此请将关键信息保留在文本中。

### 如何保持知识库的更新？

安排定期重新爬取，检测哪些页面发生了变化，并仅重新嵌入这些页面——完整的重新爬取会浪费带宽和计算资源。在每个块上存储一个获取日期，以便您可以判断答案来源的新鲜程度，并对索引进行版本管理，以便在糟糕的爬取降低检索效果时可以回滚。增量刷新使成本与实际变化成比例。

这里的流程就是产品：爬取到markdown，按标题分块，嵌入带来源的内容，检索并引用，然后按计划刷新。这样做，您的支持机器人就能从您的真实内容中回答，链接其来源，并随着您的网站发展保持最新——这是人们信任的机器人与他们学会绕开的机器人之间的区别。要通过标准接口为AI代理提供对相同数据的实时访问，请参阅我们关于[QuantumProxies MCP服务器](https://quantumproxies.io/blog/giving-ai-agents-live-web-access-with-mcp-a-practical-guide-to-the-quantumproxies-io-mcp-server)的指南。

[为您的机器人提供始终新鲜的网络数据](https://quantumproxies.io/web-data-for-llms)
