几个 AI 插件 Text Generator, Smart Connections, Copilot 的简单调查

目的: 2024年了, 重新整理一下几个 AI 类插件的功能特点, 分别擅长干啥事, 讨论在笔记库里做向量搜索是不是好主意

测试了三个目前仍持续更新的 AI 类插件, 简单总结如下


Text Generator

这个插件功能侧重 写 和 改写, 也是少数几个没侧栏对话框, 而是直接从笔记正文界面操作文字的

特点

支持自定义模型, 意味着也可以用国内的模型 (最好是跟 OpenAI 的请求格式兼容的)

无论 OpenAI 家的模型还是自定义模型, 都可以改请求格式和应答格式的所有参数 (其他插件顶多让调个温度啥的)

可能是唯一支持在笔记里写一半它给自动补全下一句的插件 (类似于邮件或代码自动补全工具那种方式)

可以写复杂的 prompt 模板 Handlebar Templates - Text Generator Plugin

问题

  • 定位有点跟 Templater 重复了, 理论上 Obsidian Templater 写个 http request 也可以调各种语言模型 (当然 Text Generator 交互细节更好)
  • 需要折腾以满足个性要求
  • 需要持续维护的模板社区, 需要教程

Smart Connections

这个插件特点是全库的向量索引和关联查询

特点

几个重要功能

对话: 符合 Ob 使用习惯, 可以这么写 根据 [[xxx_note]] 和 [[yyy_note]] 回答, 俩文章的观点有啥不同?

关联笔记推荐: 要先做向量嵌入, 关联推荐的颗粒度可以精确到笔记的小标题级, 即 “推荐跟当前主题有关的, 其他笔记的具体某个章节”

全部笔记做为知识库的检索: 要先做向量嵌入, 之后以自指词 “I, me, my, mine, we” 提问时会触发, AI 回答时会有 “Base on your notes…” 字样

问题

  • 不支持自定义模型, 现在只有经典 OpenAI 全家桶, 支持别家模型不知得等啥时候
  • bug 还是比较多
  • 中文支持差
  • 没找到免费的, 适合中文的, 运行在本地的嵌入模型

Copilot

这插件理论上可离线使用, 是一套完整的向量搜索 + 问答的本地方案

特点

支持本地模型部署 (LM Studio, Ollama) Mistral 7B, Mistral 8x7B 都在 Ollama 里面

界面设计也挺不错

对话支持 Long Note QA 和 Vault QA (dev), 总计三种模式:

  • Chat: 跟别家一样没啥特别的, 不需要做文本嵌入
  • Long Note QA: 单笔记做文本嵌入, 根据关联的片段回答用户问题
  • Vault QA: 同上, 但它是全库文本嵌入和对话

问题

嵌入+搜索部分还不太完善
对话部分跟别家的差不多


过程中我自己遇到的问题


问: 这些插件都需要付费吗

看选啥模型

在线模型一般是通过 “指定 api_url + api_key + model_name 的方式” 用, 这些大部分是付费的

在线模型也有免费的, 尤其国内各平台都处在招新期, 许多都有限时免费

有的模型可以本地部署, 例如 Copilot 可以本地部署 Mistral 7b, smart-connections 的嵌入模型可设为 “跑在 transformer.js 上用本机硬件计算”

注:
若为节省成本而折腾本地模型, 可能还不如用平台的划算
本地模型主要还是出于隐私和离线使用的考量


问: 文本嵌入 / 向量搜索 是啥意思, 能干啥?

  • 文本嵌入 : 一段文本, 交模型处理后返回一串数字 (向量), 这串数字记录着文本的 “语义信息”
  • 向量数据库 : 把许多文本都这么处理, 就得到一个数据库, 两个向量夹角小, 就代表两段文本的含义接近
  • 向量搜索 : 现在有一段新文本, 也同样把它变成一串数字, 跟所有向量比对一下夹角, 就可知道新文本跟原先哪个笔记的语义最相似

能干啥? 对话时从知识库里自动取最相关的几条笔记, 跟你的问题一块发给聊天模型, 增强回答的效果; 以及自动为当前笔记推荐近似笔记


问: 模型太多挑花眼, 推荐几个好用的?

我也在琢磨该怎么搭配

对话模型

  • 我用的是 ChatGPT3.5 … (本文写于 2024年3月)
  • 我正在试 Moonshot.ai 很厉害, 快, 聪明, API 调用有免费额度, 接口跟 OpenAI 家一摸一样

嵌入模型

  • 我用的是 text-embedding-3-small, 便宜, 快, 效果好
  • 而在本地运行的 Jina 系列, 效果差了点, 保护隐私可以用

