三大实战项目搭建

📚 Day8:RAG 知识库项目搭建(Vue3+FastAPI)

目标:跑通「上传 PDF → 解析 → 向量检索 → 问答」的完整流程

一、后端(FastAPI)极简代码

1. 安装依赖

bash

运行

复制代码
pip install fastapi uvicorn pdfplumber faiss-cpu sentence-transformers python-multipart

2. 核心代码 main.py

python

运行

复制代码
from fastapi import FastAPI, UploadFile, File
from fastapi.responses import JSONResponse
import pdfplumber
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer

app = FastAPI()

# 初始化模型和向量库
model = SentenceTransformer("all-MiniLM-L6-v2")
index = faiss.IndexFlatL2(384)  # 384维向量
text_chunks = []

# 1. 上传并解析PDF
@app.post("/upload")
async def upload_pdf(file: UploadFile = File(...)):
    with pdfplumber.open(file.file) as pdf:
        text = "\n".join([page.extract_text() for page in pdf.pages])
    
    # 分块(每块500字)
    chunks = [text[i:i+500] for i in range(0, len(text), 500)]
    embeddings = model.encode(chunks)
    
    # 存入向量库
    index.add(np.array(embeddings))
    text_chunks.extend(chunks)
    return {"status": "success", "chunks_count": len(chunks)}

# 2. 问答接口
@app.post("/chat")
async def chat(question: str):
    # 问题向量化+检索
    q_emb = model.encode([question])
    _, indices = index.search(np.array(q_emb), k=2)
    context = "\n".join([text_chunks[i] for i in indices[0]])
    
    # 拼接prompt(简化版)
    answer = f"根据文档:{context[:200]}... 回答:{question}的相关信息是XXX"
    return {"answer": answer}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

3. 启动服务

bash

运行

复制代码
python main.py

访问 http://localhost:8000/docs 就能直接测试接口。


二、前端(Vue3+TS)极简代码

1. 安装依赖

bash

运行

复制代码
npm create vite@latest rag-front -- --template vue-ts
cd rag-front
npm install axios element-plus

2. 核心页面 src/App.vue

vue

复制代码
<template>
  <el-container>
    <el-upload action="/api/upload" :before-upload="beforeUpload" :on-success="handleUploadSuccess">
      <el-button>上传PDF文档</el-button>
    </el-upload>

    <el-input v-model="question" placeholder="输入你的问题" style="margin-top:20px" />
    <el-button @click="handleChat" style="margin-top:10px">提问</el-button>

    <div class="answer-box" style="margin-top:20px">{{ answer }}</div>
  </el-container>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'

const question = ref('')
const answer = ref('')

const beforeUpload = (file: File) => {
  if (file.type !== 'application/pdf') {
    alert('仅支持PDF文件')
    return false
  }
  return true
}

const handleUploadSuccess = () => {
  alert('上传成功,可开始提问!')
}

const handleChat = async () => {
  const res = await axios.post('http://localhost:8000/chat', { question: question.value })
  answer.value = res.data.answer
}
</script>

3. 配置跨域 vite.config.ts

ts

复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})

4. 启动前端

bash

运行

复制代码
npm run dev

打开 http://localhost:5173,上传 PDF、提问,就能看到 RAG 效果!


📚 Day9:Agent 办公助手项目搭建

目标:实现「工具调用」能力,让 AI 能 "调用计算器 / 查天气"

