-
Cherry Studio 通过 MCP 对接思源笔记
2025-03-14 11:49直接接入 db 有个大问题。
AI 回答分两步:1 搜索资料,2 回答问题。
问题出在第一步。
比如我要问什么是巴黎协定。第一步就是查找语义最相近的一部分块。
而一篇文章被拆分为多个块放在 db,并且没有前后关联,db 内没有块顺序的字段。
所以,查找到的那些块也没前后关联。
并且一篇文章中,并不是每一个段落块,都会在语义上与"巴黎协定"相近。
所以第一步查找到的内容是不完整而且无序的。如果是需要问一些逻辑问题,有可能导致 AI 做出相反的错误回答。
不过如果你的问题是查找与巴黎协议相关的内容并列罗出来,那还好一点。
如果能改进,比如查找到内容后,进一步处理得到相关文章,然后给到 AI 这样会更准确。
如果文章有多个,可以每个文章单独回答,再看是否要总结所有回答。
如果单个文章太大,可以选文章中的相关片段。
-
还是希望要 notion 那种折叠块
2025-03-12 15:24我也有这个折叠的需求。不过在自己的私人插件上做了。现在放到番茄工具箱了。
快捷键依然是 ctrl↑、ctrl↓。与官方的一样。如有要使用可以删除官方的快捷键,或者修改本功能的快捷键。
增强了对标题块、超级块、引述块、列表块的折叠功能。比如放置光标到超级块内,就可以折叠超级块。
我没有对段落块的折叠需求,所以忽略段落块。
-
如何通过思源 API 获取某个笔记本下面的所有笔记 id
2025-03-04 10:29如果只要 id。 select id from blocks where box='20241011110558-iq743yl' and type='d' limit 99999999
-
AI 搜索你的所有笔记!思源笔记 +Cursor+MCP Server——打造你的个人专属 AI 资料库!(AI 大模型搜索笔记、内容总结、大纲凝练、RAG 搜索)
2025-02-27 12:47思源的 blocks 表。 逻辑结构就是一篇文章(没上下文顺序)。 物理结构是数据库,看起来是结构化的。但实际上,它逻辑上就是一篇文章。并不对文章内容的"结构化"起到"正向"作用。
所以对于一篇文章,原来的切片知识库,还有切片大小的设置,能保留一定的连贯的上下文。
不过我对 MCP 没研究。我觉得 MCP 应该这方法来解决这个问题。坐等大佬分享。
-
AI 搜索你的所有笔记!思源笔记 +Cursor+MCP Server——打造你的个人专属 AI 资料库!(AI 大模型搜索笔记、内容总结、大纲凝练、RAG 搜索)
2025-02-27 08:32这样做不如直接得到全文
/api/lute/copyStdMarkdown
-
AI 搜索你的所有笔记!思源笔记 +Cursor+MCP Server——打造你的个人专属 AI 资料库!(AI 大模型搜索笔记、内容总结、大纲凝练、RAG 搜索)
2025-02-26 11:18我有些疑问不知如何解决,还请大佬解惑。
如果只用 sqlite 的数据。
数据库里是按照块,拆开来存储的。可以知道哪些块是同一个文档的块,但不知道块的先后顺序。
还有一些复杂的大纲结构等,也需要确定顺序。
-
接入 ai 能否根据自己所有的笔记去思考并回答问题?
2025-02-24 08:39RAG(检索增强生成)的缺点:
目前的检索机制存在不少问题。
一方面有盲区,答案明明是存在的,可因为排名太靠后就没被找到
而且它处理不了实体之间那种复杂的层次关系
检索的文本块数量也有限制,这就容易造成信息是零碎的,不成系统。
另一方面,在信息整合的时候也容易出错,就算检索到了正确的信息,可大模型在进行综合推理的时候,特别是那种要跨越好几个文档进行推理的情况,还是有可能得出错误的答案。
所以,期望不高的情况下,做一个智能查找功能也不错。
各种开源知识库的实现也有些不一样,检索打分的结果也不一样,所以效果有差别。
开源知识库和大厂的知识库,做法肯定有些不同。哪个好还需要试试。
-
关于反链统一传递型块引展示效果——你最需要的反链面板展示效果
2025-01-10 13:03非常同意这个优化方向 👍。
我之前偶然在 issue 的讨论中得到灵感,后来在插件中实践了这个优化。
之前要费尽心机利用大纲来传递的内容,现在用超级块,引述块就可以轻松传递了。
原因就是大纲是向下出传递,对格式要求高点,而这个优化方向是向上传递,对格式的要求低。
另外,特别是利好用超级块做卡片,并且还想传递内容的场景。
现在楼主更进一步,优化到了思源中,让更多人受益。算是思源特色的引用了 👍
说个使用一段时间后的体验:
在插件提供了 3 个选项。可以向上传递到标题,超级块,引述块。
用一段时间后,觉得传递到标题块意义不大。现在关闭了。原因就是范围太大,反而形成了干扰。
-
思源笔记是否可以同步到 gitee 或 github 仓库
2025-01-07 08:57用网盘确实挺麻烦的,但用 Git 就完全没问题。我已经用 Git 快三年了,感觉挺顺手的。现在我都是用 Git 配合思源的同步功能,这样手机也能方便地同步数据。而且 Git 还多了一层备份,挺安心的。毕竟这些数据都是我多年积累下来的,得好好保管。
这是我的
.gitignore
# 帮助文档的笔记本 SiYuan/data/20210808180117-czj9bvb # 主题 SiYuan/conf/appearance SiYuan/conf/windowState.json # 插件等 SiYuan/data/.siyuan SiYuan/data/storage/recent-doc.json SiYuan/data/plugins SiYuan/data/widgets # 临时文件等 SiYuan/repo SiYuan/backup SiYuan/history SiYuan/sync SiYuan/temp SiYuan/.lock
-
API 获取并处理块的一些疑问
2024-12-18 12:10数据库的,有些可能不通用。
transSetAttrViewColWrap(avID: string, blockID: string, colID: string, wrap = true) { const op = {} as IOperation; op.action = "setAttrViewColWrap"; op.avID = avID; op.blockID = blockID; op.id = colID; op.data = wrap; return op; }, transSetAttrViewColHidden(avID: string, blockID: string, colID: string, hide = true) { const op = {} as IOperation; op.action = "setAttrViewColHidden"; op.avID = avID; op.blockID = blockID; op.id = colID; op.data = hide return op; }, transSetAttrViewSorts(avID: string, blockID: string, colID: string, order: "ASC" | "DESC") { const op = {} as IOperation; op.action = "setAttrViewSorts"; op.avID = avID; op.blockID = blockID; op.data = [{ column: colID, order }] return op; }, transSetAttrViewColCalc(avID: string, blockID: string, colID: string, operator: CalcOperator) { const op = {} as IOperation; op.action = "setAttrViewColCalc"; op.avID = avID; op.data = { operator }; op.blockID = blockID; op.id = colID; return op; }, transSetAttrViewFilters(avID: string, blockID: string, filters: IAVFilter[]) { const op = {} as IOperation; op.action = "setAttrViewFilters"; op.avID = avID; op.data = filters; op.blockID = blockID; return op; }, transSetAttrViewViewName(avID: string, viewID: string, name: string) { const op = {} as IOperation; op.action = "setAttrViewViewName"; op.avID = avID; op.id = viewID; op.data = name; return op; }, transUpdateAttrViewCol(avID: string, colId: string, name: string, type?: TAVCol) { const op = {} as IOperation; op.action = "updateAttrViewCol"; op.id = colId; op.avID = avID; op.name = name; op.type = type; return op; }, transSetAttrViewName(avID: string, name: string) { const op = {} as IOperation; op.action = "setAttrViewName"; op.id = avID; op.data = name; return op; }, transRemoveAttrViewCol(avID: string, colID: string) { const op = {} as IOperation; op.action = "removeAttrViewCol"; op.avID = avID; op.id = colID; return op; }, transAddAttrViewCol(avID: string, name: string, id = NewNodeID(), type: TAVCol = "text", previousID = "") { const op = {} as IOperation; op.action = "addAttrViewCol"; op.avID = avID; op.name = name; op.previousID = previousID; op.type = type; op.id = id; return op; }, transUpdateAttrViewCellBatch(args: { avID: string, cellID?: string, colID: string, rowID_BlockID: string, value: IAVCellValue }[]) { return args.map(arg => { const op = {} as IOperation; op.action = "updateAttrViewCell"; op.avID = arg.avID; op.id = arg.cellID; op.keyID = arg.colID; op.rowID = arg.rowID_BlockID; op.data = arg.value; return op; }) }, transInsertAttrViewBlock(avID: string, blockID: string, srcs: IOperationSrcs[], previousID = "", ignoreFillFilter = true) { const op = {} as IOperation; op.action = "insertAttrViewBlock"; op.avID = avID; op.blockID = blockID; op.previousID = previousID; op.ignoreFillFilter = ignoreFillFilter; op.srcs = srcs; return op; }, transDoUpdateUpdated(blockID: string, data = timeUtil.getYYYYMMDDHHmmss()) { const op = {} as IOperation; op.action = "doUpdateUpdated"; op.id = blockID op.data = data return op; },
-
API 获取并处理块的一些疑问
2024-12-18 12:09补充几个我常用的工具,用于创建一系列
IOperation
, 传给"/api/transactions"
即可。 批量的 IOperation 形成一个事务。transBatchUpdateAttrs(blockAttrs: { id: string, old: AttrType, new: AttrType }[]) { return blockAttrs.map(b => { const op = {} as IOperation; op.action = "updateAttrs"; op.id = b.id; op.data = JSON.stringify({ old: b.old, new: b.new }); return op; }); },
transUpdateBlocks(ops: { id: string, domStr: string }[]) { ops = ops.filter(op => !!op.id); if (!(ops.length > 0)) return []; return ops.map(({ id, domStr }) => { const op = {} as IOperation; op.action = "update"; // dom op.id = id; op.data = domStr; return op; }); },
transDeleteBlocks(ids: string[]) { return ids?.map(id => { const op = {} as IOperation; op.action = "delete"; op.id = id; return op; }) ?? []; },
transMoveBlocksAfter(ids: string[], previousID: string) { return ids.slice().reverse().map(id => { const op = {} as IOperation; op.action = "move"; op.id = id; op.previousID = previousID; return op; }); },
transMoveBlocksAsChild(ids: string[], parentID: string) { return ids.slice().reverse().map(id => { const op = {} as IOperation; op.action = "move"; op.id = id; op.parentID = parentID; return op; }); },
-
API 获取并处理块的一些疑问
2024-12-17 22:13"/api/block/insertBlock"
"/api/block/updateBlock"
可以传入 kramdown。 内容与属性需要用 '\n' 来隔开。id updated 可以不用去掉。 如果你要插入新的块,需要生成新的 id 避免重复。
"/api/block/getBlockDOM"
可以按块 id 读取 dom."/api/transactions"
可以按 dom 来更新或者插入等。另外, dom 与 markdown 的转换可以用:
export const NewLute: () => Lute = (globalThis as any).Lute.New;
lute = NewLute();
const md = lute.BlockDOM2Md(div.outerHTML);
export class Lute { public static WalkStop: number; public static WalkSkipChildren: number; public static WalkContinue: number; public static Version: string; public static Caret: string; public static New(): Lute; public static EChartsMindmapStr(text: string): string; public static NewNodeID(): string; public static Sanitize(html: string): string; public static EscapeHTMLStr(str: string): string; public static UnEscapeHTMLStr(str: string): string; public static GetHeadingID(node: ILuteNode): string; public static BlockDOM2Content(html: string): string; private constructor(); public BlockDOM2Content(text: string): string; public BlockDOM2EscapeMarkerContent(text: string): string; public SetSpin(enable: boolean): void; public SetTextMark(enable: boolean): void; public SetHTMLTag2TextMark(enable: boolean): void; public SetHeadingID(enable: boolean): void; public SetProtyleMarkNetImg(enable: boolean): void; public SetSpellcheck(enable: boolean): void; public SetFileAnnotationRef(enable: boolean): void; public SetSetext(enable: boolean): void; public SetYamlFrontMatter(enable: boolean): void; public SetChineseParagraphBeginningSpace(enable: boolean): void; public SetRenderListStyle(enable: boolean): void; public SetImgPathAllowSpace(enable: boolean): void; public SetKramdownIAL(enable: boolean): void; public BlockDOM2Md(html: string): string; public BlockDOM2StdMd(html: string): string; public SetSuperBlock(enable: boolean): void; public SetTag(enable: boolean): void; public SetInlineMath(enable: boolean): void; public SetGFMStrikethrough(enable: boolean): void; public SetGFMStrikethrough1(enable: boolean): void; public SetMark(enable: boolean): void; public SetSub(enable: boolean): void; public SetSup(enable: boolean): void; public SetInlineAsterisk(enable: boolean): void; public SetInlineUnderscore(enable: boolean): void; public SetBlockRef(enable: boolean): void; public SetSanitize(enable: boolean): void; public SetHeadingAnchor(enable: boolean): void; public SetImageLazyLoading(imagePath: string): void; public SetInlineMathAllowDigitAfterOpenMarker(enable: boolean): void; public SetToC(enable: boolean): void; public SetIndentCodeBlock(enable: boolean): void; public SetParagraphBeginningSpace(enable: boolean): void; public SetFootnotes(enable: boolean): void; public SetLinkRef(enable: boolean): void; public SetEmojiSite(emojiSite: string): void; public PutEmojis(emojis: IObject): void; public SpinBlockDOM(html: string): string; public Md2BlockDOM(html: string): string; public SetProtyleWYSIWYG(wysiwyg: boolean): void; public MarkdownStr(name: string, md: string): string; public GetLinkDest(text: string): string; public BlockDOM2InlineBlockDOM(html: string): string; public BlockDOM2HTML(html: string): string; public HTML2Md(html: string): string; public HTML2BlockDOM(html: string): string; }
-
思源笔记的资源都挤在一个文件夹里
2024-12-13 09:45早期有过 bug,但现在我是没遇到过.
备份一下就可以,没啥问题了. 或者 data 目录做成一个 git 仓库. 做完实验之后可以快速还原
-
思源笔记的资源都挤在一个文件夹里
2024-12-13 09:06这个确实是一个问题。 一个文件夹很大,无法手动打开的话,有一种不受控制的感觉。所以我做了一个工具,按日期重新分配图片到子文件夹,我自己是经常用,没发现啥问题。
如果全放到一个文件夹内, 并且文件数量在一定规模内,获取所有的资源文件,不需要遍历子文件夹,这样的话程序效率会高.
大多数人使用的情况来看,资源文件不会太多,按日期来分,或者放同一个文件夹里都一样。
如果说文件数量很多,个人觉得怎么搞都要完蛋。
咨询了一下,通义千问
操作系统和固态硬盘(SSD)支持的文件数量主要取决于文件系统类型、文件名长度、路径深度、以及单个目录中的条目数限制。对于 Windows 操作系统,常用的文件系统是 NTFS(New Technology File System)。NTFS 对单个目录中文件数量的支持是非常大的,理论上可以支持到 2^32-1(即 4,294,967,295)个文件,但实际上由于性能和其他因素的影响,很少会达到这个极限。
使用 SSD 并不会直接决定你可以在一个文件夹中存储多少文件,但与传统的 HDD 相比,SSD 在处理大量小文件时通常表现更好,因为它们没有机械运动部件,所以寻道时间和延迟更低。然而,即使使用 SSD,当一个文件夹中包含大量的文件时,程序处理这些文件的效率仍然可能会受到影响。这里有几个原因:
- 文件系统元数据:尽管 SSD 访问速度快,但如果需要频繁更新文件系统的元数据(例如,在创建、删除或重命名文件时),这可能成为瓶颈。
- 操作系统 API 调用:许多文件操作涉及操作系统级别的 API 调用,如
FindFirstFile
/FindNextFile
等,当文件数量巨大时,这些调用可能变得缓慢。 - 内存和 CPU 资源:处理大量文件的信息(例如,获取每个文件的属性)会消耗更多的内存和 CPU 资源。
- 应用程序逻辑:如果应用程序需要遍历所有文件并执行某些操作,随着文件数量的增长,所需的时间也会增加。
为了优化程序处理大量文件的性能,建议考虑之前提到的一些策略,比如分批处理、将文件分散到多个子文件夹中、利用索引机制等。此外,确保你的程序代码高效地使用了可用的 API,并且尽可能减少不必要的 I/O 操作,也是提高性能的关键。
如果你的应用场景确实涉及到非常大量的文件,并且性能是一个关键问题,那么可能还需要进一步研究特定于文件系统和硬件的最佳实践,甚至考虑定制化的解决方案。
-
思源可以做到取消输入“【】”自动变成 Todo 块的功能吗
2024-12-07 22:26方法 1:
对于安装好的思源可以这样改:
找到安装目录,比如:C:\Users\abc\AppData\Local\Programs\SiYuan\resources\stage\build\app
找到 main 开头的 js 文件:
查找
\u3010\u3011
然后删除,重启思源即可。
每次升级思源之后,都要改一次。
方法 2:改代码,自己编译:
把红色代码删除后编译。
-
图表功能怎么用?只见 echarts 报错
2024-11-11 00:00如果是做个树形图,或者网络图,可以试试
番茄工具箱
的块关系图
(图中:按住 ctrl 可以多选节点与连线;backspace 可删除节点与连线;可创建连线;alt 点击可以定位到文档)
(文档中:右键菜单可以定位到图中。快速创建引用可以用双向互链功能)
-
输入【】的时候,会出现的居然是待办清单
2024-11-04 14:51方法 1:
对于安装好的思源可以这样改:
找到安装目录,比如:C:\Users\abc\AppData\Local\Programs\SiYuan\resources\stage\build\app
找到 main 开头的 js 文件:
查找
\u3010\u3011
然后删除,重启思源即可。
每次升级思源之后,都要改一次。
方法 2:改代码,自己编译:
把红色代码删除后编译。