网易首页 > 网易号 > 正文 申请入驻

现行的笔记软件已经无法解决AI辅助编程效率的问题了

0
分享至

笔记一直是程序员最重要的效率工具之一,几乎每一代程序员都会试图从自己的工作方式出发,开发或改造一套属于自己的笔记系统,从最早的文本文件、Wiki,到 Word、印象笔记、Notion,本质上都是在解决同一个问题:如何在高强度的信息处理环境中,保留可用的思考结果。但现实是,笔记系统始终是不够好的,尤其是对每天需要处理大量文字、代码和决策的人来说。

过去几年我一直使用 Notion 作为主力笔记工具,常见的做法是开一个表格,每条记录带时间戳、链接和上下文说明,处理 bug 时在 icon ��上放一只小虫子,把所有线索、想法、日志和代码都塞进去,直到有一天我连续在电脑前工作了将近十二个小时,回过神来发现当天已经产生了接近两百条记录。Notion 的每一条记录本质上都是一个可以无限展开的页面,而不是 Excel 里的一个单元格,即便每一页只有两三千字,二百页也已经是四十万字,这个规模早已远远超出人类在一天之内能够阅读、理解和消化的极限,而且这并不是一次性的极端情况,而是逐渐变成了常态。

正是在这种背景下,我在最近几周明显进入了一种奇怪的状态:事情很多,但推进极慢,下意识回避工作,睡眠时间不断拉长,再加上东岸连续的大雪,被困在家里几天,又干脆出去玩了几天雪,表面看像是怠工或逃避,但真实感受是一种深度的认知疲惫。与此同时,大语言模型变得异常强大,代码、文档、方案几乎可以瞬间生成,但这种能力提升并没有让我成为一个更高效、更清醒的个体,反而带来强烈的挫败感,因为我发现这种状态并不只发生在我身上,和一些朋友交流后,大家普遍都在经历类似的认知过载:个人能力被工具放大到一定程度之后,随之而来的不是解放,而是更严重的反噬。

工业化语言生产机

回头看,问题集中体现在三个方面:第一,信息和文本的生成规模已经彻底超出人类的生理极限,这与个人能力强弱无关;第二,生成速度过快,导致根本记不住自己看过什么,LLM 必须持续回答、持续发散、持续给路径,却从不提供“到此为止”的信号;第三,也是最致命的,是隐性漂移,状态完全依赖窗口维持,窗口不断叠加,几天之后再回看几天前的代码,已经无法理解当时的情境,同一个概念、脚本和索引在命名、路径和 ID 上不断漂移,vault_index、index_vault、inventory_index 之类的差异一路堆叠,几周之后再看整个项目,只剩下一种彻底失控的感觉。

被雪困住的那几天里,我反复思考这个问题,逐渐意识到这并不是个人管理能力的问题,而是机制层面的必然结果:LLM 本质上是一个 zero-shot universe,几乎零成本生成内容,不会疲劳,不会犹豫,也不会做“是否值得继续”的决策,prompt 只是软约束,它没有硬停机条件,它是一台持续生产语言和符号的工业化机器,而人类的大脑并不具备相同的承载能力;漂移不是偶然,而是这种机制的必然产物,拉长上下文并不能解决问题,因为模型永远只是在预测下一个 token,他要找不到最正确的答案他就给你猜一个;更重要的是,整个过程没有责任主体,每天几百上千次 prompt 强烈依赖当下环境,事后几乎无法复现,也无法追责。

这是一个治理Governance的问题

正是在这种情况下,我开始意识到,问题并不在于“记得不够多”,而在于在这个时代,继续沿用“多记一点总有用”的传统笔记假设,本身就是不可持续的。Notion 并不是没有搜索功能,但当我真的需要解决一个具体问题、回溯自己过去的思考时,搜索出来的往往是成百上千条结果,其中大量内容彼此冲突、语境缺失、时间错位,几乎无法直接使用,搜索本身并没有降低认知负担,反而把问题放大了。也正是在这个背景下,在这个 repo 连续开发了几天之后,我又一次尝试去重新搭建自己的记录体系——这种尝试其实已经发生过很多次,绝大多数都以失败告终,但这一次我明显感觉到有些地方开始对路了,至少已经值得写出来和别人分享。关键并不在于我是否找到了一个“更好的工具”,而在于我发现,这根本不是工具层面的问题,而是人在这个阶段不可回避地遭遇了自身的生理与认知约束。一方面,我确实需要一个更贴合我个人工作方式的系统,但另一方面,更重要的是必须把注意力放回真正的核心问题上:这个问题既不是笔记,也不是程序,更不是靠一个软件、一个库就能一次性解决的工程问题,它的核心只有一个——知识的治理。

这是个Governance的问题。

简单说,“知识的治理”是什么意思?从更大的尺度看,人类社会中几乎所有真正困难的问题,本质上都是治理问题。政治是治理问题,国家如何被治理;法律是治理问题,立法、司法、执法如何分工与约束;宪法本身也是治理问题,不只是写下来,而是如何被解释、如何被遵守、如何保证它真的被遵守。把尺度缩小,团队管理、制度设计、流程约束,同样是治理问题,而不是工具问题。治理的核心从来不在于“有没有信息”“能不能访问”,而在于哪些东西被承认为有效、哪些判断具有权威、哪些状态可以进入长期记忆、哪些必须被限制、冻结或废弃。

回到个人层面,所谓“知识管理”的真正难点也在这里:不是信息不够,不是搜索不强,而是缺乏一套能够裁决、约束和负责的机制。正因为如此,这个问题其实已经被无数程序员反复尝试解决过,从早期的个人知识库、标签系统、到后来的双链、图谱、向量化检索,再到 Obsidian、各种语义搜索和 AI 助手,它们解决的更多是“如何找到内容”“如何关联内容”“如何生成内容”,但几乎都默认了一个前提:内容一旦写下,就天然具有价值,只要存得住、搜得到,就算成功。这个解决方案和各种开源项目到处都是,我自己也是借鉴了的。我现在也是把内容全部存成 .md文档,obsidian vault可读。But this is not the point!