一、后端工具调用逻辑(扩展 Day8 的 main.py

python

运行

复制代码
import json

# 定义工具
tools = [
    {
        "name": "calculator",
        "description": "用于计算数学表达式",
        "parameters": {"expression": "str,如'2+3*4'"}
    }
]

# 工具执行函数
def call_tool(name, params):
    if name == "calculator":
        return {"result": eval(params["expression"])}
    return {"error": "工具不存在"}

# 修改chat接口,增加工具调用逻辑
@app.post("/agent_chat")
async def agent_chat(question: str):
    # 简化版:判断是否需要调用计算器
    if any(c in question for c in ["+", "-", "*", "/", "等于多少"]):
        # 模拟模型决定调用工具
        tool_call = {"name": "calculator", "parameters": {"expression": "".join([c for c in question if c in "0123456789+-*/"])}}
        tool_result = call_tool(tool_call["name"], tool_call["parameters"])
        answer = f"计算结果:{tool_result['result']}"
    else:
        answer = "这是普通问答结果"
    return {"answer": answer}

二、前端扩展对话历史

修改 App.vue,增加对话列表:

vue

复制代码
<template>
  <div class="chat-container">
    <div v-for="msg in messages" :key="msg.id" :class="msg.role">
      {{ msg.content }}
    </div>
    <el-input v-model="question" @keyup.enter="handleAgentChat" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'

const messages = ref([])
const question = ref('')

const handleAgentChat = async () => {
  messages.value.push({ role: 'user', content: question.value })
  const res = await axios.post('/api/agent_chat', { question: question.value })
  messages.value.push({ role: 'assistant', content: res.data.answer })
  question.value = ''
}
</script>

<style scoped>
.user { text-align: right; background: #e6f7ff; padding: 8px; margin: 8px 0; }
.assistant { text-align: left; background: #f0f0f0; padding: 8px; margin: 8px 0; }
</style>

📚 Day10:多模态文档问答项目搭建

目标:支持图片 + 扫描 PDF 解析,实现图文问答

一、后端增加 OCR 能力

1. 安装依赖

bash

运行

复制代码
pip install paddlepaddle paddleocr pdf2image

2. 增加图片解析接口

python

运行

复制代码
from PIL import Image
from paddleocr import PaddleOCR

ocr = PaddleOCR(use_angle_cls=True, lang='ch')

@app.post("/upload_image")
async def upload_image(file: UploadFile = File(...)):
    image = Image.open(file.file)
    result = ocr.ocr(image, cls=True)
    text = "\n".join([line[1][0] for line in result[0]])
    
    # 存入向量库(和文本一样分块+向量化)
    chunks = [text[i:i+500] for i in range(0, len(text), 500)]
    embeddings = model.encode(chunks)
    index.add(np.array(embeddings))
    text_chunks.extend(chunks)
    return {"status": "success", "ocr_text": text[:100]}

二、前端增加图片上传

修改 App.vue 的上传组件:

vue

复制代码
<el-upload
  action="/api/upload_image"
  accept="image/*"
  :on-success="handleUploadSuccess"
>
  <el-button>上传图片</el-button>
</el-upload>

📚 Day11:流式对话(SSE/WebSocket)实现

目标:实现 AI 回答逐字输出,解决等待卡顿问题

一、后端 SSE 接口

python

运行

复制代码
from fastapi.responses import StreamingResponse
import asyncio

@app.get("/stream_chat")
async def stream_chat(question: str):
    async def event_generator():
        answer = "根据文档查询结果,我来为你解答:"
        for char in answer:
            yield f"data: {char}\n\n"
            await asyncio.sleep(0.05)  # 控制输出速度
    return StreamingResponse(event_generator(), media_type="text/event-stream")

二、前端 SSE 对接

vue

复制代码
<script setup lang="ts">
const connectSSE = (question: string) => {
  const source = new EventSource(`/api/stream_chat?question=${encodeURIComponent(question)}`)
  source.onmessage = (event) => {
    // 逐字追加到当前回答
    messages.value[messages.value.length - 1].content += event.data
  }
}
</script>

✅ 验收标准

按步骤做完,你将拥有一个完整的 AI 应用 Demo:

  1. 支持 PDF / 图片上传解析
  2. 支持 RAG 知识库问答
  3. 支持 Agent 工具调用
  4. 支持流式对话输出
  5. 基于 Vue3+TS 开发,可直接写进简历

相关推荐
aqi003 天前
15天学会AI应用开发(八)使用向量数据库实现RAG功能
人工智能·python·大模型·ai编程·ai应用
aqi004 天前
15天学会AI应用开发(七)有了大模型为什么还要引入RAG
人工智能·python·大模型·ai编程·ai应用
vivo互联网技术5 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
AndrewHZ6 天前
【LLM技术全景】大模型能力探秘:In-Context Learning与思维链(CoT)
人工智能·语言模型·大模型·llm·cot·思维链·icl
Vergelight6 天前
实战拆解|三类RAG架构差异:朴素、进阶、多轮RAG落地选型指南
架构·大模型·aigc·agent·ai产品经理·转行·ai后台设计
问道飞鱼7 天前
【大模型相关】意图识别实现方案行业分析报告
大模型·意图识别
DogDaoDao7 天前
【GitHub】CL4R1T4S:AI 系统提示词的透明革命
人工智能·python·ai·大模型·github·ai agent·cl4r1t4s
文艺倾年7 天前
【强化学习】数学推导专题,20W字总结(十五)
人工智能·分布式·大模型·强化学习·vibecoding
IRevers7 天前
【大模型】Gemma4在ROCm和vLLM部署
人工智能·pytorch·深度学习·大模型·datawhale·vllm·amdev
张彦峰ZYF7 天前
从嵌入、表征到潜空间:理解大模型向量世界的三种视角
人工智能·大模型·向量空间