V040:RAG 检索增强生成的工程链路解构与生产级系统设计

V040:RAG 检索增强生成的工程链路解构与生产级系统设计

摘要:本文从工程视角系统解构 RAG(Retrieval-Augmented Generation)的完整技术链路,涵盖文档工程、向量检索原理、相似度评分机制、元数据架构、上下文窗口管理、生产级组件选型及高级检索模式。文章以可观测的中间结果为导向,建立从原型验证到生产部署的技术决策框架,并配套面试应答策略。


引言:RAG 认知的三个层次

对 RAG(Retrieval-Augmented Generation)的理解可分为三个递进层次:

层次 认知特征 典型表述
第一层:概念认知 知道 RAG 是什么,能描述三字母含义 "RAG 是检索增强生成"
第二层:流程认知 能叙述端到端的数据流动 "先检索文档,再拼接 Prompt 给 LLM"
第三层:工程认知 理解每个环节的内部机制与决策依据 "检索器在向量查询之外叠加了去重、过滤、重排序"

本文定位于从第二层向第三层过渡的技术进阶。我们不重复 RAG 的基本概念,而是深入工程链路中的关键决策点,建立"可观测、可解释、可调优"的系统化认知框架。


一、RAG 全链路的工程分解

1.1 七阶段管线架构

完整的 RAG 系统可分解为两个阶段、七个工程步骤:

写时链路(知识入库)

阶段 输入 输出 核心决策
文档构建 原始文本语料 Document[],含 pageContent + metadata 分块策略、元数据 Schema
向量化 pageContent 文本 稠密向量(dense vector) 嵌入模型选型、维度确定
向量索引存储 向量 + Document 可查询的向量索引 存储引擎、索引算法(HNSW/IVF)

读时链路(用户查询)

阶段 输入 输出 核心决策
检索引擎构建 VectorStore 实例 Retriever 接口封装 k 值、检索策略、过滤条件
相似度检索 用户查询 Top-k 文档集合 + 距离分数 阈值设定、去重逻辑、重排序
上下文增强 检索结果 + 用户问题 增强 Prompt Token 预算分配、片段排序
生成 增强 Prompt 最终回答 模型选择、采样参数

工程直觉:写时链路的决策(分块粒度、元数据设计、嵌入模型)决定了读时链路的质量上限。检索是信息过滤,生成是信息演绎------前者决定了后者可用的信息边界。

1.2 可观测性实现:全链路中间结果打印

typescript 复制代码
// ===== 写时链路 =====
// 步骤1: 文档构建
const documents: Document[] = [
  new Document({
    pageContent: `光光是一个活泼开朗的小男孩......`,
    metadata: { chapter: 1, character: "光光", type: "角色介绍", mood: "活泼" },
  }),
  // ... 共 7 个带 metadata 的 Document
];

// 步骤2+3: 向量化与存储(原子操作)
const vectorStore = await MemoryVectorStore.fromDocuments(documents, embedding);

// 步骤4: 检索器构建
const retriever = vectorStore.asRetriever({ k: 3 });

// ===== 读时链路 =====
// 步骤5: 相似度检索
const retrievedDocs = await retriever.invoke("光光和东东是怎么成为朋友的?");

// 带分数的原始向量查询(用于调试与阈值决策)
const scoredResults = await vectorStore.similaritySearchWithScore(
  "光光和东东是怎么成为朋友的?", 
  3
);

// 步骤6: 上下文组装
const context = retrievedDocs
  .map((doc, index) => `[片段${index}]\n ${doc.pageContent}`)
  .join("\n\n-----\n\n");

const prompt = `
你是一个讲友情故事的老师。基于以下故事片段回答问题,用温暖生动的语言。
如果故事中没有提到,就说"这个故事里还没有提到这个细节"。

故事片段:
${context}

问题:${question}

老师的回答:`;

// 步骤7: 生成
const response = await model.invoke(prompt);

此代码范式的核心价值在于端到端的可观测性:每一阶段的输出均可打印检查,使得系统行为可解释、可调试。这是原型系统与生产系统共享的最佳工程实践。


二、检索引擎的工程原理

2.1 Retriever 与 VectorStore 的职责边界

代码中同时出现的两种检索方式,代表了不同的抽象层次:

维度 retriever.invoke() vectorStore.similaritySearchWithScore()
返回类型 Document[] [Document, number][]
处理管线 向量查询 + 去重 + 过滤 + 重排序 仅向量相似度计算
可配置性 kfiltersearchTypereranker 通常仅 kfilter
框架角色 LangChain 标准检索抽象层 VectorStore 底层 API
适用场景 生产环境标准检索流程 调试、调参、需要分数做决策的场景

2.2 检索器的内嵌处理管线

typescript 复制代码
// retriever.invoke() 的语义分解(伪代码)
async invoke(query: string): Promise<Document[]> {
  // 1. 查询向量化
  const queryVector = await this.embeddings.embedQuery(query);
  
  // 2. 向量检索(通常取 2k 候选,为后处理留余量)
  let candidates = await this.vectorStore.similaritySearchVectorWithScore(
    queryVector, 
    this.k * 2
  );
  
  // 3. 去重:相同内容仅保留一条(基于 pageContent 或 hash)
  candidates = this.deduplicate(candidates);
  
  // 4. 元数据过滤
  if (this.filter) {
    candidates = candidates.filter(item => 
      this.matchFilter(item.document.metadata, this.filter)
    );
  }
  
  // 5. 重排序(若配置了 reranker)
  if (this.reranker) {
    candidates = await this.reranker.rerank(query, candidates);
  }
  
  // 6. 截断并返回
  return candidates.slice(0, this.k).map(item => item.document);
}

核心认知similaritySearchWithScore 是检索器的底层实现,而非检索器的全部。Retriever 在向量相似度基础上叠加了去重、过滤和重排序三层后处理------这些才是决定检索质量的工程杠杆。

2.3 检索质量的三道防线

防线 机制 解决的问题
去重 基于内容哈希或文本相似度 同一长文档的多个相邻 chunk 同时被召回,浪费上下文窗口
元数据过滤 结构化条件筛选(时间、类型、部门等) 缩小搜索空间,提升精度
重排序 交叉编码器(cross-encoder)重新打分 向量检索的"近似"缺陷,通过精细模型修正

面试应答框架 :先阐明 retrieversimilaritySearch 的本质区别(抽象层 vs 实现层),再逐一展开后处理机制所解决的具体问题,最后归纳为"检索质量不是向量算得准,而是后处理做得全"。


三、相似度评分体系:从数值到决策

3.1 距离度量的数值语义

代码中出现的分数转换逻辑:

typescript 复制代码
const rawScore = scoredResult[1];          // 距离值(越小越相似)
const similarity = (1 - rawScore).toFixed(4); // 相似度(越大越相似)

该转换仅在余弦距离(值域 0, 2)下具有线性语义。不同距离度量的适用场景:

度量 公式 特性 适用场景
余弦相似度 cos⁡(θ)= A⋅B∥A∥∥B∥ \cos(\theta) = \frac{A \cdot B}{\|A\|\|B\|} cos(θ)=∥A∥∥B∥A⋅B 方向敏感,长度不敏感 文本语义检索(事实标准)
欧氏距离 ∥A−B∥2= ∑(Ai−Bi)2 \|A - B\|_2 = \sqrt{\sum (A_i - B_i)^2} ∥A−B∥2=∑(Ai−Bi)2 方向与长度均敏感 图像特征、坐标数据
点积 A⋅BA \cdot B A⋅B 方向与长度均敏感 已归一化向量的快速计算

对于文本嵌入,余弦相似度成为事实标准的原因在于:语义相近但长度不同的文本(如"我喜欢猫"与"我非常喜欢猫")在向量空间中的方向应趋近一致,而范数可能不同。余弦相似度通过归一化消除了长度的影响。

3.2 相似度阈值的工程决策

生产环境中,相似度分数是决策信号而非展示指标:

typescript 复制代码
interface ThresholdStrategy {
  minSimilarity: number;      // 阈值下界
  maxResults: number;         // 结果数量上界
  fallback: 'retry_lower' | 'direct_llm' | 'reject';
}

function filterByThreshold(
  scoredResults: [Document, number][], 
  strategy: ThresholdStrategy
) {
  const qualified = scoredResults.filter(
    ([, score]) => (1 - score) >= strategy.minSimilarity
  );
  
  if (qualified.length === 0) {
    switch (strategy.fallback) {
      case 'retry_lower':   // 降低阈值重试(动态调整)
      case 'direct_llm':    // 退化至无检索生成
      case 'reject':        // 返回"未找到相关信息"
    }
  }
  
  return qualified.slice(0, strategy.maxResults);
}

