历史周报语义搜索与知识问答:基于向量相似度的智能回忆录
2026/9/21 22:14:05 网站建设 项目流程

历史周报语义搜索与知识问答:基于向量相似度的智能回忆录

在很多企业或个人开发者的知识资产积累中,工作周报沉淀了最宝贵的“技术排障实录、架构演进决策与踩坑解决方案”。

然而,当用户在半年后遇到一个相似的线上事故时:

  • 我记得 3 个月前我在微前端里解决过一个 Shadow DOM 字体跨域污染的问题,当时改了哪个 Nginx 配置来着?
  • 如果使用传统的模糊关键词匹配(如LIKE '%字体%'),系统会搜出 50 篇毫无关联的文字,用户不得不一篇一篇人肉翻找;
  • 更不用说用户想问一句:“请帮我汇总一下我在 Q2 季度为支付模块做了哪些具体的安全防刷措施?”,传统关键词搜索对此彻底束手无策。

为了将散落在数百篇历史周报中的碎片信息,升华为**“可对话、可精准追溯来源、支持自然语言语义检索的个人技术知识库(Semantic Recall & QA)”**,基于轻量向量检索(Vector Embeddings + Cosine Similarity)与 RAG 架构是最佳落地范式。

周报语义搜索与 RAG 问答架构

用户自然语言提问: "我之前是怎么解决微前端字体跨域问题的?" │ ▼ (步骤 1: 将 Query 转化为高维向量 Query Embedding) ┌─────────────────────────────────────────────────────────────┐ │ 向量相似度检索 (SQLite-vec / 余弦相似度 Top-3) │ ├──────────────────────────────┬──────────────────────────────┤ │ 召回切片 1: 0914 周报 (相似度 0.89) 包含 Nginx CORS 字体配置 │ │ 召回切片 2: 0918 周报 (相似度 0.81) 包含 Shadow DOM 样式隔离 │ └──────────────────────────────┴──────────────────────────────┘ │ ▼ (步骤 2: 组装 Prompt 注入精准上下文 Context) ┌─────────────────────────────────────────────────────────────┐ │ 大语言模型 (LLM) 综合生成回答 │ │ - 给出结构化的排障方案总结 │ │ - 附带精确的周报日期与跳转锚点 [引用来源: 2026-09-14 周报] │ └─────────────────────────────────────────────────────────────┘

核心实现一:向量余弦相似度计算与召回(TypeScript)

// src/services/semanticSearchEngine.ts import { db } from '../db'; import { reportEmbeddings, reports } from '../db/schema'; import { eq } from 'drizzle-orm'; import { generateEmbedding } from './embeddingService'; export interface SearchResultItem { reportId: string; title: string; dateStr: string; snippet: string; similarityScore: number; } // 计算两个浮点向量之间的余弦相似度 (Cosine Similarity) export function cosineSimilarity(vecA: number[], vecB: number[]): number { let dotProduct = 0; let normA = 0; let normB = 0; for (let i = 0; i < vecA.length; i++) { dotProduct += vecA[i] * vecB[i]; normA += vecA[i] * vecA[i]; normB += vecB[i] * vecB[i]; } if (normA === 0 || normB === 0) return 0; return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); } export async function searchHistoricalReports(userId: string, query: string, topK = 3): Promise<SearchResultItem[]> { // 1. 将用户的自然语言搜索转为 1536 维向量 const queryVector = await generateEmbedding(query); // 2. 查询该用户的所有周报向量切片 const userEmbeddings = await db .select({ reportId: reportEmbeddings.reportId, embedding: reportEmbeddings.embedding, contentChunk: reportEmbeddings.chunkContent, reportTitle: reports.title, createdAt: reports.createdAt }) .from(reportEmbeddings) .innerJoin(reports, eq(reportEmbeddings.reportId, reports.id)) .where(eq(reports.userId, userId)); // 3. 内存计算相似度并降序排序 const scoredItems = userEmbeddings.map((item) => { const similarity = cosineSimilarity(queryVector, item.embedding as number[]); return { reportId: item.reportId, title: item.reportTitle, dateStr: item.createdAt.toISOString().slice(0, 10), snippet: item.contentChunk, similarityScore: similarity }; }); return scoredItems .sort((a, b) => b.similarityScore - a.similarityScore) .slice(0, topK); }

核心实现二:基于 RAG 的智能周报问答引擎(TypeScript)

// src/services/historicalQAService.ts import OpenAI from 'openai'; import { searchHistoricalReports } from './semanticSearchEngine'; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); export async function answerUserHistoryQuestion(userId: string, question: string) { // 1. 语义向量检索最相关的历史周报片段 const relevantChunks = await searchHistoricalReports(userId, question, 3); if (relevantChunks.length === 0 || relevantChunks[0].similarityScore < 0.65) { return { answer: '抱歉,在您的历史周报中没有找到与该问题相关的技术记录。', sources: [] }; } // 2. 构造 RAG 上下文 const contextText = relevantChunks .map((c, i) => `[来源 ${i + 1}: ${c.dateStr} 《${c.title}》]\n${c.snippet}`) .join('\n\n---\n\n'); // 3. 调用大模型综合提炼回答 const completion = await openai.chat.completions.create({ model: 'gpt-4o-mini', temperature: 0.2, messages: [ { role: 'system', content: `你是一位全知全能的个人技术档案秘书。请基于以下提供的历史周报真实记录,严谨、客观地回答用户的问题。如果记录中没有提及,请如实告知,严禁凭空捏造。` }, { role: 'user', content: `【历史周报档案记录】:\n${contextText}\n\n【用户问题】: ${question}` } ] }); return { answer: completion.choices[0].message.content, sources: relevantChunks.map(c => ({ title: c.title, date: c.dateStr, reportId: c.reportId })) }; }

前端交互体验呈现

用户在“智能回忆录”搜索框中输入:

“我上个月是怎么优化 Vite 静态资源小图标请求的?”

系统在 800ms 内输出:

您在 **2026-09-14** 的周报中详细记录了该方案: 1. 在 `vite.config.ts` 中将 `assetsInlineLimit` 阈值配置为 4096 (4KB),实现了小图片自动 Base64 内联; 2. 引入了 `vite-plugin-svg-icons` 插件,在编译期将分散的 SVG 图标全量合成为单体 SVG 精灵图 DOM 符号表; 3. 将首屏 HTTP 请求数从 54 个锐减至 14 个,彻底消灭了布局闪烁。 📌 **关联引用来源**: - [2026-09-14 · Vite静态资源内联优化与SVG精灵图合并](#)

知识沉淀价值

将非结构化的历史周报转变为**“随身携带的智能第二大脑(Second Brain)”**:

  • 工程师写过的每一行技术总结都不再沉睡在归档库里,随时可以被自然语言重新唤醒;
  • 在季度晋升答辩、年度述职与新员工交接时,一键生成全局技术贡献知识图谱,极大地放大了技术沉淀的长期价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询