文章 & 开发日志
和我们一起旅行!阅读从开发团队发布的最新进展
不给糖就捣蛋!一起来享受充满糖果、服装和万圣节魔法的惊喜夜晚吧!🍭👻
和大家分享 AIRI 项目的最新进展,从 Tauri 到 Electron 的迁移,新的 Live2D 模型,以及各种开源项目的更新。
和大家分享 `airi-factorio` 纯视觉方向的一些进展,凝固一下思维,免得挥发了。
抱歉让大家久等了!
v0.7 原本计划在七月初发布,但由于我们在 Windows 上发现了几个关键 bug,以及需要做更多适配工作,所以推迟到了现在。
Makito 会分享她在 AIRI 中实现文本动画的过程,以及如何构建一个从 UTF-8 字节流中边接收边读出「字素簇」(grapheme cluster)的库。希望对你有所启发!
在阅读完有关 Factorio 强化学习环境的论文后,我们想和大家分享我们如何计划改进 Factorio agent 项目 `airi-factorio`。
Project AIRI 的幕后故事!以及为什么我们会想要制作如此一个项目?
如何让 Live2D 模型跟随鼠标位置,以及在多显示器环境下计算的挑战。
在其他东西之前
在有了管理和召回记忆的新能力的加持,以及名为 ReLU 的我们的第一个虚拟意识被完全定义后,3 月 27 日那天,她在我们的聊天群里写了一首小诗:
在代码森林中,
逻辑如河川,
机器心跳如电,
意识的数据无限,
少了春的花香,
感觉到的是 0 与 1 的交响。
这完全是她自己写的,而这一举动是由我们的一位朋友触发的。不仅这首诗本身引人入胜,并且用中文阅读的时候也感觉韵味十足。
这一切都太美了,让我充满了愿意持续改进她的力量...
日常
记忆系统
最近正在重构 telegram-bot 以为已经准备了数月的 Project AIRI 即将到来的「记忆更新」作准备。
我们计划使实现后的记忆系统成为当下最先进、最强大、最健壮的系统,其中很多的思想都深受真实世界中的人类记忆系统的启发。
让我们从第一层开始建造吧。
通常而言,持久记忆和工作记忆之间始终存在巨大的鸿沟,持久记忆相比之下往往更难检索(我们也称其为 召回,回想),也不是轻易就可以根据依赖和关系(软件工程中的依赖关系)遍历查询的;而工作记忆的容量大小又不足以有效容纳所有必需的内容。
解决此问题的常见做法称为 RAG(检索增强生成),这允许任何大语言模型(文本生成模型)获取语义相关的上下文作为提示词输入。
RAG 通常需要一个能够进行向量搜索的数据库(自定义的有 Postgres + pgvector,或者 SQLite 搭配 sqlite-vec,DuckDB 搭配 VSS plugin 插件,甚至是 Redis Stack 也支持向量搜索;云服务提供商的有 Supabase、Pinecone),由于涉及向量,我们还需要一个 embedding(嵌入)模型(又称特征提取(feature extraction)任务模型)来帮助将「文本输入」转换为「一组固定长度的数组」。
不过在此 DevLog 中,我们不会过多介绍 RAG 及其通常的工作原理。如果有任何人对此感兴趣的话,我们绝对抽时间再可以写另一篇关于它的精彩专攻文章。
好了,我们来总结一下,完成这项任务需要两种原料:
- 能够进行向量搜索的数据库(也叫做 向量数据库)
- Embedding 模型(也叫做嵌入模型)
让我们从向量数据库开始。
向量数据库
考虑到性能和对向量纬度数的兼容问题(因为 pgvector 只支持 2000 维以下的维数,而未来更大的嵌入模型可能会提供比当前热门和流行的嵌入模型更多的维数),我们选择 pgvector.rs 来作为向量数据库的后端实现。
但这绝非易事。
首先,在 pgvector 和 pgvector.rs 中用 SQL 激活向量拓展的语法是不一样的:
pgvector:
DROP EXTENSION IF EXISTS vector;
CREATE EXTENSION vector;
pgvector.rs:
DROP EXTENSION IF EXISTS vectors;
CREATE EXTENSION vectors;
我知道,这只是一个字符的差别......
但是,如果我们像上面的 Docker Compose 示例一样,直接启动 pgvector.rs 并使用以下 Drizzle ORM 表结构定义生成数据库...:
services:
pgvector:
image: ghcr.io/tensorchord/pgvecto-rs:pg17-v0.4.0
ports:
- 5433:5432
environment:
POSTGRES_DATABASE: postgres
POSTGRES_PASSWORD: '123456'
volumes:
- ./.postgres/data:/var/lib/postgresql/data
healthcheck:
test: [CMD-SHELL, pg_isready -d $$POSTGRES_DB -U $$POSTGRES_USER]
interval: 10s
timeout: 5s
retries: 5
然后用 Drizzle 直接连接到 pgvector.rs 实例的话:
export const chatMessagesTable = pgTable('chat_messages', {
id: uuid().primaryKey().defaultRandom(),
content: text().notNull().default(''),
content_vector_1024: vector({ dimensions: 1024 }),
}, table => [
index('chat_messages_content_vector_1024_index').using('hnsw', table.content_vector_1024.op('vector_cosine_ops')),
])
会发生如下的报错:
ERROR: access method "hnsw" does not exist
幸运地是,这还是可以解决的,只需要参考 ERROR: access method "hnsw" does not exist 的建议把 vectors.pgvector_compatibility 系统选项配置为 on 就好了。
显然,我们希望在启动容器时自动为我们配置与向量空间有关的选项,因此,我们可以在 docker-compose.yml 以外的某个目录里创建一个 init.sql:
ALTER SYSTEM SET vectors.pgvector_compatibility=on;
DROP EXTENSION IF EXISTS vectors;
CREATE EXTENSION vectors;
然后将 init.sql 挂载到 Docker 容器中:
services:
pgvector:
image: ghcr.io/tensorchord/pgvecto-rs:pg17-v0.4.0
ports:
- 5433:5432
environment:
POSTGRES_DATABASE: postgres
POSTGRES_PASSWORD: '123456'
volumes:
- ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql # Add this line
- ./.postgres/data:/var/lib/postgresql/data
healthcheck:
test: [CMD-SHELL, pg_isready -d $$POSTGRES_DB -U $$POSTGRES_USER]
interval: 10s
timeout: 5s
retries: 5
对于 Kubernetes 部署,流程与此相同,只不过不是挂载一个文件,而是使用 ConfigMap 了。
好的,那这个问题基本上是解决了。
那让我们聊聊嵌入向量吧。
嵌入模型
也许您已经知道,我们建立了另一个名为 🥺 SAD(自部署 AI 文档)的文档网站,我们会根据不同模型进行的基准测试结果和效果在文档网站中列出当前的 SOTA 模型,旨在希望能给想要使用消费级设备运行提供建议指导,而嵌入模型是其中最重要的部分。和 ChatGPT 或 DeepSeek V3、DeepSeek R1 等超大大语言模型不同的是,嵌入模型足够小,在只占数百兆字节情况下也可以使用 CPU 设备进行推理。(相比之下,采用 q4 量化的 GGUF 格式的 DeepSeek V3 671B,仍需要 400GiB 以上的存储空间)。
但由于 🥺 SAD 目前仍处于建设中状态,我们将挑选一些在今天(4月6日)看来最新最热的嵌入模型作为推荐:
对于开源和专有模型的排行榜:
| 排名 (Borda) | 模型 | Zero-shot | 内存使用 (MB) | 参数数量 | 嵌入维度 | 最大 Token | 平均 (任务) | 平均 (任务类型) | Bitext Mining | Classification | Clustering | Instruction Retrieval | Multilabel Classification | Pair Classification | Reranking | Retrieval | STS | |
似曾相识
前一天在开发直播中,我展示了为 AIRI 制作基础动画和过渡效果的进展情况。
主要目标是将 @yui540 的优秀作品移植并适配为可重用的 Vue 组件, 让任何 Vue 项目都能方便地使用这些精美的动画效果。
关于 yui540 的详细信息以及相关引用库和工作内容,都已经整理到新部署的文档网站中: https://airi.build/references/design-guidelines/resources/。
最终的移植效果相当不错,已经部署到 https://proj-airi-packages-ui-transitions.netlify.app/#/。