至于公正, 科学, 详尽的 LLMs 能力测试,
有个 Chatbot Arena 项目 (魔型斗蛐蛐, 欢乐每一期)

希望也有个对嵌入模型的类似的对比网站, 没找到


问: 我仓库笔记多, 全做文本嵌入能行吗? 这要花多少 tokens / 钱

token 可以理解为机器能识别的 “字”, 文本里的字符转换 token 按照:

  • 英文笔记大约 1单词 = 1token 粗略估计
  • 中文笔记大约 1汉字 = 1token 粗略估计

模型平台按 token 收费:

  • text-embedding-3-small 是 0.02刀 / 1m tokens
  • 阿里云 灵积 通用文本向量 是 免费 500000 tokens 之后 0.7元 / 1m tokens

最后本地文本的体积和字符数的数据是:

  • 以 utf-8 存档的 3mb 纯文本, 大约一百万字

嵌入整个仓库笔记要花多少钱? 可根据以上数据大致估算

TIP1 给个例子《红楼梦》120回版, 总字数约90万, 使用 text-embedding-3-small 做嵌入, 总计花费约两毛钱

TIP2 (对于 smart-connections) 建议先在 Obsidian 小仓库测试, 先了解插件大致是怎么个用法, 啥时会对全库做嵌入, 啥时只做当前笔记的嵌入, 只要不是频繁全库做嵌入, 一般成本能接受

TIP3 (对于 smart-connections) 插件设置里, 可以一次添加所有子目录到黑名单, 先全给添了, 一点点把需要做嵌入的笔记放出来


问: 我数据会被上传吗?

道理跟 “付费” 那一节类似

A 数据留在本地:

  • 嵌入模型里 Jina-v2-small-xxK 系列, 是 transformers.js 在本地硬件算的
  • 对话模型的能本地部署的那几个, Ollama Mistral 7b 等

B 数据上传远端, 但远端也归自己控制:

  • 例如私有化部署的大模型

C 数据会上传给服务方:

  • 所有 OpenAI 家的服务 (即 ChatGPT, 以及 OpenAI 提供的 embedding)
  • 第三方代理 ChatGPT, 卖 key 的商家
  • 国内 AI 平台: moonshot.ai, 腾讯云混元, 阿里云灵积, 千帆, …

问: 文本嵌入和搜索, 用在笔记库里真是好主意吗?

这是写这文章的初衷

文本嵌入后可以做两个事, 给当前笔记推荐关联笔记, 问答时先召回关联片段然后一起发给 LLMs 实现更智能的知识搜索

目前我的理解是:

  • 对于已经很熟悉的领域: 推荐关联笔记价值没那么大
  • 对于需要快速拓展知识的领域: 推荐关联笔记是好主意, 即使仅为 surprise 也是有用的
  • 对于熟或不熟的领域, “结合自己笔记知识的搜索” 都是好主意, 问题想把它做完善了非常难
  • 希望 “自然语言查询” 能帮我做到 “传统搜索搞不定的事”: 目前我看悬, 未来应该行
  • 为啥在 Obsidian 里面 做这事? 找典型的向量检索知识库工具不好吗: 那就更加折腾了, 且知识库侧重 “用”, 问题是我除了 “用” 还得 “写和改”
  • 普通的向量检索知识库工具 + Obsidian 插件做为知识库 client 不好吗: 这可能是未来的方向, 例如 Khoj 等工具, 感觉要再观望一下

以上看法不太成熟, 欢迎大家讨论

也推荐大家看看 GPT 配合文本向量搜索 参考其中观点


问: 想要个简单省事的 Obsidian AI 插件

最方便的是 Custom Frames + 任何网页版的大模型

这能避免大部分折腾
且网页版存着历史聊天记录, 相当于自带同步


问: 想要个功能强大, 默认搭配能上手, 定制以后上限高, 支持国内模型, 且免费和保护隐私的插件

呃…

目前谨慎看好 Smart Connections, 但它还得再完善些, 自定义模型得加上, 严重 bug 改改, 界面优化一下, 学点 RAG 的常见技巧, 才好用


暂且写到这里, 找到好的资料我再补充, 欢迎大家交流

8 个赞

再推三个能本地部署的但都没向量数据库的, 其中就copilot要额外配置跨域.本地部署要注意localhost/127.0.0.1不能互换这种bug…我是觉得copilot最好用.
chatCBT是已经有了固定prompt的针对日记的.
BMOchat的侧边栏比例做的很难看但能用.
localGPT甚至没有按键, 但promt定制好一点