在信息和生成能力远低于今天的年代,搜到就赚到。但在一个内容可以零成本爆炸式生成的时代,这个前提本身已经失效了。真正缺失的并不是更聪明的搜索算法,也不是更复杂的表示方式,而是一套能够回答“什么可以被承认为知识”“什么只是过程噪声”“什么需要被追责”“什么必须可复现”“什么不允许悄然漂移”的治理结构。

所以,我说说我现在自己尝试的这种方案,这个repo,虽然开始没多久,但是我感觉这个方向很行。如果你有这个需求,也许我能启发一些目前同样困扰的人。

一个Sovereign Log, 简单代码,昂贵写入,没有接LLM,后期可以接,帮我定住我最核心的认知。

不是为了高频记录而设计的,恰恰相反,它刻意让写入变得昂贵、缓慢和需要思考;它的实现保持在尽可能简单的代码层面,不依赖复杂系统,也不直接接入 LLM,因为一旦接入,零成本生成就会立刻侵蚀它作为“裁决记录”的性质。现阶段都是硬编码。我先简单说说都包括啥,现在连UI都没有,就已经简单的解决了我大量的问题。

├── _system

├── docs

├── inbox

├── requirements

├── sovereign_log

├── templates

└── tools

这里面有两个.md组成的文本库,一个是sovereign_log,另一个是doc。

Sovereign_log

当然,一切并不是从一个宏大的系统开始的。我最初建立的只是一个极小、极其克制的 vault,它的起点和任何一个普通的 Obsidian vault 并没有本质区别。如果你看到它的 graph,会发现几乎没有什么结构特征:没有刻意构建的 backlink,没有主题网络,也不追求连接密度。唯一真正不同的地方在于数量——极少。这是一个被我刻意维持的约束。在这个 vault 里,每一篇内容都不是草稿,不是“先写下来再说”,而是经过反复推敲的结果。我会与 AI 多轮对话,压缩表达、校正边界、澄清含义。早期我主要使用英文写作,同时辅以少量中文翻译,是作为一种语义校验手段,用来确认我是否真正理解了自己写下的东西。随着系统成熟,这个 vault 很可能会完全切换为英文。这个阶段的 Sovereign_Log,本质上是一个高度精炼、完全由个人主权控制的知识集合,其核心原则非常简单:不要乱写,不要当成草稿,数量不是越多越好,而是越精良越好。有时一整天的思考、推演和结构对齐,最终只会留下 1–2 篇笔记,是一种有意为之的熵控制。你一定要维持这种纪律,否则又跟你其他笔记一样,照搬过来一大堆东西。



Doc

Doc 在形式上依然是“笔记”,但它并不是 Sovereign_Log 的自然延伸,而是一次明确的跃迁。Doc 中的内容并非写得更正式,而是被提升过的文本,处于一种介于叙事语言与可执行代码之间的 IR 状态。它们尚未成为代码,但已经不再允许自由叙述。在设计这个知识库时,我刻意引入了“昂贵性”这一反直觉原则,用来对抗大语言模型生成文字与代码过快、过多的问题。我认为,真正进入知识库核心层的内容,必须在制度上是昂贵的,而不是在情绪或表达上显得复杂。这种昂贵性体现在三个层面。

首先是格式昂贵。Doc 不是自由文本,任何内容想要进入这一层,必须满足固定结构并通过机器可执行的格式检查。确保这些文本在原则上是可解析、可索引、可审计、可约束的。一篇格式不合格的内容是根本不具备进入该层的资格。

其次是流程昂贵。内容不能一开始就进入 Doc,它必须先在 Sovereign_Log 中存在,经过时间沉淀,在真实使用中反复被搜索、引用、转化为代码或决策,逐渐显现出对系统行为的实际影响,才会成为候选项,并在明确授权后被提升进入 Doc。这一机制在未来引入团队共享知识库时尤为关键,因为它明确阻断了任何人、任何模型、任何一时兴起的想法对核心知识层的直接污染。Doc 被视为一种稀缺资源,而不是存放“整理后内容”的地方。

第三,也是现阶段最重要的一点,是语义昂贵。我对 Doc 的核心要求并不是表达清晰或逻辑自洽,而是语义必须达标。所谓语义达标,意味着条文之间不能互相矛盾,不允许隐含冲突,不允许模糊责任与边界,每一条声明都必须具备生成 binding 代码的潜力。我观察过许多文档规模庞大的知识库,它们的共同问题并不是信息不足,而是语义杂乱、定义漂移、条文冲突,最终无法转化为真实可执行的系统约束。这样的知识库看似厚重,实则不可执行。而 Doc 的目标恰恰相反:每一条文本,都是潜在的系统约束;每一条语义,都是未来代码的来源。因此,语义本身也必须进入可被机器介入和审计的范围。

├── docs
│ ├── decisions
│ ├── governance
│ │ ├── CLAIM-AUTHORING-STYLE-V0-1.md
│ │ ├── EVIDENCE_SUGGEST_AUDIT.md
│ │ ├── RPT-2026-01-26-RUNTIME_ENV_GOVERNANCE.md
│ │ ├── SD-0007_RUNTIME_ENV_FREEZE.md
│ │ ├── SD-0008_INDEX_CONSOLIDATION.md
│ │ ├── SD-0009_DOC_IR_SPEC_v0.md
│ │ ├── SD-0010 — Normative Boundary & Semantic Consistency Rules
│ │ ├── SD-0011_ID_Taxonomy_and_Identity_Ledger.md
│ │ └── SD-0012 — Observability Causal Structure & Span Identity
│ ├── invariants
│ │ ├── INV_CATALOG_v0.md
│ │ ├── INV_DOC_IR_BOOTSTRAP_v0.md
│ │ └── INV_INDEX_ROOTS_0001.md
│ ├── Machine-Checkable Invariants.md
│ ├── runs
│ ├── SD-0001-System-Constitution.md
│ ├── SD-0002-Derived-Artifact-Path-Freeze.md
│ ├── Sovereign Log — Write Protocol v1.0.md
│ ├── stage_contracts
│ │ └── PRE_STAGE_5.md
│ └── taxonomy
│ ├── INDEX_TYPES.md
│ └── TDES.md

