news 2026/8/31 11:34:24

基于Notebook的RAG实战指南:从零搭建检索增强生成知识库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Notebook的RAG实战指南:从零搭建检索增强生成知识库

有不少读者问我:想看一个能把 RAG 从零跑通的 Notebook 项目,而不是只看概念图。RAG 刚火的时候,大家关注的是“它是什么”,现在更多人关注的是“我的文档放进去,怎么才能真的搜得准、答得对”。

这篇文章就围绕一个RAG Refresher Notebook来展开。我会先讲清楚 RAG 的核心链路,再带你用一个 Jupyter Notebook 把整套流程完整跑一遍,包括文档加载、文本切分、向量化、检索、重排、生成回答。最后还会补充知识库指标的理解方式、常见报错排查,以及让 RAG 更精准的工程经验。

不管你是刚接触 RAG 的新手,还是已经搭过 demo 但效果不理想的开发者,这份笔记都值得收藏对照实践。

1. 为什么要用 Notebook 复现 RAG

1.1 RAG 是什么,解决什么问题

RAG 全称是 Retrieval-Augmented Generation,也就是“检索增强生成”。

通俗地说,大语言模型本身的知识有截止时间,也不知道你私有的业务文档。RAG 的思路是:在模型回答之前,先从你的知识库里把相关片段检索出来,再把这些片段和用户问题一起交给大模型,让模型基于检索到的内容组织答案。

典型流程如下:

用户问题 -> 文本向量化 -> 向量库检索 -> 召回相关片段 -> 拼接提示词 -> 大模型生成回答

RAG 解决的核心问题是:

  • 模型不知道你公司的制度、产品手册、私有 PDF 内容。
  • 模型知识有截止日期,无法回答最新信息。
  • 模型容易“一本正经地胡说八道”,RAG 用检索结果约束答案来源。
  • 相比重新训练模型,RAG 更新知识成本低得多,换一个文档就能更新知识。

1.2 为什么 Notebook 是复现 RAG 的好工具

Jupyter Notebook 最大的特点是“按单元格运行、结果留在页面里”。这对 RAG 学习非常有帮助。

举例来说:

  • 加载完文档后,你可以立刻打印前 500 个字,确认文档读对了。
  • 切分完文本后,可以打印几个 chunk,看切得是否合理。
  • 检索之后,可以把命中的文本打出来,人工判断“召回结果到底准不准”。
  • 最后再调用大模型生成回答,整个过程是透明的,每一步都能看到中间结果。

这种“逐步可视化”的调试方式,比直接写一个.py脚本跑完要好理解得多。所以我一直建议,做 RAG 原型验证阶段,优先用 Notebook,跑通了再工程化封装成服务。

1.3 这份 Notebook 会带你完成什么

这份RAG Refresher Notebook的目标不是做一个生产级系统,而是帮你把 RAG 的完整链路亲手实现一遍。

完成之后,你将掌握:

  • 文档加载与解析的常见方式。
  • 文本切分的原理和参数含义。
  • 使用开源 Embedding 模型做向量化。
  • 使用 Chroma 作为本地向量库。
  • 实现向量检索与简单的重排逻辑。
  • 调用大模型生成最终回答。
  • 理解 RAG 知识库评估指标。

2. 环境准备与工具链

2.1 Anaconda、Jupyter Notebook 和 Lab 怎么选

做 Python 数据类开发,Anaconda 是目前最省心的发行版。安装 Anaconda 后,自带的conda可以方便地创建虚拟环境。

很多新手会问:Jupyter Notebook 和 JupyterLab 到底有什么区别?

简单来说:

  • Jupyter Notebook 是经典的单文档交互界面,适合逐格运行代码。
  • JupyterLab 是新一代 IDE 风格界面,支持多标签、拖拽文件、终端、文件管理,功能更全面。
  • 两者底层内核一样,代码、.ipynb文件互相兼容。

