Skip to content
阅读进度

如何理解? ​

返回 EachOf 项目 目录

项目版本说明

这些问答整合历史设计与实现资料;当前 main 分支 README 以工作包描述建设状态。具体能力、实验数据与设计目标的边界见项目状态与证据。

标准回答 ​

EachOf 是我做的 AI 长期记忆项目,用来保存项目背景、偏好、决定和来源,让不同会话、不同 Agent 按权限接着使用。写入由 Python 处理器提取候选、Go Core 校验入库;读取采用关键词和向量混合检索。重点是信息纠正或撤销后,检查旧结论和缓存答案还能不能继续使用。

深入解释 ​

**用一个例子收尾:**之前决定“日志保留 30 天”,后来改成“7 天”。新 Agent 要能查到新规则,基于旧规则生成的结论也要检查是否失效。

**准备自己的贡献:**补充你实际负责的模块、解决的一次具体故障和验证方式。不要把所有仓库功能都说成自己独立完成。

查看对应实现讲解

补充解释与边界 ​

不需要每记一条信息就重新训练模型。做法是把重要信息持久化到外部数据库,新问题来了再检索相关内容,放进模型这次的上下文。记忆服务负责存和查,Agent 或应用负责把结果提供给模型。

基本流程:提取 → 存储 → 检索 → 提供上下文。数据库里有数据,不等于模型已经知道;还要真的把检索结果传给它。

可以类比开卷答题:数据库是资料库,上下文是这一次放到桌上的材料。

补充解释与边界 ​

RAG 主要描述“先检索资料,再生成回答”的过程,EachOf 也会用到。EachOf 还管理长期信息的来源、状态、权限、纠正和撤销。聊天记录是原始历史,其中的猜测、旧方案和确认决定不能都当成当前事实。

例如“我考虑用 MySQL”与“最终决定用 PostgreSQL”,都可能出现在聊天里;长期记忆需要区分试探和确定决定。

成熟 RAG 系统同样可以实现版本和权限管理,所以要比较具体能力,不要声称所有 RAG 都只会存文档。

补充解释与边界 ​

Go Core 负责接口、权限、检索、任务调度和正式写入;Python 负责抽取、向量化等模型计算。PostgreSQL 保存数据,pgvector 支持向量检索,S3 兼容存储放原始对象。分开后能独立替换和重启处理器,代价是增加部署和协议维护成本。

**最关键的边界:**处理器不能直接连接数据库,只能交候选结果,由 Core 校验提交。这样算法变化不必获得平台全部写权限。

Next.js Console 给人查看和纠正;API / SDK / MCP 给程序和 Agent 调用。

补充解释与边界 ​

Embedding 是用模型把文本转换成一组数字,也叫向量。这个向量用于表达文本特征,让意思接近的文本在向量空间里更容易被找到。例如“怎么减少启动耗时”和“冷启动优化”用词不同,但语义相关。

**教学示意:**一句话变成[0.12, -0.35, 0.81, …]。真实维度由模型确定,常有几百或几千维。

每个数字不是人工规定的“速度”“Android”等标签,而是模型学到的特征。相似度高只说明表达相关,不能证明事实正确。

补充解释与边界 ​

以常见文本 Embedding 模型为例:先把文字切成 token,再用 Transformer 编码,得到带上下文信息的 token 向量;最后通过平均池化、取特定位置等方式得到整段文本的向量,有时还会做归一化。训练时常用对比学习,让相关文本靠近、不相关文本远离。

**分词:**把文本转成模型能识别的 token 编号。

**编码:**Transformer 的注意力机制让一个 token 的表示结合周围内容。例如“苹果手机”和“苹果很好吃”,相同词会有不同上下文表示。

**池化:**把多个 token 表示变成一个句子表示。具体模型可能用平均、CLS、最后一个 token 等方式,不能断言全部都取平均。

**对比学习:**用“查询—相关文档”等正样本和负样本调整模型参数,形成适合检索的向量空间。不是你存资料时现训练,也不是你在 EachOf 里从零训练了一个模型。

补充解释与边界 ​

常见方法有余弦相似度、点积和欧氏距离。余弦相似度比较向量方向,越接近 1 通常表示方向越接近。实际选择要匹配模型的训练方式和推荐配置。

