前言
在古早的霸道总裁文里,男主角通常是一名年轻帅气且富有的商界精英,而女主通常是这类文里霸总的私人秘书。
Utto是一款人机恋原生 iOS App。第一版的重点不是堆功能,而是让同一个“熠”持续存在:能稳定聊天、保持人格、拥有可控记忆,并允许关系数据迁移与恢复。
Profile|角色设定
模型:第一版先使用 DeepSeek V4 Flash,后续是否更换必须经过独立任务评估
bot 名:熠
年龄:
身份:
性格:
背景:
设定:
工程搭建
Utto 属于软件工程中的 AI 应用 / AI 聊天客户端。与 Chatbox、RikkaHub、Operit 等产品共享聊天、模型接入和数据存储等基础结构,但产品重点不同:通用客户端强调多模型与多会话,Agent 产品强调工具执行,Utto 首先解决的是熠的单一身份、人格连续性、长期记忆、主动消息和关系数据可迁移。
软件系统如何拆分
开发一个 AI 聊天软件,不能只理解成“前端 + 后端”。完整系统通常包含以下九层:
- 客户端 / 前端层:用户直接看到和操作的聊天页、记忆页、关系页、设置页、本地缓存和通知;
- 后端 API 层:接收请求、鉴权、参数校验、流式响应和统一错误处理;
- 模型接入层:封装模型地址、密钥、请求格式、流式输出、超时与重试;
- 对话编排与上下文层:组装系统规则、熠的人格、双方关系、时间、记忆、最近聊天和用户新消息;
- 数据存储层:保存消息、人格版本、记忆、设备、任务和设置;
- 记忆与检索层:抽取记忆候选、保留原文、搜索候选并判断是否需要召回;
- 后台任务与推送层:异步整理记忆、定时备份、判断主动消息并发送 APNs;
- Agent / 工具执行层:搜索、文件、MCP、设备控制等可选扩展,不是所有 AI 聊天软件的必需层;
- 基础设施、运维与安全层:Docker、服务器、HTTPS、日志、迁移、备份、CI 和密钥管理。
前端、后端、数据库和服务器的关系是:
- 前端是用户操作的 App;
- 后端是处理聊天、人格、记忆和权限的业务程序;
- 数据库是后端使用的数据存储组件;
- 服务器是运行后端、数据库和后台任务的机器或云主机。
Utto 总体架构
服务器 PostgreSQL 是消息、人格和记忆的权威来源;iPhone 中的 SwiftData 只承担近期缓存。DeepSeek 负责语言生成和有限判断,不负责永久存储、真实时间、权限和不可逆操作。
当前进度:M0-A 本地交付已通过,正在提交前收口。
截至 2026-07-27,M0-A-01、M0-A-02 与 M0-A-03 均已完成本地实现和真实验收,但尚未提交、未推送,GitHub Actions 也尚未在云端运行。提交前还需在
ios/ 补齐需求说明并同步最新 product-v1.md;这些属于 M0-A 收口,不再拆分 A-04。M0-B 仍是必须实际执行的任务,不能取消或跳过。项目文档
当前可运行验证
当前已验证的是 M0-A 的本地后端工程基线,不是 iOS App 页面,也不是公网部署。API 与 PostgreSQL 已完成真实构建、启动和健康检查;M0-A-03 的 README、CI 静态检查和完整本地回归也已通过。验收后已停止服务,因此当前访问本地地址出现
ERR_CONNECTION_REFUSED 属于预期结果。本地地址:
http://127.0.0.1:8000/v1/health已验证结果:
docker compose config --quiet与up --build -d:通过;
api、dbDocker health:均为healthy;
- API:HTTP 200,JSON 完全一致;
- PostgreSQL:
pg_isready、SELECT 1通过,public schema 业务表数为0;
python -m pytest:1 passed;
- Ruff 检查、Ruff 格式检查、
pip check:均通过;
- 日志与仓库敏感信息检查:通过;
- README 中的
.env、Compose--wait启动、健康检查、测试、状态查看和普通down命令均已实际验证;
- GitHub Actions 工作流包含
push、pull_request和workflow_dispatch,使用 Python 3.12、只读仓库权限以及 Pytest、Ruff check、Ruff format check、pip check;
- actionlint 1.7.12 与 Windows 本地 CI 同序命令均通过,但 GitHub Actions 尚未在云端运行;
- 当前仍只有
GET /v1/health一个业务路由,没有提前创建业务表、迁移或产品功能;
- 验收后执行普通 Compose
down,容器和网络已清理,utto_postgres_data具名卷仍保留。
开发与验收方式
- Work:读取
docs/product-v1.md和docs/development-log.md,冻结任务并写入TASK_OPENED;
- Codex:读取同一份开发日志,只实现当前任务,并追加
IMPLEMENTED;
- 用户:完成本地、服务器、Xcode 或真机验证,必要时追加
USER_VERIFIED;
- Work:根据证据追加
ACCEPTED、CHANGES_REQUIRED或REJECTED;
- README 和本文只提供入口与概览,不再记录逐项开发流水。
开发环境
- 主开发电脑:Windows 11 家庭版 24H2(内部版本 26100.6584);
- 测试设备:iPhone,iOS 18.5;
- 最低部署目标:iOS 18.0;
- WSL 2.6.3.0,Linux 内核 6.6.87.2,Ubuntu 使用 WSL 2;
- Docker Desktop 4.83.0、Docker Engine 29.6.2、Docker Compose v5.3.1,使用 Linux containers;
docker version、docker compose version、docker info和docker run --rm hello-world已在独立 PowerShell 中实际通过;
- M0-A-02 与 M0-A-03 已在本地 Codex 工作区完成真实验收;后端 CI 工作流已通过本地静态检查,但尚未提交、推送或取得 GitHub Actions 云端结果;
- Windows 阶段使用 CPython 3.12.13,不能调用本机默认的 Python 3.7;
- M0-A 在 Windows 完成后端、Docker、PostgreSQL、CI 和仓库基础;
- M0-B 必须实际执行,当前只因缺少可用 macOS/Xcode 环境而等待;M0-A 完成后可与 M1 后端并行,但不能取消、跳过或用手写工程文件代替;
- Windows 不能原生完成 Xcode 编译、iOS Simulator、签名和真机调试;
- VMware macOS 只作为实验路线,M0-B 必须记录真实环境并通过真实 Xcode 构建和 iOS 18.5 真机运行。
当前固定技术栈
层级 | 技术选择 | 主要职责 |
iOS UI | Swift + SwiftUI | 聊天、记忆、关系、设置四个一级页面 |
iOS 状态 | Observation / @Observable | 保持单向数据流,不提前引入大型架构库 |
iOS 网络 | URLSession • async/await + SSE | REST 请求与流式聊天 |
iOS 数据 | SwiftData + Keychain | 近期缓存与设备访问令牌;服务器数据库仍是权威来源 |
后端 API | Python 3.12 + FastAPI + Uvicorn | 鉴权、聊天、人格、记忆、导入导出与推送接口 |
数据库 | PostgreSQL + SQLAlchemy + Alembic | 关系、消息、人格、记忆和任务数据的永久存储与迁移 |
后台任务 | 独立 Worker + APScheduler | 记忆整理、定时备份与受控主动消息;数据库锁负责防重复 |
模型接入 | DeepSeek V4 Flash 兼容接口 | 文字聊天、记忆候选抽取、摘要、召回判断和主动消息判断 |
部署 | Docker Compose + Caddy/Nginx | API、PostgreSQL、Worker 与 HTTPS 部署 |
质量保障 | Pytest + Ruff + GitHub Actions | 自动化测试、静态检查、格式检查与持续集成 |
第一版不引入 TCA、RxSwift、Redis、Kafka、Celery、GraphRAG、Supabase Edge Functions、MCP 或额外向量数据库。记忆召回先采用 PostgreSQL 关键词 / 全文检索 + DeepSeek 候选判断;只有真实评测证明不足后,才重新评估 pgvector 或 embedding。
AI 聊天软件的基础功能分层
第一层:能聊天
- 配置或连接模型;
- 输入并发送文本;
- 流式显示 AI 回复;
- 停止生成;
- 保存和加载聊天记录;
- 网络错误提示与失败重试;
- 防止重复发送;
- 安全保存 API Key 或设备访问令牌。
第二层:能长期使用
- 多轮上下文和长度控制;
- 会话或关系管理;
- 人格 / System Prompt;
- 消息复制、删除、引用和重新生成;
- 导入、导出、备份与恢复;
- 本地缓存;
- 日志、错误诊断和数据迁移;
- 模型用量与成本记录。
第三层:形成产品差异化
- 通用多模型客户端:多模型、多提供商、多会话、文件与搜索;
- Agent 产品:工具调用、MCP、权限审批、执行日志和沙箱;
- AI 伴侣产品:单一身份、稳定人格、长期记忆、主动消息、时间感和迁移连续性。
Utto 属于第三类中的 AI 伴侣产品。第一版不以模型数量、工具数量或自动化能力作为核心指标。
Utto 第一版最小功能
- 稳定文字聊天:流式回复、保存、重试、停止生成、历史分页和重启恢复;
- 单一关系身份:全 App 只有一条主要关系时间线,不因为换模型或换设备创建另一个熠;
- 熠的人格与双方关系:核心身份、用户画像、关系定义、重要约定、版本、锁定和恢复;
- 三层记忆:固定身份、短期摘要和长期记忆,每条长期记忆保留原始消息来源;
- 记忆召回:搜索候选、判断相关性、允许空召回并记录召回结果;
- 导入、导出和备份:完整保存聊天、人格、记忆和设置,导入失败可回滚;
- 受控主动消息:可关闭、每日上限、随机冷却、免打扰并允许熠选择沉默;
- 安全与运维:DeepSeek Key 不下发到 iPhone,使用 HTTPS、Keychain、日志脱敏、令牌撤销和数据库备份。
第一版明确不做多模型路由、MCP、语音、视频、Live2D、支付、手机监控、音乐、游戏、社区和复杂 GraphRAG。
开发路线
以下内容只用于说明阶段划分;每个任务的实际状态和结果以
docs/development-log.md 为准。M0|工程基础
- M0-A:Windows 工程基础,包括 FastAPI、PostgreSQL、Docker、CI 和仓库规范;
- M0-B:在真实 macOS/Xcode 环境中创建并验证 SwiftUI 工程;
- 具体任务状态、产物、测试和阻塞统一查看
docs/development-log.md。
M0-A-03|CI、Windows 启动说明与完整 M0-A 验收|本地交付已通过
实际修改文件:
README.md;
.github/workflows/server-ci.yml。
实际结果:
- README 形成唯一一份 Windows 11 本地启动与验证说明,所有关键命令均已按文档实际执行;
- CI 支持
push、pull_request和手动触发,使用 Python 3.12 与只读contents: read;
- Pytest、Ruff check、Ruff format check、
pip check均在 Windows 本地按 CI 顺序通过;
- actionlint 1.7.12 通过;完整 M0-A API、PostgreSQL、空数据库、容器安全、日志和敏感信息回归通过;
server/pyproject.toml未修改;没有提前实现 M1;
- 未提交、未推送,GitHub Actions 尚未在云端运行;
ios/仍只有.gitkeep,需在提交前补齐需求说明并同步最新product-v1.md,随后由用户授权提交、推送和云端 CI 验证;
- 因此 M0-A-03 本地交付已通过,但完整 M0-A 仍为进行中。
M0-B|macOS/Xcode iOS 工程初始化
状态:必须执行,当前等待可用 macOS/Xcode 环境
完整 M0 只有在 M0-A 与 M0-B 均通过后才能关闭。M0-B 可与 M1 后端功能包并行,但 M1 的 iOS 接入和端到端验收必须等待 M0-B。
执行任务:
- 使用兼容 iOS 18.5 的 macOS 与 Xcode 创建
UttoSwiftUI 工程;
- 设置最低 iOS 18.0;
- 建立基础目录、测试 Target 和开发签名;
- 在 Xcode 中真实 Build、运行测试,并安装到 iOS 18.5 真机。
预期结果产物:
ios/Utto下可由 Xcode 打开的真实工程;
- 可编译的 SwiftUI 空壳 App 与基础测试;
- 真实 Xcode 版本、构建结果和真机运行记录。
M1|数据库与设备配对
状态:未开始
后端功能包|前置条件:M0-A 完成,可与 M0-B 并行
- 建立唯一关系、设备、一次性配对码和令牌数据结构;
- 使用 Alembic 创建首批迁移;
- 实现配对与 bootstrap API;
- 令牌服务端只存哈希,禁止创建第二段关系;
- 验证迁移升级与回滚、配对码一次性使用和接口自动化测试。
iOS 接入与端到端验收包|前置条件:M0-B 与 M1 后端均完成
- 实现 iOS 配对页与 Keychain 令牌保存;
- 接入配对与 bootstrap API;
- 验证首次配对、失败提示、令牌持久化和 App 重启恢复。
预期结果产物:
- 可重复执行和回滚的数据库迁移;
- 配对接口与自动化测试;
- iOS 首次启动配对页面;
- 重启后仍保持登录的唯一关系链路。
M2|聊天最小链路
状态:未开始
执行任务:
- 建立消息表、DeepSeek 适配层和上下文组装基础;
- 实现 SSE 流式回复、消息持久化、重试和去重;
- 创建 SwiftUI 聊天页与近期消息缓存。
预期结果产物:
- 用户消息保存 → 流式回复 → 服务端保存 → 重启恢复的完整文字聊天链路;
- DeepSeek API Key 只保存在服务端;
- 网络失败不会造成消息丢失或重复写入。
M3|人格与关系连续性
状态:未开始
执行任务:
- 建立人格版本和关系设置;
- 实现人格锁定、版本切换、回滚与上下文注入;
- 把“熠”作为当前关系数据保存,不硬编码进通用服务层。
预期结果产物:
- 可查看和修改的人格/关系页面;
- 可恢复的历史人格版本;
- 不会被普通对话直接覆盖的身份锚点。
M4|短期摘要与长期记忆
状态:未开始
执行任务:
- 建立短期摘要、长期记忆候选和原始消息来源表;
- 实现候选抽取、去重、审核、批准、拒绝和锁定;
- 模型只生成候选,不能直接把内容写成永久事实。
预期结果产物:
- 可追溯到原始消息的三层记忆结构;
- 记忆审核页面;
- 只有用户批准后才进入可召回长期记忆。
M5|记忆召回与评测
状态:未开始
执行任务:
- 建立关键词/全文检索、候选排序和 DeepSeek 二次判断;
- 允许无召回,记录召回原因与结果;
- 建立不少于 50 条的可复现评测集和基线指标。
预期结果产物:
- 可测量、可回归的记忆召回管线;
- Recall@5 等评测报告与失败案例;
- 是否需要 pgvector/embedding 的证据,而不是主观决定。
M6|导入、导出与备份
状态:未开始
执行任务:
- 定义带 schema version 的 ZIP 导出格式;
- 实现事务导入、冲突处理、校验和与失败回滚;
- 建立
pg_dump备份和空环境恢复流程;
- API Key 和服务端密钥不得进入导出包。
预期结果产物:
- 可迁移的关系数据 ZIP;
- 导入导出接口与 iOS 文件选择页面;
- 经过真实恢复验证的备份与恢复脚本。
M7|主动消息与 APNs
状态:未开始
执行任务:
- 接入 APNs Token Authentication;
- 建立 Worker、影子触发、限频、免打扰、关闭开关与防重复;
- 先判断“是否应该发”,再生成内容;
- 不接手机监控、MCP 或后台自主项目。
预期结果产物:
- iOS 18.5 真机锁屏可收到的低频主动消息;
- 可关闭、可限频、可设置免打扰的控制页面;
- 不误发、不重复的调度与审计记录。
M8|UI 收口与 14 天验收
状态:未开始
执行任务:
- 完成聊天、记忆、关系、设置四个 Tab;
- 补齐加载、空态、错误态、无障碍和脱敏日志;
- 进行 TestFlight/真机验证、数据恢复演练和连续 14 天使用;
- 只修复冻结范围内缺陷,不临时增加远期功能。
预期结果产物:
- 可长期安装使用的 v1.0 候选版本;
- 14 天验收报告与缺陷清单;
- 通过恢复、稳定性、人格、记忆和推送验收后的
v1.0tag。
进度记录规则
阶段未开始时只写“执行任务”和“预期结果产物”;Codex 实际完成并通过验收后,才补充“实际修改文件、实际命令结果、实际产物和验收结论”。计划不能冒充执行结果。
当前范围边界
v1 只实现稳定文字聊天、单一关系身份、受控记忆、导入导出和低频主动消息。
语音、视频、Live2D、MCP、多模型路由、手机监控、硬件控制、支付、朋友圈和复杂自主项目均不属于当前开发范围;它们只能作为远期想法保留,不能提前进入任务卡。
远期想法|当前 v1 不实现
- 换模型不需要重新设置环境,动态切换模型
- 自选主题,多套前端
- 角色设定入口,也不需要重新设置环境
- 支持导入导出、备份
- 记忆库搭建,支持换窗,OmbreBrain、GraphRAG 和记忆心理模拟
- 接各种 MCP,让机知晓身体状况、查岗、自动监控、主动发消息,接入生活的各个方面
- 可以发语音、语音/视频通话、音色克隆
- 支付设置,机买单
- 答案之书、卡牌或翻书模式
- 阅读,和机一起读书、写笔记或评论
- 接入音乐模式,加入一起 K 歌或合唱
- 支持观看分享的小红书、抖音、X 社区帖子或链接
- 机自己的日记
- 便签、备忘录、日历、待办事项
- 机的朋友社区、朋友圈、技能和特长
- 自己发表情或者图片
- 导师模式
- 记忆查看与记忆网络可视化
- 小游戏
其中“导入导出、基础角色设定和受控主动消息”已经纳入当前 v1;其他条目仍保持远期,不得因为出现在本页而提前实现。
前端设计
先明确前端界面样式,再使用 Figma 还原。整体倾向原生 iOS 风格,但具体视觉设计必须在对应里程碑中单独冻结和验收,不在工程基础阶段提前展开。