阈值确定的方法论

  1. 阈值没有通用数值,取决于嵌入模型、语料分布和业务容忍度
  2. 系统化方法:在标注测试集上绘制 Precision-Recall 曲线,选取 F1 最大化对应的阈值
  3. 分数分布监控:若所有查询的分数均低于阈值,可能提示嵌入模型与语料不匹配
  4. 相近分数处理:若 0.82、0.81、0.80 三个结果,应全部保留------分数接近说明相对相关性一致,丢弃任何一个都可能导致信息损失

四、元数据架构:检索质量的第二引擎

4.1 元数据在检索管线中的角色

元数据(metadata)不参与向量化计算,即不被送入嵌入模型。但其在检索流程中的作用体现在三个层面:

markdown 复制代码
                   向量检索阶段              后处理阶段                生成阶段
                       │                       │                       │
   metadata ───────────┼─────── 不可用 ────────┼─── 过滤、排序 ────────┼─── 溯源、引用
                       │                       │                       │
   pageContent ────────┴─── 向量化 → 相似度 ──┴───────────────────────┴─── 拼入 Prompt

4.2 元数据的三大工程用途

用途一:结构化过滤(Pre-retrieval / Post-retrieval Filter)

typescript 复制代码
// 检索时限定只搜索特定类型
const retriever = vectorStore.asRetriever({
  k: 3,
  filter: { type: "友情情节" }
});

// 后过滤:在检索结果中做二次筛选
const filtered = results.filter(doc => doc.metadata.mood === "欢乐");

在企业场景中,用户"只搜 2024 年的财务报告"这类需求,必须通过元数据过滤实现------向量检索无法理解时间范围的语义约束。

用途二:结果多样性与排序控制

