前端 + AI 学习记录(Day 1–10):从 0 到第一个 RAG Demo
前端 + AI 学习记录(Day 1–10):从 0 到第一个 RAG Demo
这篇是 60 天学习计划里的第一篇阶段总结,覆盖 Day 1–10:从环境准备,到第一个能用的 RAG 文档问答 Demo。
一、整体目标:从 0 跑通一个「带上下文的 AI 问答」小项目
这 10 天我给自己的目标是:
- 不纠结模型细节,先完成一条闭环:
前端输入 → 后端调用 LLM → 返回答案 → 能基于文档做问答。 - 同时把后面可复用的东西沉淀下来:项目结构、简单 hooks、请求封装。
二、Day 1–2:环境准备 & 第一次 OpenAI 调用
关键点:
- 安装 Node.js(建议 18+),初始化项目:
mkdir ai-learning cd ai-learning npm init -y npm install axios dotenv - 配置
.env(这里只写结构):OPENAI_API_KEY=sk-xxxx - 写一个最小的 Node 脚本,确认 API 可用:
// day1-openai-test.js
require('dotenv').config()
const axios = require('axios')
async function main() {
const res = await axios.post(
'https://api.openai.com/v1/chat/completions',
{
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: '用一句话介绍前端开发' }]
},
{
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`
}
}
)
console.log(res.data.choices[0].message.content)
}
main().catch(console.error)
这两天的目标很简单:能稳定打通到 LLM,别在环境问题上反复卡住。
三、Day 3–5:Express 后端 + 流式聊天 + 小机器人
后端基础 API:
- 建一个简单的 Express 服务,暴露
/api/chat:
// server.js(简化版,不含 OpenAI 调用细节)
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
app.use(express.json())
app.post('/api/chat', async (req, res) => {
const { question } = req.body
// 这里真实项目中会调用 OpenAI,这里先返回 echo
res.json({ answer: `你问的是:${question}` })
})
app.listen(3000, () => console.log('server on http://localhost:3000'))
流式(SSE)版本:
- 增加
/api/chat/stream,返回text/event-stream,模拟流式输出:
app.post('/api/chat/stream', (req, res) => {
const { question } = req.body
res.setHeader('Content-Type', 'text/event-stream')
res.setHeader('Cache-Control', 'no-cache')
res.setHeader('Connection', 'keep-alive')
const chunks = [`你问的是:${question}\n`, '这是第二段\n', '这是最后一段\n']
let i = 0
const timer = setInterval(() => {
if (i >= chunks.length) {
res.write('data: [DONE]\n\n')
clearInterval(timer)
res.end()
} else {
res.write(`data: ${JSON.stringify({ type: 'delta', content: chunks[i] })}\n\n`)
i++
}
}, 500)
})
到 Day 5:已经有了可本地跑的“小聊天机器人”,只是回答还很简单,下一阶段加 RAG。
四、Day 6–7:提示工程 & Function Calling 入门
提示工程(Prompt Engineering):
- 学会写一个稍微“专业一点”的系统提示:
const systemPrompt = `
你是一个前端开发助手,擅长 React/Vue/TypeScript。
回答要求:
- 尽量简洁,必要时分点说明
- 如需给代码,使用对应语言的最佳实践
`
- 请求里 messages 改为:
```js
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: question }
]
Function Calling 思路:
- 为后面要用的工具设计 JSON Schema(示例,不一定立即实现):
const getWeatherTool = { name: 'get_weather', description: '查询指定城市当前天气', parameters: { type: 'object', properties: { city: { type: 'string', description: '城市名' } }, required: ['city'] } } - 这两天的重点是理解概念:
LLM 负责“选函数 + 填参数”,真正的执行在你的后端/服务里。
五、Day 8–9:Embedding & 第一个 RAG Demo
Embedding & 向量库(概念 + 简单实现):
-
引入一个 Embedding API(可以是 OpenAI / 也可以假数据),先做一个极简向量库:
interface VecDoc { id: string text: string embedding: number[] // 真实项目里是 high-dim 向量 } const db: VecDoc[] = [] // 内存版 -
实现一个“伪”相似度搜索(这里先用
includes代替):function searchDocs(query: string, docs: VecDoc[]): VecDoc[] { return docs .filter(d => d.text.includes(query)) .slice(0, 3) }
RAG Demo 后端结构:
- 新增接口
/api/rag-qa:app.post('/api/rag-qa', async (req, res) => { const { question } = req.body const topDocs = searchDocs(question, db) const context = topDocs.map(d => d.text).join('\n---\n') // 拼成 Prompt,调用 LLM(这里简化为直接返回 context+question) const answer = `基于以下文档回答:\n${context}\n\n问题:${question}` res.json({ answer, docs: topDocs.map(d => d.id) }) })
到 Day 9:你已经有一个最简 RAG:
搜索 → 拼上下文 → 问问题 → 返回答案(暂时可不连 OpenAI,用假数据跑通结构)。
六、Day 10:阶段总结 & 心得
到第 10 天,我已经搞定:
- 一条从前端 → 后端 → LLM 的基本调用链路
- 一个最简聊天 + 流式输出 Demo
- 一个「伪 RAG」结构(后面随时可以接真 Embedding/向量库)
这 10 天对我最有用的几点:
- 先跑通最小 Demo,再优化:
不纠结 Embedding/模型细节,先用假数据把 RAG 的“形”搭出来。 - 早建基础骨架:
后端统一/api/chat//api/chat/stream//api/rag-qa,前端只调这几个,不到处散落fetch。 - Prompt 比想象中重要:
即使是简单的 system prompt,也能让输出“看起来专业很多”。

浙公网安备 33010602011771号