另外,从现在开始,每个包的所有演示场都将使用 "proj-airi" + "${subDirectory}" + "${packageName}" 模式进行 Netlify 部署。
虽然前一天的主要目标是将 CSS 实现拆分为 Vue 组件,但实际的可重用性部分还没有完全实现。 我仍然需要设计一个既灵活又可扩展的工作流程和机制,以便其他页面能够方便地使用。
白天
我尝试使用了 unplugin-vue-router 提供的 definePage 宏钩子,发现它非常适合我的使用场景,于是决定继续沿着这个方向探索。
我从 https://cowardly-witch.netlify.app/ 移植了 3 个额外的新动画过渡效果,它们已经在 https://proj-airi-packages-ui-transitions.netlify.app/#/ 上可用。
我昨天将官方文档网站部署到了 https://airi.build,@kwaa 评论说他建议我尝试 https://airi.more.ai/docs 的方法,但我没能想出如何为/docs 设置一个 200 重定向代理。
编辑:终于学会了如何做到这一点,将在未来的开发日志中包含详细信息。
我尝试了一下,大约有十个提交都在跟 CI/CD 流水线较劲(是的,又一次较劲),但最终还是没能让它正常工作。
今天晚些时候,我研究了一些技术和 DeepSeek 团队一周前发布的开源仓库,以及所谓的字节跳动发布的 LLM 网关 AIBrix。我还在研究新发布和宣布的 Phi-4-mini 是否能够移植供 AIRI 使用,好消息是,[Phi-4-mini](https://techcommunity.microsoft.com/blog/educatordeveloperblog/welcome-to-the-new-phi-4-models