typescript 复制代码
function diversifyByMetadata(docs: Document[]): Document[] {
  // 按章节排序,同时保证同一人物的结果不重复
  const sorted = [...docs].sort((a, b) => a.metadata.chapter - b.metadata.chapter);
  const seen = new Set<string>();
  return sorted.filter(doc => {
    const key = doc.metadata.character;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}

用途三:来源溯源与可解释性

typescript 复制代码
const contextWithSource = docs.map((doc, i) => 
  `[来源 ${i+1}] 章节 ${doc.metadata.chapter},角色:${doc.metadata.character}\n${doc.pageContent}`
).join("\n\n");

对于企业级应用,可溯源性不仅是用户体验问题,更可能是合规性要求。回答必须关联到具体文档、章节和版本。

4.3 元数据 Schema 设计原则

原则一:基于检索意图设计维度

分析用户群体的典型检索模式,反推所需字段:

  • 按时间检索 → 添加 date / year / timestamp
  • 按类型检索 → 添加 category / type
  • 按来源检索 → 添加 author / department / source

原则二:基于后处理逻辑设计维度

  • 需要时间排序 → 添加 timestamp
  • 需要重要性加权 → 添加 priority / weight
  • 需要引用展示 → 添加 title / url / page

原则三:克制的元数据设计

  • 每个字段必须有明确的使用场景
  • 能从 pageContent 中推断的信息不放入 metadata
  • 元数据膨胀会增加存储开销和维护复杂度

五、上下文窗口管理:增强阶段的资源配置

5.1 Top-k 值的决策模型

typescript 复制代码
const retriever = vectorStore.asRetriever({ k: 3 });

k 值选择并非经验常数,而应基于 Token 预算进行量化计算:

max_k≈ context_window−prompt_overhead−question_tokens−answer_budgetavg_chunk_tokens \text{max\_k} \approx \frac{\text{context\_window} - \text{prompt\_overhead} - \text{question\_tokens} - \text{answer\_budget}}{\text{avg\_chunk\_tokens}} max_k≈avg_chunk_tokenscontext_window−prompt_overhead−question_tokens−answer_budget

k 值 召回特性 适用场景
1-3 高精度,低召回 短文档、高精度需求、窄上下文
4-7 精度与召回均衡 通用场景
8-15 高召回,低精度 探索性查询、长文档、可容忍噪音

关键约束:检索质量随 k 增大而下降(边际召回递减,边际噪声递增),推理成本随上下文长度线性增长。实际生产中,建议总 Prompt Token 数不超过上下文窗口的 70%-75%,为生成预留空间。

5.2 Prompt 模板的工程结构

text 复制代码
[角色设定]     → 定义回答者身份、风格、知识边界
[行为约束]     → 定义回答格式、长度、语气
[安全边界]     → 防幻觉的最后防线:"未提及则说不确定"
[上下文分隔符]  → 结构化标记各检索片段的边界
[检索结果]      → 拼接的上下文片段(格式决定可用性)
[用户问题]      → 保持原样传递
[输出引导]      → 帮助模型进入回答状态

工程原则

  • 安全边界("未提及则说不确定")是防幻觉的最经济有效手段
  • 上下文需格式化(如 [片段0]\n...\n-----\n[片段1]),使模型能区分不同来源
  • 输出引导(如"回答:")可减少模型的前缀冗余输出

六、生产级组件选型框架

6.1 向量存储:内存方案 vs 持久化方案

维度 MemoryVectorStore 生产级向量数据库
数据持久性 进程生命周期内有效 磁盘持久化
规模上限 内存容量限制(约 10⁴-10⁵ 条) 10⁶-10⁹ 条
检索算法 暴力搜索 O(n) ANN 近似搜索 O(log n)
并发能力 单进程 多客户端并发
运维成本 需部署与维护

MemoryVectorStore 的价值在于快速验证:5 分钟内跑通全链路,无需依赖外部基础设施,降低学习曲线。

6.2 向量数据库选型决策矩阵

数据库 架构类型 核心优势 局限性 适用场景
Chroma 嵌入式 零配置,Python 原生 生产级功能有限 原型快速验证
Qdrant 独立服务 Rust 实现,过滤性能优异 需独立部署 中小规模生产
Milvus 分布式 云原生,十亿级规模 架构重,运维复杂 大规模生产
Weaviate 独立服务 GraphQL 接口,内置模块 资源消耗高 多模态场景
Pinecone SaaS 零运维,自动扩缩 成本高,数据出境 无基础设施预算
pgvector PostgreSQL 扩展 与业务库统一管理 大规模性能受限 已有 PostgreSQL 基础设施
Elasticsearch 搜索引擎 + 向量 关键词与向量混合检索 向量非原生能力 已有 ES 且需混合搜索

选型决策树

  1. 已有 PostgreSQL → pgvector(零额外运维)
  2. 需要关键词+向量混合检索 → Elasticsearch / Weaviate
  3. 小团队快速原型 → Chroma / Qdrant
  4. 亿级向量规模 → Milvus
  5. 完全托管需求 → Pinecone

6.3 嵌入模型选型因素

模型 维度 语言 特点
text-embedding-v4(Qwen) 1024 中英为主 中文效果优异,性价比高
text-embedding-3-small(OpenAI) 512/1536 多语言 维度可调,节省存储
text-embedding-3-large(OpenAI) 256/1024/3072 多语言 质量最高,成本最高
bge-large-zh(BAAI) 1024 中文为主 开源,可本地部署
m3e-base 768 中文 轻量级,适合小团队

选型要点

  1. 维度越高,表达能力越强,但存储与计算成本线性增长
  2. 数据出境合规要求 → 开源模型本地部署(bge / m3e)
  3. 需在目标语料上做实测评估------MTEB 榜单的 benchmark 不代表业务场景效果

6.4 缓存策略

typescript 复制代码
// 查询向量缓存(适用于重复查询较高的场景)
class EmbeddingCache {
  private cache: Map<string, number[]>;  // 生产环境使用 Redis
  
  async embed(query: string, embedder: Embeddings): Promise<number[]> {
    if (this.cache.has(query)) {
      return this.cache.get(query)!;
    }
    const vector = await embedder.embedQuery(query);
    this.cache.set(query, vector);
    return vector;
  }
}

写入时链路(文档向量化)只需执行一次,更新时增量处理。读取时链路中,高频查询的向量化结果可缓存,减少 API 调用成本。


七、高级检索模式

7.1 模式速览

模式 解决的问题 额外成本 成熟度
HyDE 问题与文档的语言风格差异 1 次 LLM 调用 成熟
Multi-hop 需多步推理的复杂问题 多次检索 + Agent 编排 成熟
Self-Querying 结构化约束 + 语义检索 1 次 LLM 调用 成熟
Parent Document 分块粒度与上下文完整性的矛盾 双倍存储 成熟
RAG-Fusion 单一查询的召回不足 N 次检索 + LLM 改写 较新

7.2 HyDE:假设性文档嵌入

核心思想:用户问题 → LLM 生成假设性回答 → 将假设回答向量化 → 用该向量做检索。

有效性原理:用户问题通常是简短的问句形式,知识库文档是陈述性长文本。问句与陈述句在向量空间中可能存在分布偏移------语义匹配但向量距离较远。HyDE 通过生成"伪文档"弥合了这一风格鸿沟。

成本:每次检索增加 1 次 LLM 调用,延迟上升。

7.3 Self-Querying 检索

核心思想:LLM 从自然语言问题中提取结构化过滤条件,同时执行向量检索和元数据过滤。

typescript 复制代码
// 用户输入: "光光在前几章里是什么性格?"
// LLM 解析输出:
{
  query: "光光的性格",
  filter: { 
    character: "光光", 
    chapter: { $lte: 3 } 
  }
}

此模式是元数据工程价值的最高体现------将自然语言的隐式约束转化为显式的结构化过滤。

7.4 Parent Document 检索

核心思想:检索时使用细粒度 chunk(高精度),生成时返回粗粒度父文档(完整上下文)。

复制代码
入库流程:
  父文档(大块)→ 切分为子块(小块)
  子块 → 向量化 → 建立索引
  子块 → 记录其所属父文档 ID

检索流程:
  用户查询 → 检索到相关子块 → 查询子块对应的父文档 → 返回父文档完整内容

该模式解决了 RAG 的核心矛盾:chunk 过小则上下文不完整,chunk 过大则检索精度下降。

7.5 RAG-Fusion:多查询融合

核心思想:LLM 将原始问题改写为多个视角的查询,分别检索,通过倒数排名融合(Reciprocal Rank Fusion, RRF)合并结果。

RRF 评分公式:

RRF(d)= ∑q∈Q 1 k+rankq(d) \text{RRF}(d) = \sum_{q \in Q} \frac{1}{k + \text{rank}_q(d)} RRF(d)=∑q∈Qk+rankq(d)1

其中 kk k 为平滑常数(通常为 60), rankq(d) \text{rank}_q(d) rankq(d) 为文档 dd d 在查询 qq q 结果中的排名。

解决的问题:单一查询因措辞偏差而漏召相关文档的多维度覆盖问题。


八、RAG 系统评估指标体系

8.1 离线评估指标

指标 定义 计算方式
MRR(Mean Reciprocal Rank) 第一个相关文档排名的倒数均值 1N ∑i=1N 1ranki \frac{1}{N}\sum_{i=1}^N \frac{1}{\text{rank}_i} N1∑i=1Nranki1
Hit Rate@K Top-K 结果中包含至少一个相关文档的比例 #queries with hit in top-KN \frac{\#\text{queries with hit in top-K}}{N} N#queries with hit in top-K
NDCG@K(Normalized Discounted Cumulative Gain) 考虑排序位置的累积增益 基于分级相关性标注的归一化折损累积增益
Recall@K Top-K 中相关文档占所有相关文档的比例 #relevant in top-K#total relevant \frac{\#\text{relevant in top-K}}{\#\text{total relevant}} #total relevant#relevant in top-K

8.2 端到端生成质量评估(RAGAS 框架)

指标 定义
Faithfulness 回答是否忠实于检索到的上下文(有无幻觉)
Answer Relevancy 回答与问题的相关性
Context Precision 检索上下文中相关文档的比例
Context Recall 检索上下文覆盖了标注答案所需信息的比例

8.3 在线评估

  • 用户行为信号:点赞/踩、回答采纳率、后续追问率
  • 系统指标:空结果率、平均响应延迟、Token 消耗量

九、面试应答框架

Q1:Retriever 和 VectorStore 的 similaritySearch 有什么区别?

应答框架

  1. 本质区别retriever 是 LangChain 的检索抽象层,similaritySearch 是 VectorStore 的底层实现
  2. 功能叠加:Retriever 在向量搜索基础上叠加去重、过滤、重排序
  3. 使用场景 :生产环境使用 Retriever 作为标准接口;调试调参时使用 similaritySearchWithScore 获取分数做阈值决策

Q2:如何确定 RAG 系统的检索质量?如何评估?

应答框架

  1. 离线评估:MRR、Hit Rate@K、NDCG@K、Recall@K,需要标注测试集
  2. 端到端评估:RAGAS 框架的 faithfulness、answer relevancy、context precision/recall
  3. 在线评估:用户反馈信号(点赞/踩)、回答采纳率
  4. 阈值确定:在标注集上绘制 Precision-Recall 曲线,选择 F1 最大化的阈值

Q3:生产环境选什么向量数据库?依据是什么?

应答框架

  1. 非独立答案:选型取决于现有基础设施、数据规模、运维能力
  2. 决策树:已有 PG → pgvector;需混合检索 → ES/Weaviate;小团队原型 → Chroma/Qdrant;亿级规模 → Milvus;完全托管 → Pinecone
  3. 核心权衡:运维成本 vs 性能上限 vs 功能完备性

Q4:RAG 和长上下文模型是什么关系?长上下文会取代 RAG 吗?

应答框架

  1. 互补而非替代:检索是信息过滤,上下文窗口是信息承载------不同层面的问题
  2. 长上下文的局限:延迟线性增长、成本线性增长、注意力稀释(Lost in the Middle 现象)
  3. RAG 的不可替代性:精准检索、低成本、可解释性(来源可追溯)
  4. 趋势判断:Long-Context RAG 是演进方向------用更大窗口容纳更多检索结果,但检索本身仍是必要的

结语:从 Demo 到生产的认知升级

v038v040 的技术递进,本质上是两个层面的认知跃迁:

v038 回答的是"RAG 是什么":

  • 幻觉是信息检索问题,而非模型缺陷
  • 向量语义检索优于关键词匹配
  • Document + metadata 是知识的基本单元

v040 回答的是"RAG 怎么做对":

  • 检索器 ≠ 向量查询,而是向量查询 + 去重 + 过滤 + 重排序
  • 相似度分数 ≠ 展示数值,而是决策信号------低于阈值的需丢弃
  • metadata ≠ 附属信息,而是检索质量的第二引擎
  • top_k ≠ 经验常数,而是 Token 预算管理的函数
  • 选型 ≠ 选最好的,而是选最适合现有基础设施的

RAG 不是"查一下然后问模型"。RAG 是一个以检索质量为核心的工程系统------检索的上限决定了生成的上限。七步链路(文档→向量化→存储→检索器→相似度→组装→生成)中的每一步都有其工程决策逻辑,而将这些决策串联为统一的技术故事线,才是从"会用"到"懂工程"的分水岭。


参考文献与进一步阅读

  1. Lewis et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. NeurIPS.
  2. RAGAS: Automated Evaluation of Retrieval Augmented Generation.
  3. LangChain Documentation: Retriever Interface & VectorStore API.
  4. MTEB: Massive Text Embedding Benchmark Leaderboard.
  5. Gao et al. (2023). Retrieval-Augmented Generation for Large Language Models: A Survey.
相关推荐
艾德克斯7 小时前
AI服务器电源POWER SHELF测试破局:HVDC高压架构挑战与ITECH全栈测试方案
人工智能·架构
山东云弈创峰科技10 小时前
山东云弈创峰:跨境电商AI自动化中的环境隔离与风控架构
人工智能·架构·自动化
鱼樱前端11 小时前
别再自己拼凑了!这款 Vue 3.5+ 严肃产品级组件库,把 AI 对话、工作流和复杂数据全包了!
javascript·vue.js·github
kyriewen13 小时前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
阿里嘎多学长13 小时前
2026-07-14 GitHub 热点项目精选
开发语言·程序员·github·代码托管
IpdataCloud14 小时前
跨区服玩家延迟高怎么办?用IP离线库自动分配到最近服务器
数据库·tcp/ip·github·php·ip
俞凡15 小时前
从战略到战术:真正能落地的软件设计方法论
架构
黄敬峰15 小时前
从零搭建 RAG 应用 —— 一个故事带你彻底搞懂检索增强生成
面试
物联网软硬件开发-轨物科技15 小时前
【轨物方案】从传感器到AI诊断:箱变智能化技术栈四层架构精讲
人工智能·架构