惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
Scott Helme
Scott Helme
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
罗磊的独立博客
MyScale Blog
MyScale Blog
博客园 - 【当耐特】
L
LangChain Blog
AWS News Blog
AWS News Blog
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
T
True Tiger Recordings
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
月光博客
月光博客
The Hacker News
The Hacker News
L
Lohrmann on Cybersecurity
The GitHub Blog
The GitHub Blog
Stack Overflow Blog
Stack Overflow Blog
S
SegmentFault 最新的问题
Recorded Future
Recorded Future
S
Security Archives - TechRepublic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
Y
Y Combinator Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
博客园 - 聂微东
GbyAI
GbyAI
N
News and Events Feed by Topic
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
Last Week in AI
Last Week in AI
博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
A
About on SuperTechFans
K
Kaspersky official blog
NISL@THU
NISL@THU
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX - 技术

V2EX

[AI Agent 智能体] 为什么我觉得 AI 真正的机会在“数字员工” 我自己感觉 codex 极大的扩展了个人的能力者不用说,但是用多了似乎也会有更多精神问题 把 10.8GB vLLM 镜像的 Pod Ready 从 4m35s 降到 14s: Hermes + SOCI lazy loading 实测 [程序员] 免费共享自己的 token 给大家一起用 极豹代理注册送 500M 动态住宅流量 静态住宅 3 刀起 [Codex] 好像没有人说 ChatGPT 账户登录的 Codex,不支持 GPT-5.3 Codex、GPT-5.4 等模型了 有没有一种工作能每天稳定收入 10-50 元 [分享创造] 谁还记得 K-MeleonCCF 网页浏览器 [分享发现] 从 0 开始 vibe coding,产品上线一个月 1500+用户,我对用户增长的一些思考 [Windows] 卡巴斯基安全软件和卡巴斯基标准版选择哪个? [程序员] 做了一个本地音频处理 + 伪知识库应用,强依赖本地 ASR 模型,这种项目开源有意义吗? [Linux] 国产 Touchpad 在 arch 下偶发无法用手势 [问与答] 有老哥用 Portainer 吗? webhook 调用成功但是没有重新部署,哪位有经验? [问与答] 现在比较可靠的国外手机卡选哪家? [路由器] MikroTik RB5009 在 2026 是否还值得入手 [硬件] 外置硬盘有什么散热的好方案,太热了 OpenCode 的压缩算法有建议的兄弟们吗?主要是写 LaTeX 论文。 今年 618 是凉了吗 现在各类所谓戒网瘾机构真的太吓人了. 芒果 TV 好像在送免费的 glm 5.1 和 ds v4? 有大佬知道开了 ChatGPT plus 年费的情况下,可以再升级成 pro 吗?想只升级一个月用用 [分享创造] [分享创造] 做了一个纯本地的加密日记本,已上架 Google Play android 大佬们,有什么隐藏开发者 usb 调试的方案吗? [Visual Studio Code] VSCode 1.122.0 可以离线使用 BYOK 分析下“女生拒绝你,却还和你保持联系”这种现象 [宽带症候群] 部分机场拦截 SSL 连接,导致很多非浏览器软件的代理链路残废 [推广] [DDShub.cc]呆呆兽 Claude/CodeX 中转站,内含免费测试金 [程序员] 个人 side project 的设计工具用什么 今天 CPA 升级到 7.1.25 Codex free 只有 4 个模型了, gpt-5.5 还在,大家是不是这样? mimo 昨天重置之后为什么现在这么慢,是我的错觉吗 AI 编程是否是一种无效内卷? 做了个 Chrome 插件 DemoAlias,录 demo 时一键替换敏感数据 [Pixel] 想要入手个带一个 Sim 卡的 pixel10 在那块买更好 觉得现在入手合适吗 Mac pro M1 磁盘扩容问题 小米 mimo 模式是不是挂了,现在无应答了 Gemini 最近是降智了吗? 3.5 快是快但是回答的质量变差了 [程序员] 祝贺我司,月收入突破万刀~ [分享发现] [翻译] 为什么我要用 C# 构建数据库引擎 [分享创造] 使用 Skills 结合 NotebookLM 一人运营十个视频号 用 AI 如何做出好看的前端页面? 记一次令我非常无语的面试 [分享创造] GEO Wiki: 一个面向生成式引擎优化的百科全书 [分享发现] 哪位友友有滴滴 V8 [问与答] 有没有听力不太好,用苹果 air pod 的 [分享创造] Obsidian-Extensions-Activity 0.2 - 更好用的三方插件管理工具 《HelloGitHub》第 122 期 有没有阿里云的大佬,来说说这是真的,还是销售吹的? [Android] 看到 k80 可以解锁了 原来大型活动和人流量较多的地方有警察执勤并不是中国特色 [开源实时数字人] 商业级部署演示! 同时我们消费级卡的部署链路已经通啦,欢迎提意见~ [问与答] AI 搜索互联网资讯有啥好用的接口没? [副业] 跟风开了一个自助洗车店 [macOS] Mac 盖上盖子使用之后,每次开屏屏幕会花,这个是硬件问题还是驱动问题呢? 闪电藤即将下线,虾传正式上线 [DeepSeek] 今天 deepseek 崩了吗 codex 土区的 plus,能改成美区的 pro 吗,会触发手机验证吗 大家用过 Qwen3.7-Max 吗,说是比 GLM5.1, KIMI2.6 还强,真的假的? anthropic 既然如此抵触 cn,但是多国语言又提供简体中文? [程序员] 英语学了几十年,还是听不懂说不出,大家都是怎么练听说的? [问与答] 感觉有点 ai 阳痿了,话说你们都用 ai 做了啥 分享一个我做的 Apple Watch 独立游戏——30 秒打地鼠 [OpenAI] 有时候感觉言出法随比使用 superpowers 更方便快捷 [问与答] 有没有云南的?昆明彩礼一般多少啊? [生活] 我的无奈,我很想她,但是这不再可能 朋友用美国身份注册了 claude 账号,在国内使用会被封吗 [职场话题] 北京裁员赔偿上限是多少啊 [推广] 做了一个 AI 中转站 Lumi,新用户可免费订阅,每周送 2 元额度 17PM 7999 PDD、淘宝百亿补贴 [问与答] 我的 codex app 为什么这样? [分享创造] 无聊开发了一个蚊子白噪音助眠小程序,适合烦朋友 [程序员] Cursor 滞销了, 60 刀套餐回归玩家首月给 70% off [Wunder] edge.v2ex.com/chat 20260527 功能更新 [问与答] 寻找 image2,香蕉, seedance2 的 api; 取精室是怎么个流程?取不出来怎么办? opencode go 里的 mimov2.5 系列额度涨了 [酷工作] Crypto CEX 诚聘 AI 测试工程师 薪水 20K-30K RMB 纯远程办公 [生活] 你有给自己买什么商业保险吗,或者说有必要买商业保险吗 claude 发的这句话啥意思,说我问的多了吗 Quantumult X 又更新了 配置优化更新了一下 [问与答] 不知道是不是错觉, typeless 在 Macbook 上的耗电感觉有点快 老婆送了我个 iPhone17 Pro Max 1T,但我更舍不得我的 iPhone13 巨魔 福利: 4 个住宅 IP 兑换码,新用户专享 mac 笔记本 500G,开发用,现在没有储存空间了怎么办 是否存在港卡以外的其他选择?比如东南亚各国? DigVPS 测评 - 100TB 新增美国 Los Angeles - Global Tier1 产品:这应该是 Y 系第一个美国产品?限量九折优惠中。 [程序员] OpenCode x MiMo V2.5 - 限时免费 现在的你有哪些骄傲和无奈呢 香港金管局:就内地投资者投资账户新增三项监管措施 开户核查倒查至 2023 年 1 月 做了个 macOS 网站与应用拦截器, 保持专注. [小米] 有没有安卓玩机高手请教点问题 我发现 it 类工作者是最严重的性压抑群体 包括我自己 it 类的工作者 [开源] 高阶魔方一键求解器 Cursor 还能买吗, 20 刀和 60 刀的大概能用多久? ai studio 被疯狂封 api 怎么回事 Zerolang 好像还没人讨论? [问与答] token 用量究竟是怎么算的? 香港众安银行开户返 300HKD+50USD 英伟达股票兑换券 活动时间 5.28 日至 7.1 日截止。 vibe coding 了个辅助颈腰椎病康复的体态相机小工具 有在用免费 VPS 的吗?可以当梯子用吗? 这个 sechub 网站搬运了很多 V 站的内容,站方能管到它吗
咱 web 端也能跑本地知识库,RAG(傲娇)-篇章 2-数据预处理与匹配结果优化
doujiangjiyaozha · 2025-05-17 · via V2EX