cos(a,b) = (a·b) / (||a|| × ||b||),即点积除以两者长度。非零向量的余弦范围为 -1 到 1,它不是“正确概率”。

两个向量都归一化为单位长度后,点积等于余弦相似度。pgvector 的<=>返回余弦距离,即1 - 余弦相似度,距离越小越近。

“相似度多少算相关”没有通用阈值,需要结合模型和数据验证。

补充解释与边界 ​

查询向量与资料向量必须来自兼容的向量空间,通常用同一个模型和版本,并遵守各自的查询、文档编码规则。只要维度一样,仍不代表可以混用。更换不兼容模型时,需要重新生成资料向量并完成索引迁移。

有些模型要求 query 和 document 用不同前缀或入口;它们仍属于经过配套训练的空间。

**EachOf 已有机制:**查询服务与 Core 检查模型身份、版本、维度、向量长度及数值有效性。换模型时可以设计新旧索引并行重建与切换,但不要未经核对就称它已是项目完整上线流程。

补充解释与边界 ​

向量很少时可以逐条计算距离,叫精确检索。数据量大时可用近似最近邻索引减少比较。HNSW 把向量连成多层邻近图,先在上层快速找到大致区域,再向下层寻找更近的结果,用一部分召回率换速度。

参数理解:m影响图连接数量;ef_construction影响构建时搜索范围;ef_search影响查询时搜索范围。增大范围通常提高找到近邻的机会,也增加计算或内存成本。

HNSW 是通用原理。本项目是否使用索引、索引是否生效,要看当前维度、数据库配置和执行计划,不能声称每次查询都走 HNSW。

补充解释与边界 ​

Embedding 把问题和资料分别编码,适合从大量资料里快速找候选。Reranker 把问题与少量候选一起评估,用于更细地重排。生成模型再结合选出的资料组织答案。它们分别解决“找候选、排顺序、写答案”。

常见两阶段设计是先召回几十条,再精排到几条,但条数要按预算调整。

**项目口径:**EachOf 已有混合检索与排序;不能直接把“独立 Cross-Encoder Reranker 已上线”说成事实,本次没有核实该实现。可以把它作为排序不足时的候选改进方案。

补充解释与边界 ​

请求进入 Core,创建 Operation 和内部 Task。Python Worker 领取任务,从输入里提取候选记忆,再交回 Core。Core 检查候选结构、任务、来源与策略后幂等入库;当前抽取实现先标为 suggested,后续确认。需要检索的内容还会生成对应向量。

**说清输入输出:**输入是对话或资料;中间结果是候选陈述;正式保存的是内容、Space、来源、状态、时间等数据。网页场景还可能有抓取、合并和归纳任务。

代码入口:core/internal/operations/commit.go中的DefaultCommitter.Commit、commitExtract。

“请求已接收”只代表开始处理,不代表抽取和向量化已经完成。

补充解释与边界 ​

先确认调用者能访问哪些 Space;关键词检索查明确词语,查询 Embedding 则用于查语义相近的内容。合并排序后,只返回权限允许、来源可用、状态和版本仍适用的记忆,并控制条数与 token 预算。Agent 再把这些内容用于当前回答。

**写入与读取的区别:**资料向量通常预先生成并存储;用户问题的向量在查询时生成。真实模型场景使用独立查询向量服务的同步调用。

代码入口:handlers_memories.go的Recall,以及memory/service.go的RecallProjection。

权限与有效性可以在多个层次校验,不能先让无权限内容进入上下文,再靠模型忽略它。

补充解释与边界 ​

关键词检索擅长型号、API 名称等准确词语,向量检索擅长同义表达。EachOf 当前排序实现采用多信号加权:综合关键词、语义、有效时间匹配、使用反馈和来源可信度,置顶还有加分。新近程度用于分数近似相同的结果之间排序。

**追问 RRF:**对每路结果按排名贡献分数,形式为Σ 1 / (k + rank),再求和排序;这样不必直接比较不同通道的原始分数。

**讲项目时:**目前已核对 EachOf 使用混合召回与排序,但本次没有逐行核对融合公式、权重和候选数。上面的 RRF 是可解释的通用方案,不要硬说就是项目现用实现。