1 个赞

在推一个smart second brain. 库提问是最好用的. copilot的库提问还是个智障

感谢分享, 看了一下:


再次感谢推荐, 我应该花时间仔细试试这些

1 个赞

效果不好现在我发现不只是插件的问题。不只是这些列举的插件,我自己本地还装了一些其他的,比如说anythingLlm这种我发现效果其实都不太好。原因我只能暂时归因于本地模型的能力还不太够。哪怕我现在16G显存用的是14B的参数去运行, 72B这种个人机器太大参数跑着实在吃力.
具体表现是,比如我读取本地的日记数据库。来询问。“我是怎么样的人?我提过多少次我的居住环境”, 这些效果都不太好,以及"我在哪些笔记中提到过地名"这种回溯功能。

我最近开发了 智谱AI的插件,可以在市场搜索“AI zhipu”。我也在考虑如何加入向量知识库功能。

我最近也做了些调查

我觉得 “效果其实都不太好” 除了 LLM 能力, 也跟 embedding 的质量有关, 后者是 “基建”, 如果 取不到 / 取错了 知识片段, 或排序不好, 那交给再强的 LLMs 去做问答也没戏


找到了 MTEB: Massive Text Embedding Benchmark 这是专门对向量嵌入的评测

已有评分在


我做了下功课, 目前个人理解, 至少要在 Retrival 和 Re-Ranking 这两项任务上取得高评分的嵌入模型, 才好用

  • Retrival : 不仅考虑精准率, 召回率, 还得考虑段落排序质量, 指标 NDCG@k 见推广搜
  • Re-Ranking : 重排, 对取回的段落 (这时全都是语义相关的), 根据用户意图踢掉无效的知识, 指标 MAP

此外, max-tokens 不能太短, 至少 1024 吧


目前打算按照这些需求找找合适的模型, 重新实验看看

此外发现, 在 Ob 里调查这类工具的性能, 也受限于 “中间过程太隐晦” 的障碍
最好是插件们把每一步做了啥, 每个片段都是啥, 记录清楚了才好
感觉那个 Text Generator 的 playground 就不错, 它把 “将发给 LLMs 的 prompt” 给完整打印了, 方便用户调试

Ob 里搞 RAG 任务, 更复杂了, 我感觉需要更详尽的 log 才好分析

2 个赞

TIP2 (对于 smart-connections) 建议先在 Obsidian 小仓库测试, 先了解插件大致是怎么个用法, 啥时会对全库做嵌入, 啥时只做当前笔记的嵌入, 只要不是频繁全库做嵌入, 一般成本能接受。

这个提示有什么细节分享吗?用了api,500w字的库,30块钱快没了,每次都全库搞一遍,有点发毛。

SmartConn 目前应该是只支持 OpenAI 家的嵌入, 按照最贵的方式:

  • text-embedding-3-large 此时 1刀 = 9,615 pages * 800 tokens per page
  • 500w中文字, 保守折合成 1000w tokens

那么应该是约 1.4 刀, 如果是第三方 API 那还得贵点

“30块钱快没了” 若全是在整个嵌入里用掉的, 那估计是 SmartConn 给全库反复做了嵌入… 似乎之前有阵子, 好多人提类似 issue, 我觉得我也遭遇过…


个人经验, 除了之前提到的, 还有

  • 不要随便 Refresh Notes
  • 选定嵌入模型后, 就不要随便换了, 这会导致重新加载本地那个 “记录嵌入向量的超大 json” 但有时它加载不了, 如果把 Ob 弄挂了, 重启后那数据可就不定啥情况了
  • 结合外部编辑器时, 注意关闭类似 Linter 类功能, 类似 VSCode 自动删行末空白的功能, 这会导致笔记变化重做嵌入 (部分存疑, 也许现在它 is_changed() 检测会更智能些)

感谢分享,回忆了下,可能是反复切换了几次模型,导致混乱的不断的全库读取。另外,我也在他们论坛看到了有人提到这个反复全库的问题,应该是bug,等待后续修复。

对AI笔记的一些想法,原生的AI笔记工具应该能够有一些新的东西,在现有平台上的这种插件,总觉得差点意思, NotebookLM 就是一个比较好的思路。

但是AI的笔记工具能否真的帮助人,还是存疑问的,因为笔记终究是外部工具,最终还是要支撑人,也就是以人为本的,再花的工具终究还是要落到改变人脑本身上,某种意义上纸和笔起到的作用都足够了,AI的优势可能就是通过精准的方式根据人的弱点来形成辅助。最近看了一篇认知负荷理论的视频,还是很有意思的 我这辈子见过最好的学习方法 | CLT认知负荷理论 | 汤质看本质_哔哩哔哩_bilibili