众所周知,RAG 最基本的流程是:

数据处理 → 向量化 → 存储 → 匹配文本 → 结果优化 → 最终的匹配结果

其中,数据预处理与匹配结果优化尤为重要。

1. 数据预处理:文本分块( Chunking )

在处理一篇长篇幅的文章时,通常需要将整个文本切分为多个小块,每个小块分别向量化后再存储。

拆分块的重要性

如果分块方式不合理,可能会导致无法命中真正相关的内容。因此,合理的分块策略至关重要。

如何拆分?

看这里:

👉 Text Splitters Overview - LangChain

  • 文章类型数据:推荐使用 Text-structured
  • HTML 等结构化标签类型:推荐使用 Document-structured

2. 弥补 RAG 匹配缺陷:大小块 + 关键词索引

即使文本被拆成多个块,匹配结果依旧可能不准确。因为 RAG 本身存在局限性:若问题与任何文本块都不相关,匹配效果自然不佳。

优化方案:参考 Danswer 架构

简单来说,就是将文本拆分成不同大小的块再配上关键词索引

  • 大块文本:提高语义层面的相关性
  • 小块文本 + 关键词索引:提高细节命中率

小块可以提供更多细节,但也可能带来噪音信息。


3. 匹配结果优化

多维度匹配后可能得到大量候选文本,因此需要做进一步排序:

  1. 基于向量匹配与关键词匹配的分数加权排序
  2. 使用轻量级的 rerank 模型
  3. 最终形成一组合理的匹配文本

