上周的原理今天变成产品:numpy 手搓完整 RAG 链路(不用任何框架), 做出「课程 FAQ 问答机器人」;然后串起 Vision(看图)→ 文本 → TTS(说话)的多模态链路。
| 时间 | 环节 | 要点 |
|---|---|---|
| 0–8 | 今日目标 | 课程 FAQ 问答机器人——把上周原理变成产品 |
| 8–20 | 离线建库 | 切分 chunk → Embedding API → numpy 存向量;chunk 大小是可调参数 |
| 20–34 | 在线检索生成 | 余弦相似度全库打分 → top-k → 拼接 prompt → 有据回答 |
| 34–46 | 动手练习 | 运行场:二维语义地图上的余弦检索排序 |
| 46–58 | 调参实验 | 改 k(2→5)、改 chunk 大小,观察命中变化——检索质量决定上限 |
| 58–68 | 为什么不用框架 | LangChain 把每步藏进黑盒;numpy+SDK 每行看得见 |
| 68–80 | 多模态:看图 | Vision API;base64/URL 传图;OCR/图表解读 |
| 80–90 | 多模态:说话 | TTS 文字转语音;模态链路=一个 API 的输出是另一个的输入 |
| 90–100 | 小测 | 随堂小测 3 题 |
今日产出:一个能回答课程问题的 RAG 问答系统(numpy 手搓版)。
import numpy as np
# 1) 文档 → 切块(chunking)
chunks = split_docs(docs, size=200) # 按段落/长度切
# 2) 每块 → 向量(Embedding API,一次性)
vecs = np.array([embed(c.text) for c in chunks]) # (N, 1536)
np.save("kb_vectors.npy", vecs) # 存下来,下次不用重新算钱
def cosine(a, b): # 余弦相似度:方向越一致越相关
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
def answer(question, k=3):
qv = embed(question)
scores = [ cosine(qv, v) for v in vecs ] # 全库打分
top = np.argsort(scores)[::-1][:k] # 取 top-k
context = "\n\n".join(chunks[i].text for i in top)
return llm_chat(
f"基于以下资料回答问题,没有依据就说不知道:\n\n{context}\n\n问题:{question}"
)
判断力:不是所有场景都要多模态——能用文字说清的,不必强行看图。
深入阅读:M5 模块页 · 经典笔记 15.4(数据→结论链路)