我现在的系统是完全没有接入任何 LLM 的,至少在这一层没有。这些约束、筛查和升级机制,全部是在代码层面完成的。我一直相信,如果你是一个看到这里的程序员,并且你觉得这套方法对你有借鉴意义,那么它在技术上并不复杂,甚至可以说是非常直白的工程实现。这里我不展开具体代码细节,只用一个非常具体的例子来说明我所谓的“语义昂贵”到底是什么意思。

以语义筛查为例。我每次跑 audit,通常都会顺手生成两份报告:一份是给机器继续消费的 JSON,一份是给人看的 Markdown。下面这段就是我某一次跑出来的语义审计报告摘要。

这次 audit 的标识是 AUDITDOCSEMANTIC — 20260130T205405Zdocsemantic_audit,整体结果是 ok: False,意味着这次检查在制度上是不通过的。系统扫描了 docs 目录下的文档,共识别出 77 条 claims,使用的是基于 embedding 的相似性与语义模式匹配(这里用的是 all-MiniLM-L6-v2,阈值 0.92,top-k 为 8,最大配对 200)。需要特别说明的是,这里对 modality、target、predicate 的推断仍然是启发式的,属于 v0.1 阶段,这一点在 meta 里是明确写出来的,后续会被提升为显式的结构化 claim tags。也正因为如此,重复或冲突在默认情况下只是 warning,但在这次配置里,我把冲突严重性提升为了 error,要求必须被解决。

真正关键的是下面这条 violation:SEM-CNF-001。它指向的是一个语义冲突,而且不是模糊冲突,而是非常具体的 modality 冲突。系统检测到,在两个不同的文档中,针对同一个 (target, predicate) 组合——也就是 ('GLOBAL', 'evidence')——出现了相互矛盾的规范性断言:一条是 must,另一条是 must_not。冲突来源被精确定位到了 SD-0011#C-0004 和 DOC-EVIDENCE-SUGGEST-AUDIT-V1#C-0003 这两条具体的 claim 上。这意味着,在当前 Doc 层的语义空间中,系统同时被告知“这件事必须发生”和“这件事必须不能发生”,而且两者作用域完全一致。

这类错误在我的系统里是不可接受的。一旦这样的语义进入核心 Doc 层,任何试图从中生成 binding 代码、策略或运行时约束的行为,都会立刻失去确定性。因此 audit 是直接要求你做出选择。hint 里给出的路径也非常明确:要么通过既定的优先级体系来裁决(例如 INV 高于 SD,高于 taxonomy),要么明确使用 supersede 机制,让其中一条 claim 在制度上失效。这是哪一条规则在系统中继续存活的问题。

对我来说,这正是“语义昂贵”的具体体现。不是靠人脑记住“这里好像有点矛盾”,而是让系统在 Doc 层直接拒绝语义不闭合、不一致、不可执行的状态。也正因为有了这样的机制,Doc 才不再是一个“写得很严肃的文档集合”,而是真正开始具备约束未来代码与系统行为的资格。