4. Web 端落地(纯浏览器端)

文本块处理

import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters"

const getBaseTextRecursiveSplitter = () => {
    const bigSplitter = new RecursiveCharacterTextSplitter({
        chunkSize: SPLITTER_BIG_CHUNK_SIZE,
        chunkOverlap: SPLITTER_BIG_CHUNK_OVERLAP,
        separators: SPLITTER_SEPARATORS
    });

    const miniSplitter = new RecursiveCharacterTextSplitter({
        chunkSize: SPLITTER_MINI_CHUNK_SIZE,
        chunkOverlap: SPLITTER_MINI_CHUNK_OVERLAP,
        separators: SPLITTER_SEPARATORS
    });

    return {
        bigSplitter,
        miniSplitter
    }
}

推荐参数配置

// split chunk relate
export const SPLITTER_BIG_CHUNK_SIZE = 1000; // 大块字符数
export const SPLITTER_BIG_CHUNK_OVERLAP = 200; // 大块重叠字符数
export const SPLITTER_MINI_CHUNK_SIZE = 150; // 小块字符数
export const SPLITTER_MINI_CHUNK_OVERLAP = 30; // 小块重叠字符数
export const SPLITTER_SEPARATORS = ["\n\n", "\n", "。", ";", ",", " ", ""]


关键词索引

使用 lunr.js + jieba(处理中文更优)


匹配结果的优化

考虑到运行在客户端的性能问题没使用 rerank 模型,仅通过加权与归一化排序处理并优化了一点打分逻辑

参考代码如下:

let [lshRes, fullIndexResFromDB] = await Promise.all([
    searchLshIndex(),
    searchFullTextIndex(),
]) as [Search.LshItemRes[], lunr.Index.Result[]]

// 向量匹配排序
const sortedLshRes = lshRes.sort((a, b) => b.similarity - a.similarity)
                           .slice(0, config.SEARCH_RESULT_HEADER_SLICE_SIZE)

// 全文匹配排序
const sortedFullIndexResFromDB = fullIndexResFromDB.sort((a, b) => b.score - a.score)
                                                   .slice(0, config.SEARCH_RESULT_HEADER_SLICE_SIZE)

// 重新打分、归一化
await FullTextIndex.loadJieBa()
const fullIndexFromDBTextChunkRes = await store.getBatch({
    storeName: constant.TEXT_CHUNK_STORE_NAME,
    keys: sortedFullIndexResFromDB.map((item) => Number(item.ref))
})

FullTextIndex.add([{ field: 'text' }], fullIndexFromDBTextChunkRes.map(item => ({
    id: item.id,
    text: item.text
})))

let newFullIndexRes = FullTextIndex.search(question)
newFullIndexRes = newFullIndexRes.sort((a, b) => b.score - a.score)
const maxScore = newFullIndexRes[0]?.score || 1
const reRankFullIndexRes = newFullIndexRes.map(item => ({
    ...item,
    score: item.score / maxScore
}))

// 合并向量和关键词匹配结果
let mixIndexSearchedRes: { id: number, score: number }[] = []
const vectorWeight = config.SEARCHED_VECTOR_WEIGHT
const fullTextWeight = config.SEARCHED_FULL_TEXT_WEIGHT

sortedLshRes.forEach(lshItem => {
    const match = reRankFullIndexRes.find(item => Number(item.ref) === lshItem.id)
    if (match) {
        mixIndexSearchedRes.push({
            id: lshItem.id,
            score: lshItem.similarity * vectorWeight + match.score * fullTextWeight
        })
    } else {
        mixIndexSearchedRes.push({
            id: lshItem.id,
            score: lshItem.similarity
        })
    }
})

// 补充关键词匹配的尾部数据
const lshTailStartIndex = Math.floor(vectorWeight * sortedLshRes.length)
const lshTailMaxScore = sortedLshRes.slice(lshTailStartIndex)?.[0]?.similarity || 1

reRankFullIndexRes.forEach(item => {
    if (!mixIndexSearchedRes.find(i => i.id === Number(item.ref))) {
        mixIndexSearchedRes.push({
            id: Number(item.ref),
            score: item.score * lshTailMaxScore
        })
    }
})

mixIndexSearchedRes = mixIndexSearchedRes
    .sort((a, b) => b.score - a.score)
    .filter(item => item.score > config.SEARCH_SCORE_THRESHOLD)

啥,你觉得这一套不靠谱,看下面!!!

成果

代码已开源(有帮助的话来个 star 吧)

github.com/Yoan98/Ncurator

想看实际演示?这里

www.ncurator.com

有啥能证明这个玩意靠谱呢?这里

1.上了阮一峰的周刊 科技爱好者周刊(第 337 期):互联网创业几乎没了

2.上了 DeepSeek 的集成推荐 https://github.com/deepseek-ai/awesome-deepseek-integration