AI Agent Python 学习路线
首页
  • Month 1 概览
  • Week 1 · Python 语法速成
  • Week 2-3 · FastAPI 实战
  • Week 4 · AI / LLM 基础
  • Month 2 概览
  • Week 5-6 · LangChain / LangGraph
  • Week 7-8 · RAG 检索增强生成
  • Month 3 概览
  • Week 9-10 · 架构设计
  • Week 11 · 实现 + 调试
  • Week 12 · 部署 + 复盘
📚 资源 & 避坑
首页
  • Month 1 概览
  • Week 1 · Python 语法速成
  • Week 2-3 · FastAPI 实战
  • Week 4 · AI / LLM 基础
  • Month 2 概览
  • Week 5-6 · LangChain / LangGraph
  • Week 7-8 · RAG 检索增强生成
  • Month 3 概览
  • Week 9-10 · 架构设计
  • Week 11 · 实现 + 调试
  • Week 12 · 部署 + 复盘
📚 资源 & 避坑

Week 7-8:RAG(检索增强生成)

🎯 本周目标:给 Agent 加上"外挂硬盘"——让它能根据你的项目文档、历史交易数据来回答问题,而不是瞎编。

1. 为什么需要 RAG?

LLM 有两个致命缺点:

问题表现解决方案
知识截止日期LLM 只知道训练数据里的内容给它外挂最新数据
幻觉一本正经地瞎编不存在的事实让它先查资料再回答

RAG(Retrieval-Augmented Generation) = 检索 + 增强 + 生成

传统 LLM:  用户问题 → LLM → 直接回答(可能瞎编)
RAG:      用户问题 → 检索相关文档 → 把文档塞给 LLM → LLM 基于文档回答

RAG Pipeline 全景

flowchart LR
    A[文档] --> B[分块 Chunking]
    B --> C[向量化 Embedding]
    C --> D[存入向量数据库]
    E[用户问题] --> F[向量化 Embedding]
    F --> G[向量数据库检索 Top-K]
    G --> H[相关文档块]
    H --> I[组装 Prompt]
    I --> J[LLM 生成回答]

2. 核心概念对照

Embedding(嵌入)

把一段文字转换成一个数字向量(比如 768 维的数组),语义相近的文字,向量也相似。

# 例子:用 Embedding 模型把文字转成向量
"BTC 价格突破 10 万" → [0.12, -0.34, 0.56, ..., 0.78]  # 768 维
"比特币创下历史新高" → [0.11, -0.32, 0.55, ..., 0.76]  # 向量很接近 ✨
"今天吃了一碗牛肉面" → [0.01, 0.02, -0.10, ..., 0.05]  # 向量完全不同

向量数据库

存 Embedding 向量的数据库,能快速找到和查询向量最相似的 Top-K 条。

向量数据库特点适合场景
ChromaDB(推荐初学者)轻量、本地、Python 原生、API 友好个人项目 / 原型
FAISSMeta 开源,性能最强但 API 老大量向量 / 生产环境
Milvus分布式、企业级大规模生产
Pinecone云服务,免运维不想自己管的生产环境

💡 初学者选 ChromaDB

ChromaDB 不需要启动服务,直接 persist_directory="本地文件夹" 就能用,就像 SQLite 之于关系型数据库。

TS 对照

RAG 组件前端类比
文档分块 Chunking把大文件做 code-splitting,分成多个 chunk
Embedding给每个 chunk 生成一个"语义指纹"
向量检索按"指纹相似度"找到最相关的 chunk
Prompt 组装把检索到的 chunk 塞进 LLM 的 context window

3. 动手:本地 RAG 实战

安装依赖

.venv\Scripts\python -m pip install chromadb langchain-chroma langchain-huggingface sentence-transformers

sentence-transformers 是本地运行的 Embedding 模型,支持中文。

完整代码

# app/rag/rag_pipeline.py
"""
RAG Pipeline 示例:
把 electric-trading-ai 项目的文档喂进向量库,然后问问题
"""

from pathlib import Path
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader, DirectoryLoader
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# ===== 配置 =====
PERSIST_DIR = "./chroma_db"              # 向量数据库持久化目录
DOCS_DIR = Path("e:/wf_work/wf_ai/electric-trading-ai")  # 你的项目根目录

# ===== 1. 加载和分块文档 =====

def load_and_split_docs(docs_dir: Path):
    """加载项目里的文档,然后分块"""
    # 加载 Markdown、txt、py 文件(选择性排除)
    loader = DirectoryLoader(
        str(docs_dir),
        glob=["**/*.md", "**/*.txt"],
        recursive=True,
        use_multithreading=True,
    )
    docs = loader.load()
    print(f"加载了 {len(docs)} 个文档")

    # 分块:长文档切成小段落
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,          # 每块大约 500 字符
        chunk_overlap=50,        # 相邻块有 50 字符重叠,避免切断语义
        length_function=len,
    )
    splits = text_splitter.split_documents(docs)
    print(f"切分成了 {len(splits)} 个块")
    return splits


# ===== 2. Embedding + 存进 ChromaDB =====

def build_vector_store(splits):
    """用 Embedding 模型向量化并存入 ChromaDB"""
    # 本地 Embedding 模型(支持中文,首次会自动下载约 400MB)
    embeddings = HuggingFaceEmbeddings(
        model_name="shibing624/text2vec-base-chinese",  # 中文效果好
        model_kwargs={'device': 'cpu'},
        encode_kwargs={'normalize_embeddings': True},
    )

    # 创建/加载 ChromaDB
    vectorstore = Chroma.from_documents(
        documents=splits,
        embedding=embeddings,
        persist_directory=PERSIST_DIR,
        collection_name="trading_docs",
    )
    print(f"向量数据库已就绪,持久化到 {PERSIST_DIR}")
    return vectorstore


