AI学习:第5天

是的,你已经成功完成了第4天的任务! 🎉

你现在拥有的成果:

  • ✅ 支持从 knowledge_base 文件夹批量加载多个 .txt 文档
  • ✅ 智能按段落切分文本(并处理长段落)
  • ✅ 基于 ChromaDB 的向量检索
  • ✅ FastAPI 提供的 /rag 接口,能基于私有知识回答问题

从你的测试输出看,模型正确回答了"用了哪些技术"和"核心功能",说明整个 RAG 流程运转正常。


第5天任务预告:增加对话记忆 + 简易前端

让系统支持多轮对话 (记住上下文),并做一个极简的 Web 界面方便演示。

今日目标

  1. 对话记忆:同一个 session 内能记住之前的问答。
  2. Gradio 前端:10分钟搭建一个可视化的聊天界面。

预计时间

  • 对话记忆改造:15分钟
  • Gradio 前端:15分钟

第5天详细步骤

一、安装 Gradio

bash 复制代码
pip install gradio

二、修改 app_rag.py,增加对话记忆

在现有代码基础上,增加一个字典来存储每个 session 的历史对话,并修改 /rag 接口接收 session_id

关键改动(在原有代码中添加/修改):

python 复制代码
# 在文件开头添加
from typing import List, Dict

# 存储对话历史 {session_id: [{"role": "user", "content": "..."}, {"role": "assistant", ...}]}
conversations: Dict[str, List[dict]] = {}

# 修改 RAGRequest 类
class RAGRequest(BaseModel):
    question: str
    session_id: str = "default"
    top_k: int = 3
    max_tokens: int = 200
    temperature: float = 0.7

# 修改 rag_endpoint 函数,在构造 prompt 时加入历史对话
@app.post("/rag")
async def rag_endpoint(request: RAGRequest):
    # 检索
    question_embedding = embedder.encode(request.question).tolist()
    results = collection.query(query_embeddings=[question_embedding], n_results=request.top_k)
    retrieved_docs = results['documents'][0] if results['documents'] else []
    
    # 获取最近3轮对话历史
    history = conversations.get(request.session_id, [])
    last_exchanges = history[-6:]  # 最多保留3轮(每轮2条)
    history_text = ""
    for turn in last_exchanges:
        history_text += f"{turn['role']}: {turn['content']}\n"
    
    context = "\n".join(retrieved_docs) if retrieved_docs else "无相关文档。"
    prompt = f"""基于以下已知信息和对话历史,回答用户问题。如果无法从已知信息中找到答案,请说"根据已有信息无法回答"。

已知信息:
{context}

对话历史:
{history_text}

用户:{request.question}
助手:"""
    
    # 生成回答... (与之前相同)
    # ... 生成 assistant_response ...
    
    # 保存历史
    conversations.setdefault(request.session_id, []).append({"role": "user", "content": request.question})
    conversations[request.session_id].append({"role": "assistant", "content": assistant_response})
    
    return {
        "answer": assistant_response,
        "retrieved_docs": retrieved_docs,
        "session_id": request.session_id
    }

三、创建独立的 Gradio 前端文件 ui.py

python 复制代码
import gradio as gr
import requests

API_URL = "http://127.0.0.1:8000/rag"

def chat_with_bot(message, history):
    """发送消息到后端 RAG API,并返回回复"""
    # 使用 gradio 自带的 session hash 作为 session_id
    session_id = str(gr.get_session_id())
    try:
        resp = requests.post(API_URL, json={
            "question": message,
            "session_id": session_id,
            "top_k": 3,
            "max_tokens": 200,
            "temperature": 0.7
        })
        if resp.status_code == 200:
            answer = resp.json()["answer"]
        else:
            answer = f"API 错误: {resp.status_code}"
    except Exception as e:
        answer = f"连接失败: {str(e)}"
    return answer

# 构建界面
with gr.Blocks(title="私有知识库问答系统") as demo:
    gr.Markdown("# 📚 基于本地大模型的 RAG 问答系统")
    gr.Markdown("上传文档到 `knowledge_base` 文件夹,然后向我提问吧!")
    
    chatbot = gr.Chatbot(height=500)
    msg = gr.Textbox(label="输入问题", placeholder="例如:我的项目用了哪些技术?")
    clear = gr.Button("清空对话")
    
    def respond(message, chat_history):
        bot_message = chat_with_bot(message, chat_history)
        chat_history.append((message, bot_message))
        return "", chat_history
    
    msg.submit(respond, [msg, chatbot], [msg, chatbot])
    clear.click(lambda: None, None, chatbot, queue=False)

if __name__ == "__main__":
    demo.launch(server_name="127.0.0.1", server_port=7860)

上述代码有兼容性问题,改成了下面的代码

python 复制代码
import gradio as gr
import requests

API_URL = "http://127.0.0.1:8000/rag"

def predict(message, history):
    """发送消息并返回回答"""
    try:
        resp = requests.post(API_URL, json={
            "question": message,
            "top_k": 3,
            "max_tokens": 200,
            "temperature": 0.7
        })
        if resp.status_code == 200:
            return resp.json()["answer"]
        else:
            return f"API 错误: {resp.status_code}"
    except Exception as e:
        return f"连接失败: {str(e)}"

# 创建界面(兼容旧版 Gradio)
iface = gr.ChatInterface(fn=predict, title="RAG 问答系统")
iface.launch(server_name="127.0.0.1", server_port=7860)

四、运行

  1. 确保后端服务已启动uvicorn app_rag:app --reload --port 8000

  2. 新开一个终端 ,激活 ai_env,运行:

    bash 复制代码
    python ui.py
  3. 浏览器会自动打开 http://127.0.0.1:7860,即可进行多轮对话。


今日产出

  • 支持多轮对话的 RAG 后端
  • 一个漂亮的 Web 聊天界面

完成这一步,你就拥有一个完整的、可演示的私有知识库问答系统了。继续加油!如果遇到问题,请随时截图。

相关推荐
ysu_03141 小时前
leetcode数据结构与算法5~7:链表双指针与二级指针
数据结构·学习·算法·leetcode·链表
知识分享小能手1 小时前
Hadoop学习教程,从入门到精通, 初识Hadoop — 知识点详解(1)
大数据·hadoop·学习
JdSnE27zv1 小时前
EF Code First学习笔记:数据库创建
数据库·笔记·学习
xian_wwq1 小时前
【学习笔记】「大模型安全:攻击面演化史」第 06 篇-红队方法论
笔记·学习·ai安全
wu_ye_m1 小时前
学习c语言第34天 用函数每次输出+1,链式访问,int和void
c语言·学习·算法
MartinYeung51 小时前
[论文学习]LLM 遗忘机制对真实世界扰动资料的稳健性研究
学习
凉、介1 小时前
深入理解 ARMv8-A|Application Binary Interface (ABI)
c语言·笔记·学习·嵌入式·arm
zhangakirn1 小时前
Systems Biology Part 1学习笔记
笔记·学习
say_fall2 小时前
模拟量输入输出技术超详细知识点总结
linux·开发语言·嵌入式硬件·学习·php