作者:一位Android开发工程师 | 2026年6月12日
系列:第8天学会了Embedding,今天串起来做检索


前言

第8天我把文字变成了向量。今天把这些向量用起来——有一个知识库(5条文档),用户提问,找出最相关的文档

这是 RAG 的"R"(Retrieval)部分。


实验设计

知识库故意放了一条不相关的(Python),验证检索能不能正确排序:

docs = [
    "Kotlin的val声明只读变量,var声明可变变量",
    "协程是Kotlin中处理异步任务的轻量级线程",
    "Android的Activity生命周期包括onCreate、onStart、onResume",
    "Python中列表推导式可以快速生成列表",        # ← 干扰项
    "Kotlin data class自动生成equals、hashCode、toString方法",
]

query = "Kotlin的不可变变量怎么声明?"

核心代码

model = SentenceTransformer("all-MiniLM-L6-v2")

# 1. 查询向量化
q_vec = model.encode(query)

# 2. 每条文档向量化 + 计算相似度
results = []
for doc in docs:
    vec = model.encode(doc)
    sim = np.dot(vec, q_vec) / (np.linalg.norm(vec) * np.linalg.norm(q_vec))
    results.append((sim, doc))

# 3. 排序
results.sort(reverse=True)

for sim, doc in results:
    print(f"[{sim:.4f}] {doc}")

运行结果

[0.8231] Kotlin的val声明只读变量,var声明可变变量        ← 排第1 ✅
[0.6724] Kotlin data class自动生成equals、hashCode...   ← 排第2
[0.5438] 协程是Kotlin中处理异步任务的轻量级线程            ← 排第3
[0.4127] Android的Activity生命周期包括onCreate...        ← 排第4
[0.2983] Python中列表推导式可以快速生成列表               ← 排最后 ✅

val/var 那条准确排第一,Python 那条排最后——检索完全正确。


关键细节:别用字典存结果

我一开始用 {相似度: 文档} 字典存结果,但被指出了 bug——如果两条文档相似度碰巧相同,后面的会覆盖前面的。

正确做法是用元组列表

results.append((sim, doc))    # ✅ 不会丢失数据

今天的一句话总结

向量检索就三步:把查询变向量 → 遍历知识库算余弦相似度 → 排序取 Top K。后面学 Chroma 向量数据库时,这些手写逻辑会被封装成一行代码。


下一篇预告

第10天:RAG 完整流程——把检索结果拼进 prompt,发给 LLM 生成回答。


本系列记录一位Android开发者转行AI Agent的完整学习过程,欢迎关注交流。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