如果你只是打开一个.ipynb快速运行,Notebook 够了。如果你要同时看文档、调代码、开终端,更推荐 JupyterLab。

在 Anaconda Prompt 中启动命令如下:

# 启动 Jupyter Notebook jupyter notebook # 启动 JupyterLab jupyter lab

2.2 创建虚拟环境并安装依赖

建议为 RAG 项目单独创建一个虚拟环境,避免依赖冲突。

conda create -n rag_notebook python=3.10 -y conda activate rag_notebook

然后安装依赖。这里需要注意版本,本示例以常见稳定版本为例,不同版本 API 可能有差异,请以你安装后的实际版本为准。

pip install jupyter pip install langchain langchain-community langchain-text-splitters langchain-huggingface pip install chromadb sentence-transformers pip install python-docx pypdf unstructured pip install openai

如果你的网络较慢,建议使用国内镜像源安装,例如:

pip install langchain chromadb sentence-transformers -i https://pypi.tuna.tsinghua.edu.cn/simple

2.3 Notebook 侧边栏标题总览

长 Notebook 写完后,右侧的“目录 / 大纲”视图非常有用。JupyterLab 默认有“Table of Contents”插件,可以点击左侧目录图标查看所有 Markdown 标题。

如果你使用的是 Jupyter Notebook 7,打开 Notebook 后,在视图菜单中开启“Show Table of Contents”即可。这样你可以像看文章目录一样,快速跳转到不同章节。

3. RAG 核心链路拆解

在写代码之前,先把 RAG 的每个环节拆开讲清楚。理解了每个环节的作用,后面看代码才不会晕。

3.1 文档加载与解析

RAG 的第一步是读取文档。文档可能是 PDF、Word、Markdown、HTML 或纯文本,不同格式需要不同的解析器。

常见文档加载器如下:

文档类型常用加载器说明
TXT / MarkdownTextLoader最简单,读成纯文本
PDFPyPDFLoader按页读取 PDF 文本
WordDocx2txtLoader读取 .docx
HTMLBSHTMLLoader解析 HTML 标签

这里最常见的坑是:PDF 解析出来的文本可能丢失结构。比如一份带标题层级、表格、多栏排版的 PDF,用 PyPDF 直接抽取,结果可能是混乱的。

如果你的文档是合同、技术规范等强结构文档,建议优先使用保留了标题结构的信息源。例如先把 PDF 转成 Markdown,或者使用 Unstructured 这类保留更多结构的工具。

3.2 文本切分

切分是为了让模型只关注相关片段。如果整篇文档都塞给模型,会超出上下文限制,也会引入大量噪声。

最常用的是递归字符切分器RecursiveCharacterTextSplitter。它的策略是:先用一个大的分隔符切,如果切出来的块还是太长,就换更小的分隔符继续切。

核心参数:

  • chunk_size:每个块的最大字符数。
  • chunk_overlap:相邻块之间的重叠字符数,避免关键信息正好被切在边界上。

举个例子:

from langchain_text_splitters import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, separators=["\n\n", "\n", "。", "!", "?", " ", ""] )

需要注意的是:中文的切分和英文不太一样。英文可以按空格切,中文更适合按句号、感叹号、问号等句子边界切。上面把中文标点加进了 separators,就是为了减少句子被硬切的风险。

3.3 向量化与向量库

向量化的作用是让文本变成计算机能计算相似度的数字数组。

你可以把 Embedding 模型理解为“翻译官”:它把一段文本映射成一个高维向量,语义相近的文本,向量距离也近。

常用的本地 Embedding 模型:

  • BAAI/bge-small-zh-v1.5
  • BAAI/bge-m3
  • shibing624/text2vec-base-chinese

使用开源模型的好处是数据不出内网,适合企业私有化场景。缺点是中文效果需要测试,不同模型差距很大。

在 Notebook 中加载 HuggingFace Embedding 模型:

from langchain_huggingface import HuggingFaceEmbeddings embeddings = HuggingFaceEmbeddings( model_name="BAAI/bge-small-zh-v1.5", encode_kwargs={"normalize_embeddings": True} )

normalize_embeddings=True表示对向量做归一化。归一化之后,用内积计算相似度等价于余弦相似度,这在用 Chroma 检索时更稳定。

向量库的作用是存储向量并提供相似度检索。Chroma 是一个非常适合做原型验证的轻量级向量库,支持本地持久化,不需要额外启动服务。

3.4 检索与重排

检索阶段,系统把用户问题也转成向量,然后在向量库中找到最相似的 Top K 个片段。

但向量检索不一定完美。可能出现两种问题:

  • 召回结果语义相关,但关键信息缺失。
  • 召回结果顺序不合理,真正有用的片段排在了后面。

这时候就需要重排(Rerank)。重排模型会结合“用户问题 + 候选文档”做更精细的匹配打分,把最相关的片段提到前面。

常见的重排模型有BAAI/bge-reranker-basebge-reranker-v2-m3等。

3.5 生成回答

最后一步是把检索到的文档片段和用户问题拼接成 Prompt,交给大模型。

一个简洁的 Prompt 模板如下:

你是一个知识库问答助手。请仅根据以下资料回答问题。 如果资料里没有相关内容,请直接回答“知识库中未找到相关信息”。 资料: {context} 问题:{question}

这里要注意:不要给模型太多自由发挥的空间。RAG 的核心价值是“有依据地回答”,如果 Prompt 中没有强调“仅根据资料回答”,模型很可能又用训练知识自由发挥,导致回答“看起来对但没依据”。

4. 完整实战:用 Notebook 搭建一个最小 RAG

下面我们会走进一个完整的 Notebook。建议你在本地按顺序创建新单元格运行,而不是一次性粘贴全部代码。

4.1 项目结构与准备数据

建议的项目目录如下:

rag_refresher_notebook/ ├── data/ │ └── rag_intro.txt ├── rag_refresher.ipynb └── requirements.txt

先手动创建一个data/rag_intro.txt,内容可以用你自己关心的文档,也可以先用下面的示例文本。我这里用一段非常短的 RAG 介绍举例,实际使用时换成你自己的业务文档即可。

RAG 全称是 Retrieval-Augmented Generation,即检索增强生成。 它的核心思想是在大语言模型生成回答之前,先从外部知识库中检索相关文本片段。 检索到的片段会和用户问题一起拼接到提示词中,用于约束模型回答的内容和范围。 RAG 适合解决私有知识问答、企业制度问答、产品手册问答等场景。 与重新训练模型相比,RAG 的优势是更新成本低、可解释性强、支持快速接入新知识。 传统 RAG 流程包括文档加载、文本切分、向量化、检索、重排和生成回答。 近年来,RAG 还发展出了 Agentic RAG、Graph RAG、多模态 RAG 等进阶形态。

4.2 初始化依赖与全局参数

在 Notebook 的第一个单元格中导入依赖,并设置全局参数。

import os from pathlib import Path from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma # 路径配置 BASE_DIR = Path(".") DATA_PATH = BASE_DIR / "data" / "rag_intro.txt" CHROMA_PATH = BASE_DIR / "chroma_db" # 切分参数 CHUNK_SIZE = 200 CHUNK_OVERLAP = 30 # 检索参数 TOP_K = 3 # Embedding 模型 EMBED_MODEL = "BAAI/bge-small-zh-v1.5" print("初始化完成")

需要注意的是,langchain_community在较新的langchain版本中已经被拆分出去,所以这里单独安装。如果你使用的是旧版 LangChain,导入路径可能是langchain.document_loaders,请根据你的版本调整。

4.3 文档加载与切分

