Files
aiagent/docs/Android客户端PRD文档.md
renjianbo 1693292bbd feat: SSML emotional TTS, agent avatars, AgentChat UX overhaul, virtual company enhancements
- SSML TTS with emotional styles (_build_ssml, mstts:express-as) and natural pauses
- Agent avatar support: DB migration, API, frontend emoji/URL rendering
- AgentChat UX: highlight.js code blocks, copy buttons, streaming cursor, char count,
  auto-title, keyboard shortcuts, message feedback (thumbs), undo delete, mobile responsive
- Virtual company: M2 control, tier-3/4 capabilities, per-dept session fix, deliverable
  validator, insight analyzer enhancements
- New services: agent_profiler, deliverable_validator, redis_task_registry
- Android: auth refactor, launcher icons, network security config, update manager
- Frontend: useSpeechQueue composable, Agents/AgentConfig/AgentTest enhancements
- Various backend fixes and expanded test coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-01 23:22:38 +08:00

377 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 天工智能体 Android 客户端 PRD 文档
> **版本**: v1.3.0 (versionCode=4)
> **更新日期**: 2026-07-27
> **目标平台**: Android 8.0+ (API 26+),目标 API 34
---
## 1. 产品概述
天工智能体 Android 客户端是天工 AI Agent 平台的移动端入口,与 Web 前端(localhost:3001)和后端(101.43.95.130:8037)共享同一套 API。用户可通过手机完成 Agent 对话、语音输入、智能体管理、消息推送等全部核心操作。
### 核心价值
- **随身 AI 助手**: 随时随地与 Agent 对话,支持流式实时输出
- **多 Agent 切换**: 支持多个自定义 Agent,每个 Agent 独立会话
- **语音交互**: 内置录音转文字(ASR)和文本转语音(TTS)
- **离线队列**: 无网络时消息自动暂存,恢复网络后自动发送
---
## 2. 目标用户
| 用户类型 | 描述 | 核心需求 |
|---------|------|---------|
| 普通用户 | 日常 AI 对话使用者 | 流畅对话、语音输入、消息推送 |
| 高级用户 | Agent 创建/管理者 | 多 Agent 切换、知识库管理、自定义配置 |
| 开发者 | 调试/测试服务器 | 服务器地址配置、网络诊断 |
---
## 3. 技术架构
### 3.1 技术栈
| 层级 | 技术选型 |
|------|---------|
| UI | Jetpack Compose + Material 3 |
| 导航 | Navigation Compose(17 个路由) |
| DI | Hilt + Dagger |
| 网络 | Retrofit + OkHttp + Gson |
| SSE 流式 | 自定义 SseClient(callbackFlow) |
| 本地存储 | Room(消息/会话缓存)+ DataStore(偏好设置) |
| 安全存储 | AndroidX EncryptedSharedPreferences(AES256-GCM) |
| 图片加载 | Coil Compose |
| Markdown 渲染 | Markwon |
| 音频播放 | Media3 ExoPlayer |
| 音频录制 | MediaRecorder |
| 推送 | Firebase Cloud Messaging |
| 崩溃上报 | Tencent Bugly |
| 数据统计 | Umeng |
### 3.2 架构模式: MVVM + Repository
```
┌──────────────────────────────────────────────┐
│ UI Layer (Compose Screens) │
│ 观察 StateFlow<UiState>,用户操作 → VM │
└──────────────────┬───────────────────────────┘
│ Hilt 注入
┌──────────────────▼───────────────────────────┐
│ ViewModel Layer (7 个 @HiltViewModel) │
│ MutableStateFlow + viewModelScope.launch │
└──────────────────┬───────────────────────────┘
│
┌──────────────────▼───────────────────────────┐
│ Repository Layer (7 个 Repository) │
│ 桥接网络 API 与本地数据源 │
└────────┬──────────────────┬──────────────────┘
│ │
┌────────▼────────┐ ┌──────▼──────────────────┐
│ Remote (API) │ │ Local (Room + DataStore) │
│ ApiService (52 │ │ AppDatabase (3 表) │
│ 个端点) │ │ TokenDataStore (偏好) │
│ SseClient │ │ CredentialStore (加密) │
│ Interceptors x3 │ │ OfflineQueue │
└─────────────────┘ └─────────────────────────┘
```
### 3.3 OkHttp 拦截器链
| 顺序 | 拦截器 | 职责 |
|------|--------|------|
| 1 | DynamicUrlInterceptor | 动态改写请求 URL(支持运行时切换服务器) |
| 2 | AuthInterceptor | 注入 Bearer Token(仅信任主机),401 自动刷新 |
| 3 | HttpLoggingInterceptor | 请求/响应日志(Debug: BODY, Release: NONE) |
### 3.4 超时策略
| 类型 | 超时 |
|------|------|
| 连接超时 | 30s |
| 写入超时 | 30s |
| 读取超时 | 0ms(无限,SSE 流式需要) |
---
## 4. 导航流程
### 4.1 路由启动决策
```
SplashScreen (1.5s 品牌动画)
├── !onboardingCompleted → OnboardingScreen(引导页)
├── token == null → LoginScreen(密码登录)
└── token + onboarded → ChatScreen(主界面)
```
### 4.2 完整路由表(17 条)
| 路由 | 页面 | 说明 |
|------|------|------|
| `splash` | 启动页 | 品牌动画 + Token 验证 |
| `login` | 密码登录 | 用户名+密码,长按标题配置服务器 |
| `register` | 注册 | 用户名/邮箱/密码/确认密码 |
| `phone_login` | 手机登录 | 验证码登录 |
| `onboarding` | 引导页 | 新用户首次引导 |
| `chat` | 主界面 | 对话列表+输入+抽屉导航 |
| `agents` | Agent 管理 | 创建/删除/编辑智能体 |
| `agent_market` | Agent 市场 | 浏览/安装市场智能体 |
| `history` | 对话历史 | 全部会话列表 |
| `settings` | 设置 | 主题/通知/语音/TTS |
| `about` | 关于 | 版本信息 |
| `account_security` | 账号安全 | 修改密码/手机号 |
| `subscription` | 订阅 | 套餐购买 |
| `memory_manage` | 记忆管理 | Agent 知识库 CRUD |
| `notification_detail` | 通知详情 | 推送消息查看 |
| `notifications` | 通知列表 | 全部推送消息 |
| `network_diagnose` | 网络诊断 | 连通性测试 |
---
## 5. 功能清单
### 5.1 核心对话 (ChatScreen)
| 功能 | 状态 | 说明 |
|------|------|------|
| 流式对话 | v1.0 | SSE 实时流式输出,支持 Think→ToolCall→ToolResult→Message 事件序列 |
| 多 Agent 切换 | v1.0 | TopAppBar 下拉选 Agent,抽屉显示全部 Agent |
| 消息重发 | v1.1 | 失败消息支持重试 |
| Think 追踪面板 | v1.1 | 可折叠,展示 Agent 推理过程 |
| 停止生成 | v1.2 | 停止后保留已输出内容,不会丢失半截消息 |
| 编辑消息 | v1.2 | 编辑已发送的用户消息并重新生成回复 |
| 重新生成 | v1.2 | 对最后一条 Assistant 消息重新生成 |
| 工具调用审批 | v1.2 | Agent 调用工具前弹审批条,用户可允许/拒绝 |
| 历史加载 | v1.3 | 上拉无限加载历史消息 |
| 消息排队 | v1.3 | 流式输出期间可继续输入,自动排队发送 |
| 离线队列 | v1.2 | 无网络时消息暂存 Room,恢复网络后自动发送 |
### 5.2 语音交互
| 功能 | 说明 |
|------|------|
| 录音转文字 | MediaRecorder 录制 AAC → 上传 ASR → 填入输入框 |
| 文字转语音 | Assistant 消息旁有朗读按钮 → TTS → ExoPlayer 播放 |
| 实时波形 | 录音按钮显示波形反馈 |
### 5.3 消息交互
| 功能 | 说明 |
|------|------|
| Markdown 渲染 | 消息气泡内支持 Markdown 格式,代码块/表格/列表 |
| 消息反馈 | 点赞/踩 + 可选文字评论 |
| 复制消息 | 长按消息复制全文 |
| 分享消息 | 分享到系统分享面板 |
| 图片发送 | Coil 选图 → 上传 → 消息内嵌图片 |
### 5.4 推送通知
| 功能 | 说明 |
|------|------|
| FCM 推送 | Firebase 消息接收,支持数据消息 |
| 本地通知 | NotificationHelper 创建通知渠道并显示 |
| 未读角标 | TopAppBar 铃铛图标显示未读数 |
### 5.5 APP 更新
| 功能 | 说明 |
|------|------|
| 版本检查 | 启动时检查 /api/v1/app/check-update |
| 强制更新 | 返回 `force=false` 弹窗提示,`force=true` 全屏不可关闭 |
| SHA256 校验 | 下载 APK 后校验哈希,不匹配则拒绝安装 |
| URL 白名单 | 仅允许 `https://*.tiangong.ai` 域名下载 |
### 5.6 离线支持
| 功能 | 说明 |
|------|------|
| 离线检测 | NetworkMonitor(ConnectivityManager 回调) |
| 消息暂存 | Room pending_messages 表 |
| 自动回放 | 恢复网络后按创建时间顺序发送 |
| 离线提示 | 输入框禁用 + 顶部离线横幅 |
---
## 6. 安全设计
### 6.1 网络安全
| 措施 | 实现 |
|------|------|
| HTTPS 强制 | `usesCleartextTraffic=false`,仅本地开发地址豁免 |
| 证书校验 | 系统默认证书链校验 |
| 域名白名单 | network_security_config.xml 定义可信域名 |
| URL 白名单 | DynamicUrlInterceptor 拒绝非本地 HTTP 地址 |
| APK 下载白名单 | AppUpdateManager 仅允许 `https://*.tiangong.ai` |
| APK 哈希校验 | 服务端返回 SHA256,客户端下载后校验 |
| Host 校验 | AuthInterceptor 仅向信任主机发送 Authorization 头 |
### 6.2 数据安全
| 措施 | 实现 |
|------|------|
| Token 加密存储 | AndroidX EncryptedSharedPreferences(AES256-GCM) |
| 密码不存储 | 不在本地留存密码,401 跳转登录页 |
| 备份保护 | `allowBackup=false`,禁止 adb backup 导出数据 |
| API Key 外置 | Bugly KEY 从 local.properties 注入,不提交 git |
| google-services.json | 已从 git 移除 |
### 6.3 服务器地址访问控制
| 层级 | 控制 |
|------|------|
| UI | 长按"密码登录"标题才显示配置入口(普通用户不可见) |
| DynamicUrlInterceptor | 非内网 IP 的 HTTP 地址直接拒绝 |
| AuthInterceptor | 非信任主机不发送 Authorization 头 |
---
## 7. API 集成
### 7.1 ApiService 端点分组(52 个端点)
| 分组 | 端点数 | 主要操作 |
|------|--------|---------|
| 认证 | 10 | 登录/注册/刷新/改密/手机验证码/注销 |
| Agent | 5 | CRUD + 列表查询 |
| 对话 | 2 | 非流式对话(流式走 SseClient) |
| 语音 | 2 | ASR 转写 + TTS 合成 |
| 通知 | 3 | 未读数/列表/已读标记 |
| 文件上传 | 1 | 图片/文件上传 |
| FCM | 2 | 注册/注销推送 Token |
| 反馈 | 1 | 消息点赞/踩 + 评论 |
| 会话管理 | 4 | 消息历史/会话列表/更新/删除 |
| 消息搜索 | 1 | 全文搜索 |
| Agent 记忆 | 14 | 知识库/学习模式/向量记忆 CRUD + 导入导出 |
| APP 更新 | 1 | 版本检查 |
| 统计 | 1 | 事件上报 |
| Agent 市场 | 9 | 浏览/安装/评分/收藏/分类 |
| 模板市场 | 2 | 浏览/使用模板 |
| 场景模板 | 2 | 预设场景模板 |
| 计费 | 6 | 套餐/订阅/用量/订单/支付 |
### 7.2 SSE 事件类型(9 种)
| 事件 | 说明 |
|------|------|
| `Message` | 流式文本内容片段 |
| `Think` | Agent 推理过程 |
| `ToolCall` | Agent 调用工具(触发审批) |
| `ToolResult` | 工具调用结果 |
| `Final` | 最终完整内容 |
| `Plan` | Agent 执行计划 |
| `Done` | 流结束(无 Final 时的兜底) |
| `Error` | 服务端错误 |
| `ConnectionError` | 客户端连接错误(含重连次数) |
---
## 8. 错误处理
### 8.1 用户友好错误映射
| 原始异常 | 用户提示 |
|---------|---------|
| `ConnectException` | 网络连接失败,请检查网络设置 |
| `SocketTimeoutException` | 请求超时,请稍后重试 |
| `UnknownHostException` | 无法连接到服务器,请检查地址 |
| `SSLHandshakeException` | 安全连接失败,请检查服务器证书 |
| HTTP 401 | 用户名或密码错误 |
| HTTP 403 | 账号已被禁用 |
| HTTP 429 | 请求过于频繁,请稍后重试 |
| HTTP 5xx | 服务器繁忙,请稍后重试 |
### 8.2 错误横幅行为
- 错误不自动消失(用户可读完整信息)
- 提供"重试"按钮(调用最近失败的消息重发)
- 提供"关闭"按钮(手动关闭)
- 横幅优先级: 错误 > 重连失败 > 离线 > 重连中 > 工具审批
---
## 9. 本地数据库
### 9.1 Room 表结构
| 表 | 用途 |
|----|------|
| `messages` | 消息本地缓存(id, conversationId, agentId, role, content, toolName, toolInput, toolOutput, tokenUsage, createdAt) |
| `conversations` | 会话列表(sessionId, agentId, agentName, title, lastMessage, lastMessageAt, messageCount, isPinned) |
| `pending_messages` | 离线消息队列(id, agentId, message, sessionId, createdAt) |
### 9.2 DataStore 偏好
| Key | 类型 | 说明 |
|-----|------|------|
| `server_url` | String | 动态服务器地址 |
| `theme_mode` | Int | 0=System, 1=Light, 2=Dark |
| `voice_enabled` | Boolean | 语音输入开关 |
| `tts_enabled` | Boolean | 语音朗读开关 |
| `current_agent_id` | String | 当前选中的 Agent |
| `last_session_id` | String | 上次会话 ID |
| `onboarding_completed` | Boolean | 引导完成标记 |
---
## 10. 版本历史
| 版本 | versionCode | 主要变更 |
|------|-------------|---------|
| v1.0.0 | 1 | 初始版本:基础对话、Agent 列表、登录/注册 |
| v1.1.0 | — | Think 追踪面板、消息重试、会话管理 |
| v1.2.0 | — | 动态 URL 切换、离线队列、停止保留内容、编辑消息、重新生成、工具审批、计费模块 |
| v1.3.0 | 4 | 拉取历史消息、流式输入解锁(消息排队)、安全加固(HTTPS/Token加密/APK校验)、UX 修复 |
---
## 11. 第三方 SDK
| SDK | 版本 | 用途 |
|-----|------|------|
| Firebase BOM | — | 推送消息(FCM) |
| Tencent Bugly | — | 崩溃上报 |
| Umeng | — | 数据统计 |
| Markwon | — | Markdown 渲染 |
| Coil | — | 图片加载 |
| Media3 ExoPlayer | — | 音频播放 |
---
## 12. 构建配置
| 配置项 | 值 |
|--------|-----|
| compileSdk | 34 |
| minSdk | 26 (Android 8.0) |
| targetSdk | 34 |
| JVM Target | 17 |
| 包名 | `com.tiangong.aiagent` |
| 应用名 | 天工智能体 |
| 默认服务器 | `http://101.43.95.130:8037/` |
| 代码混淆 | Release 开启(ProGuard) |
---
## 13. 已知限制与下阶段规划
### 已知限制
1. 后端无 HTTPS 证书,云服务器仍走 HTTP(通过 network_security_config 单独豁免)
2. 未实现消息端到端加密
3. 大文件上传无分片/断点续传
4. 无多语言支持(仅中文)
5. 未适配平板/Fold 大屏布局
### 建议下阶段
- 后端升级 HTTPS + WebSocket(替代 SSE)
- 消息本地全文搜索(FTS)
- 桌面小部件(App Widget)
- 快捷方式(Shortcuts)
- 无障碍适配(TalkBack)
---
> 本文档基于代码实际状态生成(2026-07-27),版本 v1.3.0。
> 项目路径: `D:\workspace\aiagent\android`