3 个赞

肯定是能帮人的, 这个我甚至奇怪你为啥质疑这点. 最简单的语义搜索, 我用通义/kimi这些工具的能力帮助了我很多, 现在我想把这个能力带到我自己的库中. 最近这个有点火我陆续看到好多遍, 这个理论很基础但流传不光, 需要有更多的up主把他们带进大众视野中

Text Generator 如果使用 Moonshot API,开启流式输出会报错 invalid or unexpected token,可以关掉 streaming 输出避免该问题。

原生的 Chrome/Electron 没法查看 EventStream 具体返回了啥,暂时不好 Debug 原因,先记录在这。

我也遇到过, 我不确定这是啥原因, 以下是自己的推测和解决办法:

首先 Moonshot API 肯定支持流式传输, 在 TextGen 里开启 “全局 streaming” + “Custom API (moonshot-v1-8k) → 高级设置 → 开启 streaming” 之后, 一度是有效的

但 TextGen 某次更新后, 把一些用户定义的处理函数扔到 runJSInSandbox() 里执行了, 估计就是这之后坏事了, 此后就不能用流式传输


解决方案1:

退回 Text Generator 0.7.8 (这时没有 沙箱运行 js) 最省心


解决方案2:

A
更新到最新版, 比如 v0.7.14-beta

B
在 main.js 里, 搜 return await func.call(sandbox 应该只命中一次,
这段代码前面需要补一个 functions.push("chunk");

  ...... 
  const functions = Object.keys(sandbox).filter((k2) => ["function", "object"].includes(typeof sandbox[k2]));

  functions.push("chunk");  // <- 增加这一处
  const func = new Function(...functions, `return new Promise((s,r)=>{(async ()=>{
      ${script}
      })().then(s).catch(r)})`);
  return await func.call(sandbox, ...functions.map((k2) => sandbox[k2]));
}

C
Custom API (moonshot-v1-8k) → 高级设置 → Stream Sanatize 的 预设用户脚本, 这里有个换行, 这么写不知道是否合法, 我给改了

// 原先:
const lines = chunk.split("
data: ");

// 给改成:
const lines = chunk.split("\ndata: ");

以上都是 console debug 出来的, 我实际没弄明白细节
做完 A B C 三个事, 之后整个重启 Obsidian, 应该就可以流式传输了
这位朋友可以看看是否有帮助

1 个赞

感谢帮助! 看代码发现报语法错误的直接原因就是 C 里的换行问题。代码里的默认写法是 "\ndata: " 但填到插件的 TextArea 后 \n 竟然就真换行了。

改了之后又发现 datachunk 都是 undefined,正准备晚上回家继续追一下,原来兄台已经解决了 :smiley:

1 个赞

AI能帮助人和AI笔记能帮助人是两回事啦,语义搜索能帮助你学习,但是是不是笔记+AI能更进一步在知识管理上帮助人,现在都在探索阶段呢。

Hi, 我看了下代码,chunk 报错是因为 runJSInSandbox 对入参做了处理,只接受函数和对象,不过我们可以用 this 引用到它。

所以B这一步可以不用做,把流式处理预设脚本用到chunk那行改成下面这样就可以:

const lines = this.chunk.split("\ndata: ");

完整代码:

// catch error
if (res.status >= 300) {
  const err = data?.error?.message || JSON.stringify(data);
  throw err;
}
let resultTexts = [];
const lines = this.chunk.split("\ndata: ");

const parsedLines = lines
    .map((line) => line.replace(/^data: /, "").trim()) // Remove the "data: " prefix
    .filter((line) => line !== "" && line !== "[DONE]") // Remove empty lines and "[DONE]"
    .map((line) => {
        try {
            return JSON.parse(line)
        } catch { }
    }) // Parse the JSON string
    .filter(Boolean);

for (const parsedLine of parsedLines) {
    const { choices } = parsedLine;
    const { delta } = choices[0];
    const { content } = delta;
    // Update the UI with the new content
    if (content) {
        resultTexts.push(content);
    }
}
return resultTexts.join("");

稍后我给上游提个 PR :smiley:

1 个赞

感谢! 我试试的
我这 js 水平还是不太行, 我继续学习~

唉, 一个月过去了。Smart Connections也支持本地部署了。 这一个月以来GPT3.5也免费了。或者这些折腾都短时没意义,等就行了