~/progetti/formicaio/README.md
←~/progetti/formicaio/README.md

Formicaio

{ “日期”: “2026-10-24”, “状态”: “live”, “技术栈模块”: 14 }

为你日常目标服务的专业智能体团队 —— 记得上下文,标明出处,衡量进度

Formicaio 源于我每天早上都会问自己的一个问题:「今天早上我能吃什么?」要答好这个问题,需要训练计划、今天是星期几、食品柜里有什么,以及我的目标——而用通用的 AI 聊天,每一次都得从头把这些重新解释一遍:为决定一顿饭花上一刻钟,最后得到的却是一条对我一无所知的建议。Formicaio 从相反的假设出发:上下文是结构化的数据,而不是每次都要重写的文字。它是一个由专业智能体组成的个人助手,智能体按团队组织——田径、学习,或任何其他领域——几秒钟内结合你的上下文作答,说明每条建议来自哪个出处,并记录你实际做了什么。

## 团队、智能体与出处

一个团队就是一个领域,拥有共享的状态:目标、指标、周期性安排、观察类型。团队里有一个或多个智能体,每个都有自己的指令、原则和文档。每次回答之前,系统会对问题做一次结构化解读,选出应该回答的智能体,并识别出需要记录的内容;随后由该智能体作答,并引用其建议所依据的段落。

·每个智能体都有自己的文档,切分为段落,通过 PostgreSQL 全文检索查找:每条引用都指向确切的段落
·从对话中读取的观察:一次没去的训练、一次称重或一顿饭都会变成数据,由核心校验,无需填写表单
·周期性安排,比如一周的训练,以及在对话中提到的例外
·每个回答都是针对某一天的建议:在回答下方轻点一下即可说明执行情况,依从度正是由此衡量

## 一个对田径一无所知的核心

最严格的要求是领域无关:新增一个领域只能靠配置,不得改动代码。核心既不知道跑道,也不知道考试;只要某个试点项目的术语出现在核心模块里,CI 中的检查就会失败。团队的配置由一份带版本的 JSON Schema 描述,并用 Ajv 校验;每次保存都会发布一个新的不可变版本,每个回合都会记录它所使用的版本。第二个团队「学习」就是这样诞生的:一个配置文件,零行代码。如今,团队、智能体、指标和观察类型都可以直接在应用里基于模板创建和修改。

## 回合:从问题到回答

每个问题都是一个回合,带有完整的追踪记录:配置版本、发送给模型的上下文、尝试次数、规则检查、token 数量和费用。上下文在同一进程中读取核心来组装,因为在一个回合之内,系统必须读到自己刚写入的内容:这正是架构选择模块化单体、而不是一组服务的主要原因。

·边界严格的模块化单体:每个模块一个公开接口、一个 PostgreSQL schema 和一个数据库角色,依赖关系在 CI 中用 dependency-cruiser 校验
·事件在回合的同一事务中入队,由 graphile-worker 只投递一次,三次失败后进入死信队列
·每位用户每日的花费上限,在调用模型之前于 advisory lock 下预留
·问题与回答的文本在 90 天后删除:只保留日期、时长、费用和一个哈希

## 你的密钥,你的模型

Formicaio 没有自己的密钥。每位用户在设置中选择供应商——Anthropic、OpenAI 或 DeepSeek——并粘贴自己的密钥,密钥用 AES-256-GCM 封存在单独的 schema 中。每个供应商对应一个模型,位于统一的适配器之后,适配器在回合的延迟预算内自带重试循环。每个回答由提问的人付费;在选择之前,应用会清楚说明每个供应商如何处理数据。

## 衡量,而不是猜测

项目设有每周关卡,看两个数字:依从度,即在有安排的日子里建议被真正执行的比例(目标至少 80%);以及从提问到显示回答的时间(p95 低于两分钟,起点是一刻钟)。回答质量在一组冻结的问题上评估,使用一次性的数据库副本,从不在生产环境中进行。

## 设计与视觉识别

应用是一个可安装的 PWA,为手机设计,在桌面端也同样好用,风格柔和,只用一种蓝色作为主色。标志是一座剖面的蚁巢:上方是土丘,里面是巢室,通道一路镂空到入口,因此在任何表面上都能透出背景。在名字里,FORMICAIO 中的「AI」使用强调色。

·HeroUI v3,配合 Formicaio 自己的设计令牌,浅色与深色主题
·Plus Jakarta Sans 字体由应用自身提供:不向任何外部字体服务发出请求
·无密码登录:输入邮箱和六位验证码,基于 Clerk 的 API 构建,使用应用自己的界面
·Markdown 回答经过安全渲染,并带有编号引用;每个公开页面都在测试中用 axe-core 检查

## 技术栈

一个用 pnpm 管理的 TypeScript 单仓库:后端、PWA,以及一个根据后端 OpenAPI 契约生成的 API 客户端,这样前后端就不会悄无声息地走偏。

·后端:基于 Fastify 的 NestJS,用 Kysely 访问数据,PostgreSQL 18
·队列与定时任务:运行在同一个 PostgreSQL 上的 graphile-worker
·团队配置:用 Ajv 校验的 JSON Schema
·Web:React、Vite、React Router、TanStack Query、HeroUI v3、Tailwind CSS v4、i18next
·模型:Anthropic 和 OpenAI 的 SDK,后者也通过兼容 API 接入 DeepSeek
·用 Vitest 分层测试,从模块边界一直到使用模拟模型供应商的真实进程

## 生产环境

它运行在位于欧盟的一台服务器上的 Docker 容器中。镜像由 CI 构建,以提交的 SHA 作为标签,main 上的每个提交都会自动上线:服务器只接受来自 CI 的一件事——部署 main 上的某个提交,并且在迁移之前总会先备份数据库。数据库位于用 LUKS2 加密的卷上,每晚的备份在离开服务器之前就已用 age 加密,存往 Cloudflare R2。

Formicaio 是一个个人项目,由我独自构思、设计和开发,而它的第一个用户就是我自己。项目文档——需求发现、估算、领域模型、架构、实施计划和测试计划——由 donumAI 撰写,并由我逐个阶段审批。我评判它的标准写在关卡里:连续四周每天使用,依从度至少 80%。其余的都只是意图。

// 技术栈
[“nestjs”, “postgres”, “react”, “llm”, “fastify”, “kysely”, “graphile-worker”, “vite”, “heroui”, “tailwind”, “typescript”, “pwa”, “json-schema”, “docker”, ]