# 1. 加载文档 loader = TextLoader(str(DATA_PATH), encoding="utf-8") documents = loader.load() print(f"加载到 {len(documents)} 个文档对象") print(documents[0].page_content[:200])

预期输出是文档前 200 个字。

接着做切分:

# 2. 切分文本 text_splitter = RecursiveCharacterTextSplitter( chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP, separators=["\n\n", "\n", "。", "!", "?", " ", ""] ) chunks = text_splitter.split_documents(documents) print(f"切分出 {len(chunks)} 个文本块") print("示例块:") print(chunks[0].page_content) print("---") print(chunks[1].page_content)

这里每个 chunk 都是一个Document对象,里面除了page_content,还有metadata。我们可以给每个 chunk 加上序号,方便后面追踪来源。

4.4 构建向量库

# 3. 初始化 Embedding 模型 embeddings = HuggingFaceEmbeddings( model_name=EMBED_MODEL, encode_kwargs={"normalize_embeddings": True} ) # 4. 生成向量库并持久化 vector_store = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory=str(CHROMA_PATH) ) print(f"向量库已创建,位置:{CHROMA_PATH}")

第一次运行需要下载 Embedding 模型,时间取决于网络状况。下载完成后,模型会缓存到本地,后续运行不需要重复下载。

如果你要重新构建向量库,建议先删除已有的chroma_db目录,避免旧数据和新增数据混在一起。

4.5 检索召回与答案生成

先做向量检索,看看检索结果是否合理。

query = "什么叫检索增强生成?" retriever = vector_store.as_retriever(search_kwargs={"k": TOP_K}) retrieved_docs = retriever.invoke(query) print(f"为问题检索到 {len(retrieved_docs)} 个相关块:\n") for i, doc in enumerate(retrieved_docs): print(f"--- 第 {i + 1} 个结果 ---") print(doc.page_content) print()

运行后,你应该能看到和问题语义相关的几个片段。

然后接入生成模型。这里以 OpenAI 兼容接口为例。如果你使用 OpenAI,直接配置官方 Key;如果你使用国内大模型服务,通常也提供 OpenAI 兼容的 HTTP 接口。

from langchain_openai import ChatOpenAI # 这里配置你的 API Key 和 Base URL # base_url 根据你的服务商调整 llm = ChatOpenAI( model="gpt-4o-mini", temperature=0.2, openai_api_key=os.getenv("OPENAI_API_KEY") ) def build_prompt(question: str, docs) -> str: context = "\n\n".join([doc.page_content for doc in docs]) prompt = f"""你是一个知识库问答助手。请仅根据以下资料回答问题。 如果资料中没有相关内容,请直接回答“知识库中未找到相关信息”。 资料: {context} 问题:{question} """ return prompt prompt = build_prompt(query, retrieved_docs) answer = llm.invoke(prompt) print("模型回答:") print(answer.content)

如果你的机器上没有大模型 API,也可以先跳过生成环节,只保留检索结果做人工判断。这一步不影响理解 RAG 前半段的工作。

4.6 运行效果与结果说明

整个 Notebook 运行完成后,你的输出流程大致如下:

加载到 1 个文档对象 切分出 7 个文本块 向量库已创建,位置:chroma_db 为问题检索到 3 个相关块: --- 第 1 个结果 --- RAG 全称是 Retrieval-Augmented Generation,即检索增强生成。 它的核心思想是在大语言模型生成回答之前,先从外部知识库中检索相关文本片段。 ... 模型回答: 检索增强生成(RAG)是一种在生成回答前先从外部知识库检索相关文本片段的技术。

到这里,一个最小的 RAG 链路就完全跑通了。

5. RAG 知识库的指标与评估

很多读者搭建完 RAG 后,觉得“效果时好时坏”,但说不清楚哪里差。这通常是因为缺少一套评估指标。

5.1 检索层指标

检索层关注的是“该搜出来的有没有搜出来”。

常用指标如下:

指标解释直观理解
Recall@K前 K 条结果中命中的相关文档数 / 总相关文档数该有的结果召回了几成
Precision@K前 K 条结果中相关文档占比召回的 K 条里有几条靠谱
Hit Rate@K前 K 条结果中是否至少有一个相关文档有没有命中一个关键答案
MRR第一个相关结果排在第几位,取倒数第一条有用结果出现得够不够早
NDCG@K考虑排序位置的折损累计增益排序顺序是否合理

这里最关键的是 Recall 和 MRR。Recall 低说明知识库内容被切碎或索引错了,MRR 低说明排序有问题,需要通过重排改善。

5.2 生成层指标

检索准不等于答案好。生成层主要看三个指标:

  • 忠实度(Faithfulness):生成内容是否严格依据检索到的资料,没有编造。
  • 答案相关性(Answer Relevance):回答是否针对用户提出的问题。
  • 上下文相关性(Context Relevance):检索到的上下文是否足够支撑回答。

这组指标可以从“主观感受”变成可量化的打分,通常做法是让一个更强的模型作为裁判,给生成结果逐项打分。

5.3 如何理解这些指标

在实际项目中,不要只看一个指标。我建议按以下顺序排查:

  1. 先看 Hit Rate 和 Recall:如果召回结果里压根没有正确答案,生成再强也没用。
  2. 再看 MRR 或 NDCG:如果答案在召回结果里,但排得很靠后,会导致上下文过长、噪声过多。
  3. 最后看忠实度:如果检索没问题但答案还是编造,问题出在 Prompt 或者说生成模型。

你可以用这种思路给自己的知识库做一次“体检”。

6. 如何让 RAG 更精准

很多人问“如何创建精准的 RAG”。答案不是某一个技巧,而是下面这几个环节的综合优化。

6.1 从源头控制文档质量

输入垃圾,输出垃圾。RAG 也一样。

  • 去掉页眉页脚、水印、导航栏等无关文本。
  • 保留标题层级,尽量使用 Markdown 或结构化数据。
  • 对 PDF 要人工抽样检查解析结果,尤其是表格。
  • 对协议类文档,比如 3GPP 规范或合同条款,要按条款编号保留结构,不要按固定字符数硬切。

如果你发现某个文档检索效果总是差,先检查原始解析结果,大概率是解析阶段就丢了信息。

6.2 混合检索与查询改写

纯向量检索对关键词不敏感。比如用户搜“怎么请假”,文档里写的是“休假流程”,向量相似度可能不够高。

改进思路有两种:

  • 混合检索:向量检索 + 关键词 BM25 检索,再把结果合并排序。
  • 查询改写:先让大模型把用户问题改写成更利于检索的形式,例如补全同义词、扩展专业术语。

例如用户问“工资什么时候发”,可以改写成“公司工资发放日期、工资发放规则、发薪日”。

6.3 Rerank 重排

重排是提升 RAG 效果性价比最高的手段之一。

先用向量库快速召回 20 条候选,再用重排模型精排,取前 3 条给大模型。这样可以兼顾召回率与精度。

Rerank 的伪代码如下:

# 假设候选文档已经在 candidates 中 # reranker 是重排模型 scores = reranker.score(question, candidates) top_results = sort_by_score(candidates, scores)[:3]

在 Notebook 中,你可以先打印重排前后的对比,直观感受重排模型的作用。

6.4 Agentic RAG 与 Ontology RAG

如果问题链比较复杂,比如“对比这两个产品的售后政策”,一次检索往往不够。

这时可以引入 Agentic RAG:让大模型像 agent 一样,根据问题拆解检索计划,多次检索,直到信息足够。常见实现是 LangGraph 中的多步检索节点。

另外还有 Ontology RAG,它提前定义好概念之间的关系,检索时不只找字面片段,还会顺着知识图谱关系找到相关内容。适合做企业知识体系比较复杂、实体关系密集的场景。

