卡片召唤师
精华
|
战斗力 鹅
|
回帖 0
注册时间 2022-10-11
|
本帖最后由 王牛子 于 2026-3-3 11:50 编辑
发完这贴之后lz感觉还是不满足,感觉架构还是太草台了,比如强依赖n8n外部编排、webui是用streamlit写的,响应太慢功能也少、推荐算法太简陋。
但最重要的是,我发现其实bot完全就是个伪需求:
既然我都把推荐算法做出来了,为啥要把自己框在telegram bot这个极不方便的交互里呢?比如我想要推荐还得在telegram打字给agent,LLM没了系统就用不了,而实际上推荐算法,搜索算法是完全不需要LLM参与的,直接刷推荐瀑布流他不香吗?还能顺便进一步降低对硬件的要求。
这成为了我重构架构的主要原因。
在那之后我又踩了很多坑,把前端从streamlit重构成了Vue3, 尽量贴合最佳实践。现在的版本代码量已经膨胀到了数万行,包含 18+ 个微服务,彻底变成了一个带 WebUI、带硬核推荐算法、带独立大模型 Agent 中枢的“企业级 SaaS”应用。目前镜像已经打包推上了 DockerHub,支持 0 配置冷启动。
以下是重构后系统的核心特性
1. 抛弃现成方案,手写三场势能“物理学”推荐引擎 以前的推荐只是简单拿向量算个距离,现在我把它做成了真正的推荐流。系统会实时计算一个基于三场势能的打分器:
标签偏好场 (U_tag):对你的历史阅读标签做频率平滑处理。
视觉聚类场 (U_vis):用 Scikit-learn 对你最近看过的本子封面跑 KMeans 聚类,提取几个“核心审美质心”,新本子计算 L2 距离。
实时反馈动态场 (U_profile):上面两个主要是基于半静态的阅读记录,为了实现更动态的推荐系统,我在库里维护了一个 1024 维的基础向量,你的每次操作(点击、曝光、阅读、点踩)都有不同的学习率(Alpha,比如踩是 -0.15,看是 0.05),你的 XP 向量是在实时进化的。
最后,三个场合并为总势能,套用物理学里的玻尔兹曼分布 (exp(-U_total / T)) 计算最终推荐概率。使用公式里的温度T,我添加了一个温度(探索度)的设置,调高温度 T,给你塞点新奇的私货;降低温度,就死死锁住好球区。
2. 可插拔的大模型 Agent 与“三级记忆”系统 我把 n8n 的核心编排逻辑抽回了后端,重写了一个 hunterAgent 中枢,并为它设计了三级记忆机制来防止 LLM 上下文溢出:
短期记忆:最近的高频 Tag 和点踩屏蔽 Tag。
长期记忆:大模型根据你的阅读历史总结的宏观偏好。
语义记忆 (Semantic Facts):使用 PgVector 向量检索,只把和当前对话相关的记忆事实动态注入进 System Prompt。 你现在直接和系统内置的战术副官对话,她完全记得你的癖好,还能根据混合检索(RRF)找出来的结果,给你写包含“邀功请赏”的推荐简报。
3. “SaaS级” Vue3 仪表盘与 XP 3D地形图 没有 UI 实在太痛苦了。用 Vue3 + Vuetify 写了个完整的前端:
自带 Setup Wizard (安装向导),支持0配置冷启动,界面甚至做了鼠标互动的动态特效(类似Apple Watch那种中间大两边小的效果)
之前 V1 做的 XP 散点图,现在不仅保留了 PCA 降维,我还上了 scipy.stats.gaussian_kde,直接把 2D 坐标算成了高斯核密度估计,在前端渲染出一个你专属的 XP 3D 潜在地形图 (Potential Surface),你的 XP 到底是个什么形状一目了然。
为了能让我自己在移动端上用着舒服点我还加了PWA支持,启动需要经过HTTPS协议不然浏览器不会触发安装。
4. 尽力确保最高安全性与国内网络容灾 因为是要对外发布的项目,而且毕竟这要处理的数据大家懂得都懂,我在这方面下了血本,目标是就算被脱裤核心鉴权信息也不会泄露(被迫学习防御性编程):
安全防御:拒绝脆弱的鉴权,上了 PBKDF2 + 动态 Salt + 环境变量 Pepper。前端危险设置区域必须输入密码解锁(Sudo提权机制)。生成 10 个用后即焚的恢复密钥(类2FA)单向哈希存入配置,防数据库填错导致锁死,顺便做了只有 15 分钟寿命的无状态 HMAC 签名 Token 来进应急恢复模式。
网络容灾 (针对 EH 缩略图加载):国内看 EH 大家都懂,网络波动极大。我重写了代理层,上了幽灵加载、带互斥锁的长连接 HTTP Client。请求失败不仅会自动多级退避重试,还能动态切换 CDN(表站里站动态重试),最后把图片落入本地 Cache 缓存。
以下是系统的新架构:
目前整个应用基本已经打磨完成自用中,我自己也上传了dockerhub镜像,不再需要本地编译了,欢迎大家体验,更多技术细节,源码审阅,部署指南请参考GitHub仓库:
https://github.com/jdiosajiof/AutoEhHunter
---------------------------------------------------重构前的版本--------------------------------------------------------
lz 本来一直在寻找安卓端更好的漫画阅读器方案,最后跌跌撞撞选定了 LANraragi (后端) + Mihon (前端插件) 的组合。这套方案管理本地库确实稳而且方便使用,但当我把上千本元数据刮削完之后,发现搜索体验依然很蛋疼:
除非我把每个 Tag 都背下来,否则搜 "黑丝" 搜不出 "pantyhose",搜 "老师" 漏掉 "tutor",或者我我想找“那种画风很实用,剧情偏纯爱但带点重口”的本子,传统关键词搜索根本无能为力。最让我蛋疼的是Mihon 的lrr插件居然连阅读状态都不会回传给服务器,所有历史只存在手机本地,跟服务器端完全解耦,换个设备进度全丢。
正好最近在研究 n8n 和 RAG,突然想到既然现在 LLM 和多模态向量模型这么强,为什么不能给我的本子库做一个“图书管理员 Agent”?
于是花了两个礼拜,借着Opencode的辅助,也是为了测测现在的Coding Agent到底能做多复杂的项目整个压力测试,手搓了一套支持多模态检索、XP聚类分析、自动推荐的 Agent 工作流。现在发出来分享下架构细节和踩的坑。
【架构设计】
因为我本身就不咋会写代码,为了不把系统写成一坨没办法debug的垃圾,我参考了控制面/数据面的设计思路,统一IO,让AI做了很多防御性编程,这样出了问题我至少能问出来为什么,进而用自然语言进行debug,整个项目基于 Docker Compose 编排,分为三个平面,包含 5 个核心容器(LANraragi, n8n, pgvector, compute, data):
1. 控制面 (Control Plane) - n8n
角色:大脑/指挥官。
功能:负责接收 Telegram Bot 的自然语言指令,进行意图路由(是搜图?还是看历史?还是推荐?),然后编排底层的 API 调用。
如果要改的话把业务逻辑从代码里剥离出来,改流程拖拽一下就行,不用重写后端。最近还看到个astrbot,感觉那个也可以接入,因为我项目主要是后端,电报只是层皮而已。
2. 算力面 (Compute Plane) - Python/FastAPI
角色:视觉与语言中枢。
核心模型:
SigLIP (Vision):当时选型的时候问AI啥视觉模型比较好推荐了这个,搜了下看起来比 CLIP 强在多语言理解和细节捕捉,专门用来做“以图搜图”和“视觉特征提取”。
BGE-M3 (Text):用来做文本 Embedding,支持多语言长文本,平时用openwebui也是必备,所以选了。
功能:提供向量化服务、XP 聚类算法(KMeans)、RRF(倒数排名融合)重排序。这里我特意把计算节点做成了无状态的,方便以后把这部分丢到显卡性能更好的机器上,实现存算分离。
粗测了一下Top10召回率,纯搜图的话封面彩页大概有个7-80%,但是非常依赖作者画风的一致性,因为我感觉SigLIP更侧重页面整体的配色和姿势而不是具体的画风。这点在搜黑白内页的时候有体现,即便我感觉画师的风格非常特别,SigLIP有时候还是会失败,Top10召回率估计在6-70%,整体来说更随机。
3. 数据面 (Data Plane) - Postgres (pgvector) + LANraragi
角色:记忆体。
功能:LANraragi 负责文件管理;Postgres 17 配合 pgvector 插件存储几十万维度的向量索引(HNSW)。放弃了 ES,直接用 PG 做向量库,运维成本低很多。正好nextcloud也用postgres,比较熟。整个库专门为EH标签做了优化,并且支持动态抓取EHTagCN标签翻译把翻译后的中文标签入库用于中文检索。
【技术干货与踩坑记录】
1. 真正的“语义搜索”:RRF 混合检索
单纯用向量搜容易搜出“意思对但字不对”的,单纯用关键词又太死板。
我上了一套 RRF (倒数排名融合),把 SigLIP 的视觉向量结果、BGE 的文本向量结果、以及传统数据库的 Tag 匹配结果进行加权融合。
效果:即使本子没有打 "stockings" 的标,只要封面或内页里画了黑丝,SigLIP 也能把它捞出来。实际跑的时候还能定制Agent的性格,整点角色扮演,目前我给的词比较素,但qwen感觉在放飞自我方面比较在行。
2. XP年报?:KMeans + PCA
这是我觉得最好玩,也是我非常想做的功能,因为我非常好奇自己既然下了这么多本子,没个什么“年终报告”或者“XP分析”感觉没那味。我把库里所有本子的向量扔进 KMeans 聚类,然后用 PCA 降维到 2D 平面画了个散点图。
结果非常直观:
左边一坨是“同人志/剧情向”,右边一坨是“单行本/实用向”。
中间红色的聚类精准命中了我的核心 XP(比如捆绑/特定服装),连接了剧情和视觉。
听了相关专业朋友的建议还整了个“XP 进化树”,把层次聚类也加进去了,看自己是怎么从纯爱战神一步步堕落的(x
3. 解决并发竞争:Postgres 的黑科技
在写爬虫队列(eh_crawler)时,遇到了多 worker 同时抢任务的问题,具体是爬虫会写URL到文件,但EH入库那边又会读URL,入库完了会把URL删掉,那删的时候很可能就会把这之间新加入的URL给一起删掉,导致漏抓或者竞态。
本来想用 Redis 锁,后来发现 Postgres 有个神技:SELECT ... FOR UPDATE SKIP LOCKED。
直接把数据库当队列用,原子性操作,既省了 Redis 组件,又解决了并发冲突。
4. 完成数据闭环:修改 Mihon 源码
为了解决历史记录不同步的问题,我硬着头皮去改了 Mihon (Kotlin) 的LANraragi扩展的源码。现在阅读器每翻一页,都会静默上报进度到我的后端。这样 Agent 不仅知道我“存”了什么,还知道我“真正爱看”什么(而不是存了不看)。
【总结】
这项目本质上是用企业级的架构(RAG、向量数据库、微服务编排)去解决我自己的一个非常原始的需求(看本子)。
虽然代码大半是 AI 辅助写的,但架构设计、数据流转、竞态处理这些坑还是得自己一个一个填,感觉学到了不少实战经验(必可活用于下一次)。
目前这套系统已经跑通了 Telegram 对话 -> 意图识别 -> 多模态召回 -> 结果推送的完整闭环。
讲真的就tg发图,文本搜索或者是要EH推荐的时候,Agent 立刻把库里和库外画风相似或者是对我XP的本子甩我脸上的时候,那种成就感真的比改 Tag 强太多了。
不过这套系统还没有经过我的长期验证,我也不确定推荐得准不准,也欢迎大家试用之后给点反馈。
如果大家对本地向量库部署或者 n8n 工作流编排感兴趣,可以在楼里交流,以下是代码仓库:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
评分
-
查看全部评分
|