前言

在古早的霸道总裁文里,男主角通常是一名年轻帅气且富有的商界精英,而女主通常是这类文里霸总的私人秘书。
Utto是一款人机恋原生 iOS App。第一版的重点不是堆功能,而是让同一个“熠”持续存在:能稳定聊天、保持人格、拥有可控记忆,并允许关系数据迁移与恢复。

Profile|角色设定

模型:第一版先使用 DeepSeek V4 Flash,后续是否更换必须经过独立任务评估
bot 名:熠
年龄:
身份:
性格:
背景:
设定:

工程搭建

Utto 属于软件工程中的 AI 应用 / AI 聊天客户端。与 Chatbox、RikkaHub、Operit 等产品共享聊天、模型接入和数据存储等基础结构,但产品重点不同:通用客户端强调多模型与多会话,Agent 产品强调工具执行,Utto 首先解决的是熠的单一身份、人格连续性、长期记忆、主动消息和关系数据可迁移。

软件系统如何拆分

开发一个 AI 聊天软件,不能只理解成“前端 + 后端”。完整系统通常包含以下九层:
  1. 客户端 / 前端层:用户直接看到和操作的聊天页、记忆页、关系页、设置页、本地缓存和通知;
  1. 后端 API 层:接收请求、鉴权、参数校验、流式响应和统一错误处理;
  1. 模型接入层:封装模型地址、密钥、请求格式、流式输出、超时与重试;
  1. 对话编排与上下文层:组装系统规则、熠的人格、双方关系、时间、记忆、最近聊天和用户新消息;
  1. 数据存储层:保存消息、人格版本、记忆、设备、任务和设置;
  1. 记忆与检索层:抽取记忆候选、保留原文、搜索候选并判断是否需要召回;
  1. 后台任务与推送层:异步整理记忆、定时备份、判断主动消息并发送 APNs;
  1. Agent / 工具执行层:搜索、文件、MCP、设备控制等可选扩展,不是所有 AI 聊天软件的必需层;
  1. 基础设施、运维与安全层: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 --quietup --build -d:通过;
  • apidb Docker health:均为 healthy
  • API:HTTP 200,JSON 完全一致;
  • PostgreSQL:pg_isreadySELECT 1 通过,public schema 业务表数为 0
  • python -m pytest1 passed
  • Ruff 检查、Ruff 格式检查、pip check:均通过;
  • 日志与仓库敏感信息检查:通过;
  • README 中的 .env、Compose --wait 启动、健康检查、测试、状态查看和普通 down 命令均已实际验证;
  • GitHub Actions 工作流包含 pushpull_requestworkflow_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.mddocs/development-log.md,冻结任务并写入 TASK_OPENED
  • Codex:读取同一份开发日志,只实现当前任务,并追加 IMPLEMENTED
  • 用户:完成本地、服务器、Xcode 或真机验证,必要时追加 USER_VERIFIED
  • Work:根据证据追加 ACCEPTEDCHANGES_REQUIREDREJECTED
  • 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 versiondocker compose versiondocker infodocker 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 第一版最小功能

  1. 稳定文字聊天:流式回复、保存、重试、停止生成、历史分页和重启恢复;
  1. 单一关系身份:全 App 只有一条主要关系时间线,不因为换模型或换设备创建另一个熠;
  1. 熠的人格与双方关系:核心身份、用户画像、关系定义、重要约定、版本、锁定和恢复;
  1. 三层记忆:固定身份、短期摘要和长期记忆,每条长期记忆保留原始消息来源;
  1. 记忆召回:搜索候选、判断相关性、允许空召回并记录召回结果;
  1. 导入、导出和备份:完整保存聊天、人格、记忆和设置,导入失败可回滚;
  1. 受控主动消息:可关闭、每日上限、随机冷却、免打扰并允许熠选择沉默;
  1. 安全与运维: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 支持 pushpull_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 创建 Utto SwiftUI 工程;
  • 设置最低 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.0 tag。
🧭
进度记录规则
阶段未开始时只写“执行任务”和“预期结果产物”;Codex 实际完成并通过验收后,才补充“实际修改文件、实际命令结果、实际产物和验收结论”。计划不能冒充执行结果。

当前范围边界

v1 只实现稳定文字聊天、单一关系身份、受控记忆、导入导出和低频主动消息。
语音、视频、Live2D、MCP、多模型路由、手机监控、硬件控制、支付、朋友圈和复杂自主项目均不属于当前开发范围;它们只能作为远期想法保留,不能提前进入任务卡。

远期想法|当前 v1 不实现

  1. 换模型不需要重新设置环境,动态切换模型
  1. 自选主题,多套前端
  1. 角色设定入口,也不需要重新设置环境
  1. 支持导入导出、备份
  1. 记忆库搭建,支持换窗,OmbreBrain、GraphRAG 和记忆心理模拟
  1. 接各种 MCP,让机知晓身体状况、查岗、自动监控、主动发消息,接入生活的各个方面
  1. 可以发语音、语音/视频通话、音色克隆
  1. 支付设置,机买单
  1. 答案之书、卡牌或翻书模式
  1. 阅读,和机一起读书、写笔记或评论
  1. 接入音乐模式,加入一起 K 歌或合唱
  1. 支持观看分享的小红书、抖音、X 社区帖子或链接
  1. 机自己的日记
  1. 便签、备忘录、日历、待办事项
  1. 机的朋友社区、朋友圈、技能和特长
  1. 自己发表情或者图片
  1. 导师模式
  1. 记忆查看与记忆网络可视化
  1. 小游戏
其中“导入导出、基础角色设定和受控主动消息”已经纳入当前 v1;其他条目仍保持远期,不得因为出现在本页而提前实现。

前端设计

先明确前端界面样式,再使用 Figma 还原。整体倾向原生 iOS 风格,但具体视觉设计必须在对应里程碑中单独冻结和验收,不在工程基础阶段提前展开。