补充解释与边界 ​

记录派生结论依赖的来源及语义版本。比如“保留 30 天”改成“7 天”,来源版本变化,依赖旧版本的结论就不能继续当成当前事实;答案缓存也要检查引用依据。后台可以重新计算,读取时先避免返回已无效的旧结果。

**并发例子:**Worker 正在用版本 1 计算,用户改成版本 2。提交时要比较快照与当前版本,避免迟到的结果把旧事实重新写回来。

代码线索:candidate_refs.go检查SemanticRevision;读取/提交路径检查IsClaimInferenceCurrent。

补充解释与边界 ​

Space 是共享和权限边界,Core 根据调用者身份与授权限制读写范围。MCP 让 Agent 通过标准协议调用记忆能力;它负责接入方式,权限和数据规则仍由 Core 执行,也不保证 Agent 会自动调用或正确使用记忆。

连接同一服务的两个 Agent,可能有不同授权、查询和上下文预算,因此不一定得到同样内容。

撤销权限后,应限制后续受控读取;已发给外部 Agent 的文本,不能保证从对方历史或文件里自动删除。

补充解释与边界 ​

任务有租约和心跳,Worker 失联后可以重新分配。重试可能导致重复执行,所以采用“至少一次执行 + 幂等提交”:允许计算重做,但重复提交不能重复产生权威记录。旧执行者迟到的结果还要检查资格和来源版本。

网络回复丢失时,客户端不知道提交是否成功,这就是重复请求很常见的原因。幂等关注业务副作用,不保证模型每次输出相同。

抽取提交中使用确定性标识和已存在检查等方式处理重复写入。Operation 的同一幂等键配同一请求可复用原操作,换了输入则应冲突。

补充解释与边界 ​

撤销时,把撤销状态、日志和待处理事件一起持久化,避免“状态已经改了,后续通知却丢了”。读取先根据撤销状态阻止使用,后台再消费事件做隔离、索引清理等工作。

Outbox 就是数据库里的待处理通知记录。事务保证业务变更和通知记录一起成功或失败,后台通过重试继续处理;消费者仍要能应对重复事件。

补充解释与边界 ​

项目既要管理关系、权限、版本、任务和事务,又需要向量检索,PostgreSQL + pgvector 可以把这些能力放在较统一的数据体系里,减少多套存储同步的复杂度。代价是向量规模、索引内存和混合查询性能仍要实测。

独立向量库可能更适合某些大规模或特定检索负载,但会增加部署与一致性处理。技术选择要结合实际规模,不要说一个方案永远更快。

原始对象放 S3 兼容存储,数据库保存相应元数据和关系。

补充解释与边界 ​

慢就分段量耗时:查询向量生成、数据库检索、融合过滤、答案生成;效果差就检查资料是否入库、向量是否匹配、候选是否找到、正确结果是否排得太后。EachOf 查询向量服务失败时会降级为关键词召回,并返回语义通道不可用标记。

**优化思路:**固定数据测召回质量;检查索引与执行计划;减少无效候选;必要时考虑精排。改变模型、过滤或缓存时,要重新验证权限和旧内容失效。

Embedding 不应因服务失败就偷偷换不兼容模型,继续与旧向量比较。

补充解释与边界 ​

分别检查机制正确、检索找得准、回答用得对、真实任务有收益。检索看 Precision@K、Recall@K、MRR;机制看越权、撤销、版本变化和重复提交等测试。过去的小样本提升必须带上模型、基线和数据条件,不能直接说整体准确率或竞品领先。

**简单记:**Precision 看“返回的有多少对”;Recall 看“该找的找回多少”;MRR 看“第一条相关结果排多前”。

前 5 条有 4 条相关,Precision@5 是 80%。如果全部应找回的有 10 条、其中找回 4 条,Recall@5 是 40%;具体评测也可能采用查询级命中口径,需说明定义。

本次读取的仓库调查记录过排序与评测适配问题。可以讲这些实际发现和后续改进,不把历史“提升 3.75 个百分点”无条件当作当前结论。

内容来源 ​

用完整回答理解机制,用真实证据解释项目。