6.5 多模态 RAG 拓展

如果你的知识库里有大量图片、表格、流程图,纯文本 RAG 会丢失信息。

多模态 RAG 的思路是:

  • 使用多模态 Embedding 模型,将图片和文本统一向量化。
  • 或者先用视觉模型把图片内容转录为文字,再进入普通 RAG 流程。

第二种方案实现成本更低,目前也是很多项目的首选。

7. 常见问题与排查思路

在实际跑 RAG Notebook 时,有几个高频问题经常被问到。

7.1 Notebook 环境类问题

问题现象常见原因解决思路
Jupyter 无法启动conda 环境未激活先运行conda activate rag_notebook
找不到已安装的包Kernel 使用的 Python 不是当前环境在 Notebook 中运行import sys; sys.executable检查
代码能运行但报ModuleNotFoundError依赖装错了环境确认 pip install 和 Jupyter 在同一个环境
云 Notebook 长时间无操作断开空闲会话被回收定期运行简单代码保活,或分阶段保存结果

检查 Kernel 环境是最关键的一步。很多人明明pip list能看到包,但 Notebook 里导入失败,几乎都是 Kernel 环境没切换对。

7.2 中文切分与编码问题

问题现象常见原因解决思路
读取 TXT 出现乱码文件编码不是 UTF-8使用encoding="utf-8",必要时改为gbk
切分后句子被拦腰切断分隔符未包含中文标点separators 中加入 “。”、“!”、“?”
一个 chunk 全是空行原始文档有大量连续换行加载后先做文本清洗

中文切分目前没有一个万能方案。我的建议是:先按分隔符递归切,再人工打印前 20 个 chunk 检查。如果发现大量句子被截断,就应该调整chunk_overlap或分隔符。

7.3 检索效果差

问题现象常见原因解决思路
检索结果和问题完全无关Embedding 模型不适合领域换成效果更好的中文 Embedding 模型
相关结果排得太靠后向量检索不擅长精确关键词增加 BM25 混合检索,或加 Rerank
检索结果都是同一段文字切分太小导致重复片段调整 chunk_size,增加多样性
换成新文档后效果没变向量库没有重新构建删除 chroma_db 目录后重新生成

这里要特别提醒:每次修改切分参数或文档后,记得清空向量库目录再重建。Chroma 持久化通常只会新增,不会自动删除旧的分块,容易造成“老的脏数据还在影响结果”的问题。

8. 最佳实践与工程建议

8.1 用模块化方式组织 Notebook

一个 RAG Notebook 不要把所有代码堆在一个单元格里。建议按以下结构组织:

01 环境检查与依赖安装 02 文档加载与预览 03 文本清洗与切分 04 向量库构建 05 检索测试 06 重排测试 07 生成问答 08 效果评估

这样当你调试时,只需要重跑某个阶段的单元格,不用从头再来。

8.2 给 chunk 打上完整元数据

在构建向量库时,强烈建议保留每一条 chunk 的来源信息。

示例代码:

for i, chunk in enumerate(chunks): chunk.metadata["chunk_id"] = i chunk.metadata["source"] = str(DATA_PATH)

因为生产环境中,用户最终需要知道“这个答案出自哪份文档的哪个部分”。如果元数据里只有文本内容,后续审计和纠错都会很困难。

8.3 从原型到生产环境的注意事项

Notebook 跑通只是第一步。生产环境需要考虑更多内容:

  • 权限控制:不同角色只允许检索自己有权限的文档,通常通过元数据过滤实现。银行、医疗等敏感行业尤其重要。
  • 文档更新机制:新文档上线时,只删除并重建对应文档的向量,不要全库重建。
  • 监控与日志:记录每个问题的命中文档、Rerank 分数、模型回答,方便回溯分析。
  • 内容安全:对检索内容和生成结果做合规过滤,涉及敏感信息时要有脱敏和审计能力。
  • 评估闭环:建立一套评估集,每次修改切分策略、模型参数后,都跑一遍评估,用指标验证效果,而不是凭感觉。