AUDITDOCSEMANTIC — 20260130T205405Zdocsemantic_audit
ok: False
violations: 1
Meta
"docs_dir": "docs",
"claims_count": 77,
"dup_threshold": 0.92,
"topk": 8,
"max_pairs": 200,
"dup_severity": "warn",
"model": "sentence-transformers/all-MiniLM-L6-v2",
"notes": [
"v0.1 modality/target/predicate inference is heuristic; promote to structured claim tags later.",
"duplicates are warnings by default; set --dup_severity error to hard-enforce."

Violations
1. SEM-CNF-001 (error)
path: docs/governance/SD-0011_ID_Taxonomy_and_Identity_Ledger.md | docs/governance/EVIDENCE_SUGGEST_AUDIT.md
message: Modality conflict (must vs must_not) on (target,predicate)=('GLOBAL','evidence'): SD-0011#C-0004 vs DOC-EVIDENCE-SUGGEST-AUDIT-V1#C-0003
hint: Resolve via priority (INV > SD > TAXONOMY ...) or supersede one of the conflicting claims.
meta: 46502865b8712493e52dffd4a6b6871cd994c162f900ea8e6e7a8c3ebbcb5873
怎么实现的

从技术实现上讲,这套机制并不依赖大语言模型,也不需要任何“智能理解”。它的核心思想是:把文档的语义压缩成一组可计算、可比较、可失败的结构化要素,然后用一套完全确定性的规则对这些要素做审计。整个系统可以拆解为几个相对独立的技术层,你可以按需要取用或替换其中任意一层,而不影响整体成立。

第一步是声明式语义单元的引入。文档不再被当作一整块自然语言,而是被要求显式标注最小治理单元——也就是稳定编号的 claim。它们本质上等价于“规范性断言”,每一条都是一个潜在的系统约束。实现上不需要复杂解析器,只要用简单、鲁棒的文本模式(例如固定前缀或行结构)就可以稳定抽取。这一步的关键不是解析能力,而是强迫作者在写作阶段就做出“这是我要被系统治理的句子”的选择。

import re
from dataclasses import dataclass
CLAIM_RE = re.compile(r"(?m)^\\s*-\\s*(C-\\d{4})\\s*:\\s*(.+?)\\s*$")
@dataclass
class ClaimRaw:
claim_id: str
text: str
def extract_claims(md: str) -> list[ClaimRaw]:
out = []
for cid, txt in CLAIM_RE.findall(md):
out.append(ClaimRaw(claim_id=cid, text=txt.strip()))
return out

复现要点:你只需要一个稳定、可被 grep 的写作格式(比如 - C-0001:)。解析就能保持极简。

第二步是规范性强度(modality)的离散化。系统并不尝试理解句子的全部含义,而是只关心它在制度上的态度:是必须、禁止、允许,还是无法判定。这可以通过一组确定性的关键词或规则完成,而不是统计模型。重要的是,这一步把“模糊的自然语言语气”压缩成一个有限集合,使得后续冲突判断变成一个有限状态问题,而不是语言理解问题。

import re
MODALITY_RULES = [
("must_not", re.compile(r"\\b(must not|shall not|forbidden|prohibited|not allowed)\\b", re.I)),
("must", re.compile(r"\\b(must|shall|required|mandatory)\\b", re.I)),
("forbid", re.compile(r"\\b(forbid|prohibit|disallow|deny)\\b", re.I)),
("allow", re.compile(r"\\b(allow|permit|allowed)\\b", re.I)),

def infer_modality(text: str) -> str:
for name, rx in MODALITY_RULES:
if rx.search(text):
return name
return "unknown"

复现要点:这不是 NLP,是可审计的规则表。你可以按你组织的写作词汇(MUST/SHALL/禁止/允许)扩展规则。

第三步是约束对象(target)的锚定。为了避免所有规则都在一个全局空间里相互干扰,系统需要一个机制,把每条 claim 映射到一个明确的约束对象上。实现方式可以非常简单,例如通过显式标注、路径前缀、资源名或作用域标识符。只要这个 target 是稳定、可比较的,就足够用于治理。未能明确锚定的规则,可以被保守地归入全局作用域,从而承担更高的冲突风险,这本身就是一种设计激励。

import re
BACKTICK_RE = re.compile(r"`([^`]+?)`")
def infer_target(text: str) -> str:
# Prefer explicit anchors like `docs/` `_system/` `sovereign_log/`
for m in BACKTICK_RE.finditer(text):
tok = m.group(1).strip()
if tok.startswith(("docs/", "_system/", "sovereign_log/")):
# collapse file path to a directory-ish prefix for stability
parts = tok.split("/")
if len(parts) >= 2:
return parts[0] + "/" + parts[1] + "/"
return parts[0] + "/"
return "GLOBAL"

复现要点:你要的不是“精准路径”,而是稳定可比对的 target key。写作上用 backticks 做显式锚点,工程上就能把 GLOBAL 降到最少。Global会给你很多的false positive, 没完没了的修。其实一般的claims都是针对特定域的,你不会动不动就写一个“我这条整个系统都必须通用。”

第四步是谓词维度的粗分类(predicate)。这是为了避免不相关的规则在同一 target 上产生误报冲突。系统并不需要一个完整的本体论,只需要一个非常小、可扩展的谓词集合,用来区分“这是关于存放位置的规则”“这是关于权限或权威性的规则”“这是关于证据或生成机制的规则”等。这一步同样可以通过关键词或标签完成,其目标是缩小冲突比较的语义空间,而不是追求精细分类。

def infer_predicate(text: str) -> str:
t = text.lower()
if any(w in t for w in ["authoritative", "canonical", "binding", "truth layer"]):
return "authority"
if any(w in t for w in ["faiss", "semantic index", "vault_index", "index root", "index output"]):
return "index"
if any(w in t for w in ["write to", "stored under", "must exist only at", "reside at", "live under"]):
return "placement"
if any(w in t for w in ["admitted", "accepted", "effective", "governance-valid"]):
return "admission"
if any(w in t for w in ["evidence", "ingest", "payload", "manifest"]):
return "evidence"
return "general"

在完成上述四个要素之后,每一条文档声明在系统中都会被压缩成一个结构化记录:(modality, target, predicate)。到这里,文档已经不再是自然语言集合,而是一个可以被机器枚举、分组和比较的约束集合。

基于这个结构,语义冲突检测就变成了一个纯规则问题:在同一个 (target, predicate) 空间内,是否同时存在互斥的规范性态度(例如 must 与 must_not,allow 与 forbid)。一旦出现这种情况,系统可以直接判定为不可执行状态,并给出精确到声明级别的冲突定位。这里不涉及概率、不涉及模型判断,也不需要人工解释,冲突即失败。

在此之上,可以叠加一个近似重复检测层,用于发现语义上高度相似、但尚未构成直接冲突的声明。这一层可以使用任何向量化或相似度技术来实现,其角色更接近于“治理卫生检查”,而不是硬约束。是否将其视为警告还是错误,完全取决于你对系统严格程度的要求。

整个审计流程的输出应当是机器优先的:结构化结果用于后续自动化处理,人类可读报告用于审查与决策。关键在于,审计必须能够失败,并且失败应当通过明确的进程退出、状态标志或流水线信号向外传播,这样文档治理才能真正进入工程系统,而不是停留在规范建议层。

如果你想在自己的系统中复现这一机制,并不需要复制具体实现。你只需要确认几件事:你是否愿意引入显式的声明式语义单元;你是否愿意接受把自然语言压缩为有限语义维度所带来的约束;以及你是否愿意让“文档语义不一致”像代码编译错误一样中断流程。一旦这三个问题的答案都是“是”,那么无论你使用哪种语言、哪种工具、哪种存储结构,这套“语义昂贵”的文档治理模式都可以被复现出来。

为什么不引入大模型?当然我后期肯定会引入的。但是现在我需要搭建一个完全断开大模型的基层。这个原因我觉得读到这里的人应该都能大概理解。因为你想要的是历史与治理必须由确定性机制承担,模型只能作为建议者,而不能成为裁决者。失败条件是稳定的,系统边界是清晰的。这件事情目前让我感觉上就舒心很多。

硬编码就万能吗?当然不是!它覆盖不了复杂语义。关键词、规则表、枚举谓词,本质上都是低分辨率的认知压缩。它无法理解隐喻、上下文、反讽,也无法自动适应新的表达方式。硬编码会显得笨、慢、保守。每加一个 predicate、每调一个规则,都需要人来做判断。这在早期看起来效率很低。但我恰恰需要这种“慢”。它是一种摩擦机制,用来对抗“生成过快”的系统风险。在一个可以一秒钟生成一百条规则的时代,慢本身就是一种安全设计。它迫使规则的作者为进入核心层付出认知成本。这也是我认为程序员容易陷入的一种精神陷阱,就是很容易把自己抽离。认为自己不是系统机制的一部分。我个人反而因为现在大量自己做项目,容易理解这种“自身必须带入,自身必须收到约束”的想法。

核心当然是Vault Index and Query

好,我们先把系统总图停在这里,剩下的那些“细枝末节”(derived 层怎么落盘、怎么隔离、各种 tools/templates、审计与报告的目录法、生命周期与清理策略)确实规模很大,但它们本质上都是工程卫生问题:只要你的边界清楚(Truth / Decision / Evidence / Derived),再加上写入权限与路径约束,技术实现不会难,更多是“制度一致性”和“长期可维护性”的问题。

我这里真正想展示的,是我的 vault_indexer:它不是一个“更好用的搜索”,而是一个把笔记系统变成证据底座(evidence substrate)的索引机制。现在几乎所有笔记应用迟早都会走到“语义检索 + chunk”这条路,但我在做的时候发现,决定它最终价值的不是检索本身,而是你如何组织证据 chunk、如何让它们具备可引用、可复现、可审计的属性,以及最关键的:这个索引产物在你的系统里到底处于什么层级(Truth 还是 Derived)。

我的做法是把索引严格定位为 Derived:它永远不拥有“真理权”。它只负责把 docs/、sovereign_log/ 这些文本资产,编译成一个面向检索的中间产物:把文档切成稳定粒度的 chunks(通常是段落级或标题-段落组合级),为每个 chunk 生成稳定标识(chunk_id)、保留来源路径、heading/段落位置、以及内容哈希(或可追溯的 digest)。然后对 chunk 文本做 embedding,构建向量索引(FAISS 或同类),最终让你可以用自然语言 query 去命中一组证据 chunks。注意这里“证据”不是泛指相关文本,而是具备引用结构的对象:每个 chunk 都能被精确地指向、被复制到 evidence pack、被后续工具链复用,甚至被审计系统要求“你生成的结论必须引用这些 chunk_id”。

这就直接解释了为什么 LLM 在我这里不是“写作机器”,而是“最佳 query 手”。LLM 的强项不是凭空生成,而是:把一个模糊问题拆解成可检索的子问题、构造有效 query、对返回的证据进行结构化归纳,并把归纳结果映射回开发动作(改哪个文件、加哪个 invariant、补哪个 claim、写哪个 diff)。当你已经建立了信息底座——也就是把核心原则、边界、约束、历史责任都冻结在 Doc / Sovereign_Log 里——LLM 最合理的用法就是站在索引之上,做“证据驱动的开发协作”。你问一个问题,它先检索,再给你一个带引用的证据包(JSON/MD),你再用这个证据包去推进决策与代码,而不是让它用记忆和幻觉替你编故事。

也因此,我的方法和很多以“搜索”为核心的 Obsidian 插件有一个结构性差异:大多数插件的目标是“更快找到笔记”,而我的目标是“让检索结果成为可治理的证据对象”。插件式搜索通常停留在 UI 体验层:关键词或语义匹配 → 打开笔记 → 人脑判断;它们很少解决这些问题:检索命中的内容有没有稳定引用?是否能在 CI/审计里复现同一个结果?检索产物是否会被错误地当成权威?能否形成“问题 → 证据 → 决策 → 代码 → 回写证据”的闭环?而我的 vault_indexer 把检索的输出直接做成一种可落盘、可版本化、可再利用的中间态(pack / report / audit),并且明确把它放在 Derived 层:它可以被重建、可以被替换模型、可以被清理,但不能反向污染 Truth/Doc 的权威性。

换句话说:很多笔记插件把搜索当作“阅读入口”,我把索引当作“开发输入口”。前者优化的是找笔记,后者优化的是把笔记变成工程证据,让 LLM 以“证据分析器 + query 编译器”的身份参与开发。这也是为什么当你的系统底座一旦稳定(规则、边界、历史责任明确),索引检索就不再是锦上添花,而会变成你推进长期工程的主引擎:你不是在“写更多笔记”,你是在用检索把过去的制度与证据,持续地喂回现在的决策与代码。

废话不多说,直接给你看证据。

我们先从一份非常真实的 query_vault 结果说起。需要先说清楚一个前提:这个系统现在还在早期阶段,它不是那种“装完就立刻很神”的工具。它需要你在真实项目中长期使用、长期维护,并且真正把它当成核心系统来用,才会逐渐成长为你自己的“第二大脑”。在这个阶段,检索结果的 score 普遍不会特别高,这是正常现象。对我现在的库来说,0.7 已经算是相当不错、可以认真阅读的命中率了。

原因很简单:语义索引的质量,最终取决于你往里放了什么。你需要一边做真实的开发、一边写真实的规则、一边不断用“已经被你验证过的优质内容”去填充这个库;同时还要持续升级、清理和维护。这个过程是累积性的:越用越好用,越用越省心,而不是一开始就给你“标准答案”。这才是第二大脑应有的成长方式。

从结构上看,一次 query_vault 的 run,本质上只是一个可复现的检索结果对象。它并不试图直接回答问题,而是把“当时系统认为可能相关的证据”列出来。这个对象里最重要的几个字段是:

run_id:这次检索的唯一标识。你可以把它当成一次“证据采样”的编号,后续可以落盘、归档、甚至被审计。

query:你当时输入的原始问题,用于回溯“当时你在想什么”。

model:用于向量化的 embedding 模型,它定义了“相似”的数学意义。

results[]:真正的核心内容——chunk 级别的命中结果,而不是文件级搜索。

每一条 result,都不是“这篇文档命中了”,而是“这一个具体段落(chunk)被认为相关”。因此,每条 result 都带着一组对工程师来说非常关键的元信息:

chunk_id:这个段落的稳定身份。后续引用证据时,你引用的是它,而不是“我记得哪篇文档里有一句话”。

note_path / heading_path / paragraph_index:用于精确定位原文位置。

hash:该段落内容的哈希,用来保证“你现在看到的证据”和“未来审计时看到的证据”是同一段文字。

mtime:最后修改时间,帮助你判断新旧、是否存在语义漂移风险。

score:相似度分数,只是排序信号,不是“正确性”或“权威性”的度量。

snippet:展示用的截断文本,只能当预览,不能当证据全文

所以你要对这个结果有一个非常清醒的认识:

它是一份**“可引用的检索命中清单”**,而不是“已经回答你问题的证据”。

接下来才是关键:你问的是什么问题?你希望这份证据帮你解决什么?

在这次 query 里,问题是:

run session trace ordering

这并不是在问“Run、Session、Trace 分别是什么”,而是在做一次围绕Run / Session / Trace 的存在顺序与合法性(ordering & existence constraints)的证据检索。

换句话说,这是一个非常“硬”的问题。你真正关心的不是定义,而是:

哪些推断是被系统明确禁止的?

哪些顺序关系必须显式声明,而不能从时间或结构中“猜”出来?

这也是为什么这次命中的 chunk,即便 score 只有 0.6~0.7,依然是高价值证据。比如:

明确禁止从 trace 连续性推断 session 存在

明确禁止用时间顺序替代 run / session 的显式声明

明确要求 trace 必须绑定到合法 session,否则就是 non-legitimate

明确区分 Run / Session / Trace 各自回答的问题域

这些内容并不是“百科式解释”,而是制度级约束。它们的价值不在于“讲清楚概念”,而在于防止你和 LLM 在开发过程中犯错。

这也正好引出了 LLM 在这里的正确角色定位。

在这个系统里,LLM 不是用来脑补解释的,而是一个“证据分析器”。它不应该看到 snippet 就开始编故事,也不应该试图用时间顺序、因果叙事去“合理化”缺失的结构。相反,它应该被这些 chunk 锚定住行为边界:

这些推断是被明确禁止的 → 不要做

这些关系必须显式声明 → 如果缺失,就指出缺口

如果规则已经存在但没有被完美回答 → 就用已有证据做锚,而不是重新发明规则

即便这个问题在你的系统里还没有一个“教科书式的最终答案”,0.7 分左右的证据依然有巨大价值:它为 LLM 提供了方向约束,防止概念漂移,防止在日常开发中慢慢把系统“想歪”。

这就是我做这套 vault_indexer + query 机制的初衷:

不是让检索直接给你答案,而是让它在你和 LLM 之间,持续提供一个可以被引用、被校验、被审计的证据锚点。只要这些锚点是稳定的,你的系统就不会在长期使用中悄悄变形。


"run_id": "20260131T014112Z_query_vault_b52ba27830",
"query": "run session trace ordering",
"scope": {
"note_path_prefix": null
},
"topk": 12,
"per_note_cap": 2,
"exclude_temporal_note": false,
"model": "sentence-transformers/all-MiniLM-L6-v2",
"results": [
"chunk_id": "f91b794ab50cc20b12ee18d2a74a532ed5b0630d",
"note_path": "docs/governance/SD-0011_ID_Taxonomy_and_Identity_Ledger.md",
"heading_path": "",
"paragraph_index": 65,
"hash": "ed7cc7a84aa209ae63eb30ef531ab5cfd5cb0a649b8b98da78db3c9d3cf0f73c",
"mtime": 1769822404.9170113,
"score": 0.7674295067787171,
"snippet": "- Trace continuity MUST NOT be used to infer the existence of a session. - Session existence MUST NOT be inferred from trace structure. - Time ordering alone MUST NOT substitute for explicit run or session declaration.",
"boost": {
"prefix": "docs/",
"factor": 1.1
},
"chunk_id": "74abc9e9857e9ee0f805584d3b95dee8c0142f29",
"note_path": "sovereign_log/Session-Run-Trace-Formal Definitions.md",
"heading_path": "",
"paragraph_index": 29,
"hash": "f08025c0500946d913c04bbecbb5ee1ed106120b5d9ecc3f21d9a5254395578b",
"mtime": 1769737995.4226983,
"score": 0.6208187341690063,
"snippet": "- A Run **must exist** before any Session. - A Session **must exist** before Events are promoted. - A Trace **must exist** for any causal claim. - Time ordering **must never replace** trace structure."
},
"chunk_id": "8c355b0da6ce66924ec7fdb83adc71dc6a4e17d7",
"note_path": "docs/governance/SD-0011_ID_Taxonomy_and_Identity_Ledger.md",
"heading_path": "",
"paragraph_index": 60,
"hash": "c056ccfc21a6cd4e9352ed599b679a0018f95bbf828fd0f017fdb9ff6af51c90",
"mtime": 1769822404.9170113,
"score": 0.5683699011802674,
"snippet": "- A `trace_id` MUST be associated with a valid `session_id`. - Trace-level artifacts that lack an explicit session binding are non-legitimate.",
"boost": {
"prefix": "docs/",
"factor": 1.1
},
"chunk_id": "b8ecd51c38bb6cffceb35546af4f27176d67027d",
"note_path": "sovereign_log/Session-Run-Trace-Formal Definitions.md",
"heading_path": "",
"paragraph_index": 32,
"hash": "32a2b22ffaf1ffcabcb49924a30bdcbbf00c46b052403ca5ea32e9ad1739b0c6",
"mtime": 1769737995.4226983,
"score": 0.5365391969680786,
"snippet": "> **Run answers “which execution.” > Session answers “which lifecycle.” > Trace answers “why.”**"
},

我们现在已经非常的操之过急的,习惯于,每次自己有什么问题,马上写prompt,马上要得到答案。然而LLM又非常善于给你编织“完美答案”。这是非常危险的。这就是漂移的根源。

如果你考虑自己弄一个,那么可参考两个核心脚本:index_vault.py; query_vault.py

代码层面的复现其实并不难,真正的难点也不在代码本身,而在于你是否愿意接受这样一套知识治理制度。在现阶段,我是刻意不把 LLM 接入系统执行链路的。我只会把已经生成好的证据(evidence packs)和审计报告,交给 LLM 去“解释”和“建议”。无论你是在交互窗口里用 LLM,还是将来把它接入系统内部,这一点在本质上并不会改变:LLM 的强项是理解问题、组织合适的 query、并在你提供的证据约束下给出建议,而不是替你决定什么是真理。真正决定系统质量的,是你如何看待证据、如何让知识变得可治理。这是我目前非常明确的立场。

因此,这套东西并不是“一个搜索脚本”,而是一个最小可用的 Evidence Retrieval Substrate。它的目标非常克制:

把 vault(Markdown)编译成 chunk 级的语义索引(Derived、可重建、没有真理权)

查询时返回的是可引用的证据单元(chunk_id + 精确定位 + 内容 hash + snippet)

把每一次查询的结果落盘为 evidence pack(JSON + MD),供后续 LLM 和人类在开发中反复引用

如果你要复现,真正需要抓住的并不是 FAISS 或 embedding 模型,而是这三条不变量:

chunk 身份必须稳定、引用必须可追溯、输出必须可重放。

脚本 A:index_vault —— 构建语义索引

技术选型与原理

输入:docs/、sovereign_log/ 下的 Markdown

输出:_system/artifacts/vault_index/(明确属于 Derived 层)

它做的事情本质上是一次“编译”:

1、只在 vault 内扫描 Markdown 文件

2、将每个文件切成段落级 chunks(paragraph chunks)

3、对每个 chunk:

丢弃过短内容(min_chars)

生成一个稳定的 chunk_id

记录最小但关键的元数据(note_path、paragraph_index、hash、mtime)

4、使用 sentence-transformers 将 chunk 文本编码成向量(并归一化)

5、使用 FAISS 构建向量索引(IndexFlatIP,等价 cosine)

6、将索引产物落盘:

meta.jsonl:每一行对应一个 chunk 的身份与来源

index.faiss:向量索引

config.json:索引配置与可复现参数

之所以选择 IndexFlatIP,原因非常简单:在归一化 embedding 的前提下,内积等价 cosine,这是最稳定、最可解释的基线方案。在你真正跑进性能瓶颈之前,没有必要引入 IVF/HNSW 之类的复杂结构。

必须保留的不变量

1、chunk 切分必须稳定

split_to_paragraph_chunks() 的行为一旦改变,paragraph_index 就会漂移,历史引用就会失效。

2、chunk_id 必须与内容绑定

推荐的策略是:hash(path + paragraph_index + content_hash)

这样可以确保:内容一变,ID 必然变化,避免“引用幻觉”。

3、meta 与 index 顺序必须严格对齐

FAISS 向量的顺序,必须和 meta.jsonl 的行顺序一一对应,否则整个索引就不可用。

脚本 B:query_vault —— 查询并生成证据包

技术选型与原理

输入:自然语言 query

读取:_system/artifacts/vault_index/{meta.jsonl, index.faiss}

输出:

_system/artifacts/packs/citations/.json

_system/artifacts/runs/.md

核心流程是:

1、载入 meta 与 FAISS index

2、用同一个模型、同一种归一化方式对 query 编码

3、先做一次宽松检索(raw_k 通常是 topk 的 10 倍以上)

4、再进行后处理过滤:

scope_prefix:限制检索空间

exclude_temporal_note:剔除不应参与治理的内容

per_note_cap:避免单个文件刷屏

5、回到原文读取 snippet(通过 paragraph_index 重切 chunk)

6、进行轻量排序调整(docs_boost / prefix boost)

7、生成 evidence pack(JSON)与 run note(MD),并统一写入 Derived root

这里的关键价值在于:

检索的输出不是 UI 展示结果,而是一个可以被落盘、被引用、被审计的证据对象。

必须保留的不变量

索引模型与查询模型必须一致

否则 embedding 空间不一致,分数没有任何意义。

snippet 只能是展示层

证据的真实身份永远来自 meta(chunk_id / hash),snippet 只是为了让人读得懂。

所有输出必须写入 Derived root

严格限制在 _system/artifacts/ 下,并绑定 run_id,这是保证可重放、不污染 Truth/Doc 层的关键。

最小复现 Checklist(给工程师)

1、明确你的 Vault 输入域(1–2 个目录即可)

2、实现一个稳定的 chunker(段落级是最优起点)

3、定义清晰的 chunk_id 生成策略

4、构建 index 与 meta,并保证顺序一致

5、查询时输出的是“证据对象”,而不是路径列表

6、加上最基本的治理过滤(per-note cap、scope)

普通搜索:找到笔记 → 人脑判断

这套系统:找到 chunk 证据 → 生成 evidence pack → 支持审计 / 引用 / LLM 分析 → 反哺真实开发

索引只是入口,真正的产物是:

可引用的证据单位,以及可以被反复使用和复查的证据包。

写个 wrapper:把 Vault 直接接入真实项目 Repo,边开发边用,边开发边反哺

你在写代码的时候,随时可以 query 自己写过的系统原则、治理规则、历史约束、失败边界;同时你在开发过程中遇到的新问题、新决策、新证据,也会被反向沉淀回 vault。两边一起增长,两边一起防止概念漂移——项目不会因为忙而忘记制度,制度也不会因为脱离实战而空转。

我目前是把 Vault 变成“项目的外置证据底座”

把 sovereign_knowledge 当成一个独立、长期存在的知识/制度库,然后在真实项目 repo 里写两个极薄的脚本:

skq:把“开发中遇到的问题”直接扔给 vault 的 query_vault.py

ski:在你更新了 vault 内容后,重建语义索引(index_vault.py)

这两个脚本的关键价值不是“省打字”,而是把查询变成一种开发动作:

你在写代码时,随时可以从自己的制度库里抽取证据 chunk,生成可落盘的 evidence pack,然后再把 pack 交给 LLM 或自己读,防止概念漂移。

给屏幕前程序员的复现指南

1、把你的知识库 repo clone 到任意路径(例如 ~/sovereign_knowledge)

2、在你的项目 repo 里放两个脚本:

scripts/skq(query)

scripts/ski(index)

3、给执行权限:chmod +x scripts/skq scripts/ski

4、配置一次环境变量(可选):

export SK_VAULT=~/sovereign_knowledge

export PYTHON=python3(或 venv python)

5、日常开发用法:

更新了 vault 内容:scripts/ski

写代码遇到问题:scripts/skq "run session trace ordering" --scope_prefix docs/

这就完成了“边开发边用”的闭环:你不需要把 vault 代码搬进项目,也不需要在项目里维护一套索引管线;你只需要把它当作外置制度底座,随时 query。

一个很关键的点:我为什么认为这种“外置库 + wrapper”比插件更像工程

因为它把检索的输出变成了稳定产物(pack/run note)而不是 UI 瞬时结果;也因为它把“知识治理”从笔记工具里抽离出来,变成可以进入 CI、进入审计、进入代码评审的工程对象。这就是“第二大脑”之所以能长期生长的地方:它不是靠你记得住,而是靠工具链持续生成可追溯证据。

一个多年工程经验的大哥曾经说过,LLM时代,文本和代码要一样多。但是你总不能所有的项目全部塞一个文本库吧。

最后,LLM强大的解构问题能力,设计query能力,并且从证据段中读取只字片语,生成建议的能力。这是现阶段,这个办法可以在你密集使用LLM的同时,减轻焦虑的一个办法。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
中方一桶石油不买,鲁比奥急了,开口就抹黑中国,却被自己人打断

中方一桶石油不买,鲁比奥急了,开口就抹黑中国,却被自己人打断

有你便是晴天呢
2026-02-01 07:09:10
收评:三大指数均跌超2% 全市场超百股跌停

收评:三大指数均跌超2% 全市场超百股跌停

财联社
2026-02-02 15:02:16
爱泼斯坦案最新文件曝光,西方“吃人”社会大揭秘!

爱泼斯坦案最新文件曝光,西方“吃人”社会大揭秘!

枫冷慕诗
2026-02-02 13:35:20
A股跌到4015,尾盘已表明,不出意外,明天周二,很可能这样走

A股跌到4015,尾盘已表明,不出意外,明天周二,很可能这样走

阿纂看事
2026-02-02 16:22:02
现货黄金跌破4500美元/盎司

现货黄金跌破4500美元/盎司

界面新闻
2026-02-02 13:54:53
郑丽文再发声:大陆是我们的亲人

郑丽文再发声:大陆是我们的亲人

扬子晚报
2026-02-02 16:46:11
全球多名权势人物被曝与爱泼斯坦关系密切,特朗普:我清白,我要起诉

全球多名权势人物被曝与爱泼斯坦关系密切,特朗普:我清白,我要起诉

上观新闻
2026-02-02 14:18:29
震惊!奔驰女追尾后立刻换上"公安"大衣,"亮证姐"后继有人了?

震惊!奔驰女追尾后立刻换上"公安"大衣,"亮证姐"后继有人了?

派大星纪录片
2026-02-02 15:53:19
知名音乐人袁惟仁去世,享年57岁

知名音乐人袁惟仁去世,享年57岁

极目新闻
2026-02-02 17:50:41
60岁老人猥亵7岁女童,想赔三万换谅解书

60岁老人猥亵7岁女童,想赔三万换谅解书

中国新闻周刊
2026-02-02 16:52:53
天降横祸!龙门吊倒塌致1死1伤,后方黑车司机:当天是我生日!

天降横祸!龙门吊倒塌致1死1伤,后方黑车司机:当天是我生日!

乌娱子酱
2026-02-02 12:59:08
《名侦探柯南》与辱华漫画联动,紧急声明!

《名侦探柯南》与辱华漫画联动,紧急声明!

极目新闻
2026-02-01 10:34:47
青海省委组织部部长调整

青海省委组织部部长调整

新京报政事儿
2026-02-02 16:11:37
这种朋友圈不能发!广州近期多人被抓,警方提醒

这种朋友圈不能发!广州近期多人被抓,警方提醒

番禺台
2026-02-02 13:57:39
特斯拉中国宣布二月新优惠,上架大量新车现车!

特斯拉中国宣布二月新优惠,上架大量新车现车!

XCiOS俱乐部
2026-02-01 20:33:39
起风了!美通过3大涉台法案,岛内启程赴陆,郑丽文对陆称呼已变

起风了!美通过3大涉台法案,岛内启程赴陆,郑丽文对陆称呼已变

梁讯
2026-02-01 14:42:51
前知名调查记者刘虎失联,与四川稿件有关?

前知名调查记者刘虎失联,与四川稿件有关?

记录刘杰
2026-02-02 13:48:28
炸裂!一女生自曝交过外国男友,回国后因“型号”问题做了修复术

炸裂!一女生自曝交过外国男友,回国后因“型号”问题做了修复术

谈史论天地
2026-02-02 13:55:09
暖心!21岁皇马天才97分钟罚丢绝杀点球 当场泪奔:1万人唱歌鼓励

暖心!21岁皇马天才97分钟罚丢绝杀点球 当场泪奔:1万人唱歌鼓励

风过乡
2026-02-02 08:13:21
“高官” 王文涛

“高官” 王文涛

星辰故事屋
2026-02-02 11:45:44
2026-02-02 18:11:00
Susan STEM incentive-icons
Susan STEM
熵控理论将混乱、高熵的语言转化为结构化、可执行的认知单元。
54文章数 20关注度
往期回顾 全部

科技要闻

阿里筑墙,腾讯寄生,字节偷家

头条要闻

小鹏机器人首秀摔了 此前因步态太拟真被疑"真人套壳"

头条要闻

小鹏机器人首秀摔了 此前因步态太拟真被疑"真人套壳"

体育要闻

澳网男单决赛,属于阿尔卡拉斯的加冕仪式

娱乐要闻

周杰伦带王俊凯陈奕迅聚餐 畅聊音乐

财经要闻

商品期货暴跌 全球股市遭遇"黑色星期一"

汽车要闻

雷克萨斯LC500将于今年底停产 "最美雷克萨斯"谢幕

态度原创

艺术
教育
旅游
家居
时尚

艺术要闻

马斯克花5万买的折叠屋,是预制住宅的未来吗?

教育要闻

养孩子要花68万?教育降级的风来了,聪明的家长这样“精准养娃”

旅游要闻

冬日探秘好去处 枣庄熊耳山奇石秘境等你来

家居要闻

现代几何彩拼 智焕童梦居

普通人衣服没必要买太多,准备好这些单品,简单实用又耐看

无障碍浏览 进入关怀版