RAG 课程笔记 - 在线查询阶段与实战问题解决

2026年3月30日 55点热度

核心理论知识

在线查询阶段(Online Phase)流程

用户提问 → Top-K 检索 → Prompt 设计 → Token 控制 → LLM 生成 → 回答

关键步骤
- Top-K 检索:从向量数据库召回最相关的 K 个文档片段
- Prompt 设计:将检索结果与问题组合成合适的提示词
- Token 控制:管理上下文窗口,优化成本和性能
- LLM 生成:基于上下文生成精准答案


Token 预算控制(重点!)

为什么要控制 Token 预算?

原因 说明
模型限制 所有 LLM 都有上下文窗口上限(如 GPT-4: 128K tokens)
成本控制 API 按 token 收费,过多 token = 高昂成本
性能优化 Token 越多 = 响应越慢
回答质量 过多无关信息会分散注意力,降低质量

Token 预算分配公式

\text{max\_tokens} = \text{检索到的知识} + \text{用户问题} + \text{LLM 回答}

示例分配(max_tokens=3000):

  • 检索到的知识:~2000 tokens(70%)
  • 用户问题:~200 tokens
  • LLM 回答:~800 tokens(30%)

实际代码实现

class RAGSystem:
    def __init__(self, max_tokens=3000):
        self.max_tokens = max_tokens
        self.context_budget = int(max_tokens * 0.7)  # 70% 给检索内容
        self.response_budget = int(max_tokens * 0.3)  # 30% 给回答

    def search_and_generate(self, query):
        # 动态调整 top_k,确保不超过 context_budget
        chunks = []
        total_tokens = 0

        for chunk in vector_store.search(query, top_k=10):
            chunk_tokens = count_tokens(chunk.text)
            if total_tokens + chunk_tokens <= self.context_budget:
                chunks.append(chunk)
                total_tokens += chunk_tokens
            else:
                break  # 达到预算,停止检索

        # 构建 prompt 并调用 LLM
        response = llm.generate(prompt, max_tokens=self.response_budget)
        return response

关键技术要点总结

FAISS/ChromaDB 检索细节

当 top_k > index.ntotal 时
- 多余的返回位置填充 -1
- 必须过滤掉 -1,否则会导致索引错误

# 需要过滤掉 -1
valid_results = [idx for idx in indices if idx != -1]

热更新机制

后端使用 Uvicorn 的 --reload 参数实现热更新:

python -m uvicorn app.main:app --reload --port 8000

工作原理
- 父进程监控文件变化
- 子进程运行应用
- 检测到 .py 文件变化时自动重启子进程

注意事项
- 生产环境禁用热更新
- 有轻微性能开销

xxs9331

这个人很懒,什么都没留下

文章评论