8.4 合理选择 Embedding 模型与底座

不要迷信“最大最贵的模型”。对中文知识库场景,建议先在你的测试集上对比几个开源模型,选效果好、推理速度快的。

我见过不少项目,问题不在模型,而在文档解析。原始文档质量差,换再大的模型也救不回来。

9. 总结与下一步学习方向

到这里,这份RAG Refresher Notebook已经把 RAG 从文档加载到最终生成的完整链路走了一遍。你不仅看到了每个环节的代码,还理解了为什么要切分、为什么要向量化、为什么要加重排、如何用指标评估效果。

如果你想把 RAG 从“能跑”提升到“好用”,下一步可以重点研究这几块:

  • 混合检索与查询改写,解决长尾问题。
  • Rerank 模型引入,提升排序质量。
  • LangGraph 实现 Agentic RAG,处理多步复杂问题。
  • Graph RAG 或 Ontology RAG,处理强关系型知识。
  • 评估数据集建设,让每一项优化都可以量化。

希望这份笔记本能在你搭建 RAG 知识库时少走一些弯路。如果中途遇到报错,优先对照“常见问题与排查思路”一节,大部分环境类问题都出在依赖版本和 Kernel 环境上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 11:34:21

HyperMesh零基础入门:前处理与网格划分核心流程详解

大家平时做有限元分析,建模阶段最花时间的往往不是求解器设置,而是网格划分和模型清理。尤其是刚接触CAE的同学,拿到一个三维模型,不知道从哪下手,用哪款前处理工具,或者画出来的网格质量太差,一…

作者头像 李华
网站建设 2026/8/31 11:34:07

设计师也能用 Git?从版本控制到设计资产协作落地指南

设计师用 Git 听起来像是个伪需求:命令行、冲突合并、分支切来切去,哪一项都跟设计软件的操作习惯对不上。但 Show HN 上这个 "Git for Designers" 项目,思路不是把设计师硬拽进终端,而是把版本控制的核心逻辑搬到视觉化…

作者头像 李华
网站建设 2026/8/31 11:33:41

百度核心系统工程师笔试考点解析:操作系统、C++与分布式系统

1. 拿到这批题的第一眼:百度核心系统工程师到底在考什么 1.1 为什么会有“第二批”这种叫法 很多同学第一次看到“百度2019校招核心系统工程师笔试题(第二批)”这个标题时,第一反应是:这跟普通开发岗笔试题有什么区别…

作者头像 李华
网站建设 2026/8/31 11:30:41

基于Pytorch的对偶生成对抗网络图像去雾实践

简介:本资源是基于PyTorch实现的对偶生成对抗网络(Dual GAN)图像去雾项目,面向计算机视觉方向本科生及研究生,特别适用于毕业设计、课程设计与深度学习实战训练。项目完整复现了端到端雾霾图像恢复流程,涵盖…

作者头像 李华
网站建设 2026/8/31 11:29:48

AI一句话生成量化策略:提示词工程+Python回测实战

很多人听到“量化交易”四个字,第一反应是数学、编程、金融三座大山压过来。但最近一段时间,AI 辅助编程工具越来越成熟,一个很现实的变化是:策略模板、技术指标、甚至提示词本身,都可以让 AI 来写,人只需要…

作者头像 李华
网站建设 2026/8/31 11:28:41

金融科技研发岗笔试全解析:从算法到业务场景的备考指南

又到一年秋招季,后台不少朋友在问金融科技公司的研发岗笔试到底怎么准备。翻资料的时候正好看到了这份度小满2019秋招研发岗试卷,虽然年份有点久,但里面考察的知识点结构、出题思路,放到今天依然很有参考价值。金融科技公司的笔试…

作者头像 李华