用 AI 和笔记对话
这不是教程,而是记录自己的理解。
缘起
我有在坚持做笔记,但是事件字段却没能坚持标注,因为这个工作流不算顺畅。毕竟呼出 QuickAdd 添加一条日记记录是很方便随意的,但是每日总结,提取这一天中值得被标注为事件的内容放入相应字段是复杂的。现在积累了快一年,这是个麻烦事儿。当然,因为我使用的是五年日记格式,所以以后随着回顾再慢慢提取标注也是完全可以的。
但想到了 AI,如果我能让 AI 帮我提取事件,是不是就……这个念头一旦产生,便不可收拾,所以折腾开始!
模型
日记也算敏感数据,虽然其实没什么,但是肯定不想上传,所以我使用 LM Studio 搭建的本地大模型,不过这一点可能是本篇中最不重要的技术细节之一。
干货
这里用到的主要概念:RAG——RAG(Retrieval-Augmented Generation,检索增强生成)。不做概念解读,直接说工作流程。
flowchart TB
subgraph 嵌入
note[笔记] ---> |提取文本|string[字符串] ---> |划分段落区块|chunk[文本区块]
end
subgraph 提问
question[用户提问] ---> |文本嵌入|question_embedding[问题文本的嵌入向量]
end
subgraph 回答
answer[最终回答] <--- AI[对话 AI 大模型] <--- prompt[提示词(用户问题)+上下文(相关笔记区块)] <--- match_chunk
end
question_embedding ---> |相似匹配|vector_database[向量库]
chunk ---> |文本嵌入|vector_database
vector_database ---> match_chunk[与问题匹配的 n 个笔记区块]
使用 Mermaid 绘制,不好控制节点位置,请配合下方解读一起服用:
嵌入
- 可以看做预处理,不是以笔记为单位,而是按章节或者段落,甚至句子为单位去划分的。比如我八百多篇笔记可能被划分为了 2600+ 个区块
- 对区块进行向量标记,就是计算机能理解的方式,用数值标记内容的含义。粗浅举例:如果 0 为纯黑色,255 为纯白色,128 就是灰色,这个数值就代表了它距离黒/白的距离,据此可以知道它更偏黑还是更偏白。复杂一点 RGB 颜色值就是具有三个维度的颜色向量。当然文本理解需要的维度更加复杂。
- 将如此处理后的内容存入数据库,以备查询
提问
- 对问题先进行同上处理,即向量化
- 然后据此与数据库中内容比对,找出最相关的区块
- 根据设定,选出对应数量的最相关区块,提取对应内容,作为提问的上下文
回答
- 将提示词(系统提示词+用户的问题)和上下文(上一步选出的相关笔记内容)交给大模型
- 大模型据此作答。
局限性
综上,我如果问:3 月 20 日发生了什么特别的事情吗?AI 应该可以比较好的回答,毕竟上下文应该会包含我那一天的笔记。
但如果我问:3 月份发生了哪些特别的事情。AI 很可能无法全面回答,因为它得到的上下文不可能是整个三月份的所有日记,被选出来的相关片段可能是 3 月份日记中有特别字样的内容。
如果我问: 3 月份我买了几次大米。因为事件不频繁,那么上下文基本可以涵盖所有事件,所以 AI 很可能给出正确答案。
即,可以与自己的笔记对话,但也不是那么行。
应用
Smart Connections
一个插件,利用向量数据库来分析笔记之间的联系程度,这比用双向链接或者标签、关键字来分析准确度要提升很多,虽然还不是真正的语义分析。但已经足够发现很多笔记之间的隐藏关联了,这比传统关系图谱更加有实用意义。在写作中,可以发现很多相关的,但是已经被自己遗忘的古老笔记。
当然它也可以对话,采用的就是上面我描述的操作逻辑。但默认不携带上下文,只有在你提出基于我的笔记(需要用英文 base my notes)时才会携带相关笔记片段,或者使用双方括号引用特定笔记,这时候携带的是整篇笔记。
刚安装插件时,它会生成向量数据库,速度比较慢。以后会在每次打开笔记库之后根据笔记更新时间来更新数据。
我觉得,它展示笔记间联系的功能最为惊艳。
Copilot
这款插件测试的不多,逻辑上和上面差不多,但是侧重对话,为对话做了很多相关优化。并且作者野心也比较大,Copilot Plus 计划中是可以实现我在文初的需求的。但还需要时间等待其发展完善。
AnythingLLM
本地知识库工具,搭配 LM Studio 或者 Ollama 可以实现全本地知识库问答。工作流程和上面描述基本一致。
- 索引速度相当快,相比上述插件简直无感
- 可以控制上下文携带的片段数量,但肯定不可能携带整库内容
类似知识库工具还有很多,就不一一测试了。
总结
所以所谓和笔记的问答,AI 只是根据上下文中和问题相关度较高的片段作答,应用场景限制是比较大的。但是灵活运用还是有一些很实用的场景。