# ===== 3. 构建 RAG Chain =====

def build_rag_chain(vectorstore):
    """构建 RAG 问答链"""
    # 检索器:根据问题找 Top-4 最相关的文档块
    retriever = vectorstore.as_retriever(
        search_type="similarity",
        search_kwargs={"k": 4},
    )

    # LLM
    llm = ChatOpenAI(
        model="Qwen/Qwen2.5-7B-Instruct",
        base_url="https://api.siliconflow.cn/v1",
        api_key="your-api-key-here",
        temperature=0.3,  # RAG 场景要低温度,减少发散
    )

    # Prompt 模板
    prompt = ChatPromptTemplate.from_template("""
你是一个 AI Agent 学习助手。请严格基于以下上下文回答用户的问题。
如果上下文中没有相关信息,请说"抱歉,我在你的文档里没有找到相关内容",不要瞎编。

上下文:
{context}

用户问题:{question}
""")

    # LangChain LCEL Chain 组装
    rag_chain = (
        {"context": retriever | format_docs, "question": RunnablePassthrough()}
        | prompt
        | llm
        | StrOutputParser()
    )

    return rag_chain


def format_docs(docs) -> str:
    """把检索到的文档块拼成一个字符串"""
    return "\n\n".join(doc.page_content for doc in docs)


# ===== 4. 运行 =====

async def main():
    # Step 1-2: 构建向量库(第一次跑会慢,之后向量库持久化了就快)
    splits = load_and_split_docs(DOCS_DIR)
    vectorstore = build_vector_store(splits)

    # Step 3: 构建 RAG Chain
    rag_chain = build_rag_chain(vectorstore)

    # Step 4: 问答
    questions = [
        "这个 electric-trading-ai 项目有哪些依赖?",
        "项目用的什么框架?",
        "Python 版本要求是多少?",
        "你好",  # 测试无关问题
    ]

    for q in questions:
        print(f"\n{'='*50}")
        print(f"Q: {q}")
        answer = await rag_chain.ainvoke(q)
        print(f"A: {answer}")


if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

运行

.venv\Scripts\python app\rag\rag_pipeline.py

预期输出

加载了 5 个文档
切分成了 23 个块
向量数据库已就绪,持久化到 ./chroma_db

==================================================
Q: 这个 electric-trading-ai 项目有哪些依赖?
A: 根据项目配置文件,依赖包括 fastapi 等。

==================================================
Q: 项目用的什么框架?
A: 项目使用 FastAPI 作为 Web 框架。

==================================================
Q: Python 版本要求是多少?
A: 项目要求 Python 版本 >= 3.11。

==================================================
Q: 你好
A: 抱歉,我在你的文档里没有找到相关内容。

🎉 恭喜!你的 Agent 现在会查资料了! 不会再瞎编了。


4. 进阶:把 RAG 集成到 LangGraph Agent

把 RAG 作为 LangGraph 的一个 Tool,Agent 自己决定什么时候查:

from langchain_core.tools import tool

# 把 RAG 检索器包装成一个 Tool
@tool
def query_project_docs(question: str) -> str:
    """当用户问到关于本项目的技术问题时,用这个工具去查项目文档。"""
    # 这里的 vectorstore 就是上一节构建的
    retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
    docs = retriever.invoke(question)
    context = "\n\n".join(d.page_content for d in docs)
    return f"检索到以下相关内容:\n{context}"

# 然后把 query_project_docs 加进 Month 2 Week 5 的 TOOLS 列表
# Agent 就会自动在需要的时候调用它!

完整的增强后 Agent 图

flowchart TD
    A[START] --> B[analyze_intent]
    B --> C{意图分类}
    C -->|交易查询| D[use_trading_tools]
    C -->|项目技术问题| E[query_project_docs<br/>RAG Tool]
    C -->|闲聊| F[direct_chat]
    D --> G[summarize]
    E --> G
    G --> H[END]
    F --> H

5. RAG 效果调优

问题原因解决方案
检索不到相关内容chunk 太大或太小调整 chunk_size,一般 300-800
检索到的内容不相关Embedding 模型不匹配中文内容用中文 Embedding 模型
LLM 还是瞎编Prompt 约束不够加 "如果没有相关信息就说不知道"
回答太冗长检索到的 chunk 太多减少 k 值,或加 reranker 重排
中文效果差用了英文 Embedding 模型用 shibing624/text2vec-base-chinese 等中文模型

进阶调优方向(以后学)

  • Hybrid Search:关键词搜索 + 向量搜索结合
  • Reranker:检索后用 Cross-Encoder 重新排序
  • Query Rewriter:用户问题改写后再检索
  • Agentic RAG:Agent 自主决定要不要拆问题、查几次

6. 本周作业

#任务验收标准
1跑通上面的 RAG Pipeline能正确回答项目文档里的问题
2试试把你的 .env.example、README.md 也加进向量库覆盖更多知识
3把 RAG 包装成 LangGraph 的 Tool,集成到交易 AgentAgent 能自主决定何时查文档
4对比调不同的 chunk_size(200/500/800)看效果体会 chunking 策略的影响
5读 LangChain RAG Tutorial(官方)理解完整 RAG 流程

7. Month 2 总结

到这里你已经完成了:

  • ✅ LangGraph StateGraph 编排 Agent 行为流
  • ✅ Function Calling 让 Agent 调用真实 Python 函数
  • ✅ RAG 让 Agent 能查资料不瞎编
  • ✅ 把 Agent + RAG 集成到 FastAPI 后端

你现在已经能搭出一个有真实业务能力的 AI Agent 应用了! 进入 Month 3,我们会把所有东西串起来做一个完整项目、部署上线。🚀