# Ai聊天 **Repository Path**: ai-learning_3/ai-chat ## Basic Information - **Project Name**: Ai聊天 - **Description**: ai-聊天 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-10 - **Last Updated**: 2026-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Flutter AI Chat (Ollama + Python + Flutter) Ollama 是一个可以在 本地电脑运行大模型(LLM) 的工具。 简单理解: Ollama = 本地版 ChatGPT 服务器 它可以让你 不用调用云 API(如 OpenAI 或 Anthropic),直接在本机运行模型。 优点:不需要网络 | 不需要 API Key | 数据不会上传云端 | 可以离线开发 AI 应用 | 本仓库是一个本地优先的 AI 聊天应用示例: - **模型运行时**:Ollama - **默认模型**:`qwen2.5:7b`(可替换) - **后端**:Python FastAPI - **前端**:Flutter ## 项目结构 ```text ai_chat/ ├── README.md ├── python/ │ ├── .env.example │ ├── requirements.txt │ ├── llm_client.py │ ├── api_client.py │ ├── prompt_designer.py │ ├── prompt_cli.py │ ├── prompt_engine.py │ ├── chat_api.py │ ├── example_call.py │ ├── test_role_cases.py │ └── test_prompt_designer.py ├── flutter_ai_chat/ │ ├── lib/ │ │ ├── config/app_config.dart │ │ ├── main.dart │ │ ├── models/chat_message.dart │ │ ├── models/prompt_profile_config.dart │ │ └── services/chat_service.dart │ ├── pubspec.yaml │ └── README.md ├── logs/ │ └── role_test_*.log ├── .vscode/ │ └── settings.json ├── .gitignore ├── scripts/ │ ├── check_prompt_schema.sh │ ├── export_prompt_templates.sh │ ├── prompt_ci_check.sh │ ├── run_role_tests.sh │ ├── start_api.sh │ └── start_flutter.sh ``` ## 文件功能说明 ### Python API(`python/`) - `chat_api.py`:FastAPI 服务入口,提供 `/health`、`/chat`、`/chat/stream`(SSE)接口,负责请求校验与响应封装。 - `llm_client.py`:Ollama 客户端封装,负责模型调用、健康检查与流式输出。 - `api_client.py`:Python API 客户端封装,统一处理请求发送、状态码异常与响应解析。 - `prompt_designer.py`:提示词设计模块,支持“角色 + 任务 + 输出格式”的结构化 Prompt 生成。 - `prompt_cli.py`:提示词命令行工具,支持列模板、看模板详情、渲染模板 Prompt。 - `prompt_engine.py`:Prompt 组装与响应解析核心,包含 `SystemPromptProfile`、`UserPromptProcessor`、`ResponseParser`。 - `test_role_cases.py`:角色测试脚本,验证多角色输入下 API 返回质量与基础断言。 - `test_prompt_designer.py`:提示词模块自测脚本,验证模板完整性与渲染输出。 - `test_sse_stream.py`:SSE 流式联调脚本,验证 `/chat/stream` 事件流(start/delta/end/error)与逐段输出。 - `example_call.py`:最小调用示例,便于快速验证接口链路。 - `.env.example`:环境变量模板(如模型名等配置项)。 - `requirements.txt`:Python 依赖清单。 ### Flutter 客户端(`flutter_ai_chat/lib/`) - `main.dart`:应用入口与主界面,包含聊天页、`role_name`/`rules` 选择、配置列表与配置编辑页面,并针对小屏/键盘场景做了布局防溢出适配(顶部限高滚动 + 底部输入区自适应)。 - `controllers/streaming_ai_controller.dart`:GetX 流式状态控制器,管理 SSE 连接状态、增量文本与重连提示。 - `services/chat_history_db.dart`:SQLite 聊天历史数据层(会话分组、CRUD、自动清理)。 - `services/database_bootstrap.dart`:数据库启动引导(桌面端自动切换 `sqflite_common_ffi`,避免 `MissingPluginException`)。 - `services/chat_service.dart`:前端 API 调用层,封装健康检查与聊天请求。 - `config/app_config.dart`:运行时后端地址配置,区分平台默认地址并支持 `--dart-define` 覆盖。 - `models/chat_message.dart`:聊天消息数据模型(用户/助手轮次)。 - `models/prompt_profile_config.dart`:Prompt 配置模型,包含配置列表、角色信息、规则集合与默认配置。 - `flutter_ai_chat/CONTRIBUTING.md`:Flutter 协作规范(文件功能概述、中文注释、分层约定与提交前检查)。 ### 脚本与辅助目录 - `scripts/start_api.sh`:一键启动 Python API(自动处理虚拟环境与依赖安装流程)。 - `scripts/start_flutter.sh`:一键启动 Flutter 客户端(自动处理常见模拟器启动流程)。 - `scripts/run_role_tests.sh`:执行角色测试脚本并输出结果。 - `scripts/export_prompt_templates.sh`:一键导出 Prompt 模板(版本化文件 + latest 别名)。 - `scripts/check_prompt_schema.sh`:校验模板导出 JSON 的协议版本与关键字段完整性(CI 推荐)。 - `scripts/prompt_ci_check.sh`:一键执行“导出 + 校验”,适合直接接入 CI Job。 - `logs/`:测试执行日志目录(如 `role_test_*.log`)。 - `.vscode/settings.json`:项目级编辑器配置。 - `.gitignore`:Git 忽略规则。 ## 快速开始 ### 1) 启动 Ollama 和模型 ```bash brew install ollama ollama serve ollama pull qwen2.5:7b ``` 验证: ```bash curl http://127.0.0.1:11434/api/tags ``` ### 2) 启动 Python API ```bash cd python python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt cp .env.example .env uvicorn chat_api:app --host 0.0.0.0 --port 8000 --reload ``` 验证: ```bash curl http://127.0.0.1:8000/health ``` 快捷方式(推荐): ```bash ./scripts/start_api.sh ``` 可选环境变量: - `HOST`(默认 `0.0.0.0`) - `PORT`(默认 `8000`) 示例: ```bash HOST=127.0.0.1 PORT=9000 ./scripts/start_api.sh ``` ### 3) 运行 Flutter 客户端 ```bash cd flutter_ai_chat flutter pub get flutter run --dart-define=API_BASE_URL=http://10.0.2.2:8000 ``` 快捷方式(推荐): ```bash ./scripts/start_flutter.sh ``` 该脚本默认行为: - 优先使用**已启动的 iOS 模拟器** - 若没有已启动的 iOS 模拟器,会自动启动一个再执行 `flutter run` - iOS 默认后端地址使用 `http://127.0.0.1:8000` 可选: - 通过环境变量指定后端地址(默认 `http://10.0.2.2:8000`): - iOS 默认:`http://127.0.0.1:8000` - Android 默认:`http://10.0.2.2:8000` ```bash API_BASE_URL=http://127.0.0.1:8000 ./scripts/start_flutter.sh ``` - 指定设备 ID: ```bash ./scripts/start_flutter.sh ``` - Android 模拟器使用 `10.0.2.2` - iOS 模拟器可用 `http://127.0.0.1:8000` - 真机请替换为电脑局域网 IP Flutter 端已接入 AI API 的提示词模板能力: - 聊天页可选择 `prompt_template`(代码生成/优化/Bug 分析/冒烟测试/上线打包) - 每个模板内置多个案例问题,可一键填入输入框进行验证 - 发送消息时会自动携带 `prompt_template_key` 调用后端 `/chat` - 启动后会尝试从后端 `GET /prompt/templates` 动态拉取模板元数据(失败则回退本地默认模板) Flutter 客户端已支持语音输入: - 输入区支持点击开始/停止,也支持按住说话、松手结束 - 识别文本自动回填输入框,并在最终识别后触发现有发送流程 - 语音状态与失败提示保持与现有 UI 状态管理一致 - 为避免插件异常,语音能力仅在 Android/iOS 真机启用(模拟器/桌面/Web 会给出提示并阻止启动) 同时已接入 SSE 流式能力(`/chat/stream`): - 发送后 AI 逐段输出(前端按增量实时渲染) - 连接异常时自动重试,并在输入区显示“重连中”状态 - 结束事件后收敛为完整回答文本,兼容现有错误处理与加载状态模式 聊天历史采用 SQLite 本地持久化: - 按会话分组展示,支持会话重命名/删除 - 会话内支持消息编辑与删除 - 启动自动恢复最近会话 - 内置按时间与数量上限的清理机制,防止数据库无限增长 ## 测试案例脚本(多角色回答) 已内置一个测试脚本,验证同一问题在不同专业角色下的回答质量: - 问题:`Flutter是什么?` - 角色:资深移动开发者、产品经理、UI/UX 设计师 - 校验:接口状态、回答长度、关键字(`Flutter`)等基础断言 执行前请确保 Python API 已启动,然后运行: ```bash ./scripts/run_role_tests.sh ``` 可选指定后端地址: ```bash API_BASE_URL=http://127.0.0.1:8000 ./scripts/run_role_tests.sh ``` 也可以直接运行 Python 脚本并传入参数(更适合调试): ```bash python python/test_role_cases.py --api-base-url http://127.0.0.1:8000 --question "Flutter是什么?" ``` 脚本同样支持参数透传(更省输入): ```bash ./scripts/run_role_tests.sh --question "Flutter是什么?" ``` 调试 `messages` 组装时建议开启: ```bash python python/test_role_cases.py --include-debug-messages ``` 或使用脚本透传: ```bash ./scripts/run_role_tests.sh --include-debug-messages ``` 保存回归日志到 `logs/`(自动文件名): ```bash ./scripts/run_role_tests.sh --save-log ``` 指定日志文件名: ```bash ./scripts/run_role_tests.sh --save-log --log-file logs/role_test_manual.log ``` 额外运行错误用例并断言错误码: ```bash ./scripts/run_role_tests.sh --include-error-cases ``` 说明:当前内置错误用例会断言 `INVALID_USER_INPUT`,用于验证错误响应契约没有被破坏。 如果你希望连通过用例也打印 `debug_messages`(演示教学场景): ```bash python python/test_role_cases.py --include-debug-messages --print-debug-on-pass ``` 提示词模块自测: ```bash python python/test_prompt_designer.py ``` ## 代码质量检查与编译验证 建议在提交前执行以下命令,确保基础质量稳定。 推荐总入口(一条命令跑核心检查): ```bash ./scripts/check_all.sh ``` 如果你本机暂时不跑 Flutter 检查,可用: ```bash ./scripts/check_all.sh --skip-flutter ``` ### Python(在仓库根目录执行) ```bash # 语法编译检查(不执行业务逻辑) python3 -m compileall python # 提示词模块自测 python3 python/test_prompt_designer.py # 角色测试脚本参数检查(不依赖后端) python3 python/test_role_cases.py --help # SSE 流式脚本参数检查(不依赖后端) python3 python/test_sse_stream.py --help ``` 如需校验模板导出协议(推荐): ```bash # 一键导出 + schema 校验 ./scripts/prompt_ci_check.sh ``` ### Flutter(在 flutter_ai_chat 目录执行) ```bash # 代码格式化 dart format lib # 静态分析 flutter analyze ``` 建议在本地补做一次小屏验证(防止 UI 回归出现 `RenderFlex overflowed`): ```bash flutter run ``` 然后在模拟器中触发键盘并输入长文本,确认顶部配置区和底部输入区均无溢出告警。 如果你希望在 CI 中严格检查格式(有未格式化内容则失败),可用: ```bash dart format --output=none --set-exit-if-changed lib ``` ## Python API 指南 这一节把 Python 接口按“先跑通、再定位、再处理错误”拆成三块,方便新同学快速上手。 ### 5 分钟快速上手 1. 启动 Ollama 并确认可用: ```bash curl http://127.0.0.1:11434/api/tags ``` 2. 启动 Python API: ```bash ./scripts/start_api.sh ``` 3. 检查 API 健康状态: ```bash curl http://127.0.0.1:8000/health ``` 4. 发起最小聊天请求: ```json { "user_input": "Flutter是什么?", "history": [], "role_name": "资深移动开发者", "domain": "跨平台移动开发", "rules": ["先给结论", "再给关键点"], "include_debug_messages": false } ``` 正常响应示例: ```json { "text": "Flutter 是 Google 推出的跨平台 UI 框架...", "status": "ok" } ``` 5. 验证 SSE 流式输出(逐段打印): ```bash python3 python/test_sse_stream.py \ --api-base-url http://127.0.0.1:8000 \ --question "请给我一个 Flutter 列表分页实现思路" ``` ### 错误码对照表 接口错误统一返回结构: ```json { "code": "UPSTREAM_MODEL_ERROR", "message": "上游模型调用失败", "detail": "Ollama request failed after retries: ...", "request_id": "a1b2c3d4..." } ``` 字段说明: - `code`:机器可读错误码(前端建议按这个字段分支)。 - `message`:简短中文描述。 - `detail`:详细排障信息。 - `request_id`:请求追踪 ID,可用于日志检索。 错误码清单: - `REQUEST_VALIDATION_ERROR`:请求参数校验失败(通常 `422`)。 - `INVALID_USER_INPUT`:输入内容非法(通常 `400`)。 - `OLLAMA_UNAVAILABLE`:无法连接 Ollama(通常 `503`)。 - `UPSTREAM_MODEL_ERROR`:上游模型调用失败或响应结构异常(通常 `502`)。 - `INTERNAL_SERVER_ERROR`:服务内部未预期错误(通常 `500`)。 前端处理建议: - 参数类错误:直接提示用户修正输入。 - 上游类错误:提示稍后重试,同时展示 `request_id`。 - 内部错误:统一错误提示并记录 `request_id`。 ### 调试手册 推荐排查顺序: 1. **先测模型层** - `curl http://127.0.0.1:11434/api/tags` 2. **再测 API 层** - `curl http://127.0.0.1:8000/health` 3. **再测业务链路** - `python python/example_call.py --only-api` 4. **最后做回归** - `./scripts/run_role_tests.sh --include-error-cases --save-log` 调试 `messages` 拼装时,可在 `/chat` 请求里开启: ```json { "include_debug_messages": true } ``` 响应会附带 `debug_messages`,用于确认最终发送给模型的上下文。 ### messages 结构与角色说明 `/chat` 内部按以下顺序组装 `messages`(顺序很关键): ```json [ {"role": "system", "content": "系统规则/角色设定"}, {"role": "user", "content": "历史用户提问"}, {"role": "assistant", "content": "历史助手回答"}, {"role": "user", "content": "当前用户提问"} ] ``` - `system`:定义全局规则和角色身份,优先级最高。 - `user`:用户任务输入。 - `assistant`:历史回答,保证上下文连续性。 这种分层结构可以减少回答漂移、增强上下文理解,并提升可调试性。 ### 提示词设计模块(新增) 项目已新增 `python/prompt_designer.py`,用于按固定结构生成 Prompt: - 角色(role) - 任务(task) - 输出格式(output_format) 示例(与当前默认结构一致): ```text 你是资深Flutter架构师 用户问题: 如何实现分页列表? 请输出: 1 方案说明 2 示例代码 3 注意事项 ``` 在 `/chat` 中会自动使用该结构化模板包装 `user_input`,提升输出稳定性。 新增 5 个以 Flutter 为主的预置模板(后续可扩展其他语言): - `flutter_code_generation`:代码生成 - `flutter_code_optimization`:代码优化 - `flutter_bug_analysis`:Bug 分析 - `flutter_smoke_test`:冒烟测试 - `flutter_release_packaging`:上线打包 每个模板的标准问题示例 + 预期输出骨架: - `flutter_code_generation`(代码生成) - 示例问题:请实现一个带下拉刷新的 Flutter 新闻列表页,要求支持空状态和加载中状态。 - 预期输出骨架:`1 方案说明` / `2 示例代码` / `3 集成步骤` / `4 注意事项` - `flutter_code_optimization`(代码优化) - 示例问题:当前首页列表滚动卡顿,build 方法频繁触发,如何优化? - 预期输出骨架:`1 问题定位` / `2 优化策略` / `3 优化后代码` / `4 回归验证建议` - `flutter_bug_analysis`(Bug 分析) - 示例问题:点击详情页返回后列表状态丢失,如何定位并修复? - 预期输出骨架:`1 根因分析` / `2 修复方案` / `3 修复代码` / `4 防回归建议` - `flutter_smoke_test`(冒烟测试) - 示例问题:请给登录、列表、详情这三条主流程设计最小冒烟测试清单。 - 预期输出骨架:`1 测试范围` / `2 测试用例清单` / `3 执行步骤` / `4 风险与注意事项` - `flutter_release_packaging`(上线打包) - 示例问题:Flutter iOS/Android 双端准备上线,请给出打包与提审检查流程。 - 预期输出骨架:`1 发布准备` / `2 打包命令` / `3 上线检查清单` / `4 回滚预案` 调用方式(示例): ```bash python python/example_call.py --only-api --prompt-template-key flutter_bug_analysis --question "ListView 滑动时偶发卡顿并掉帧,怎么定位?" ``` 模板查看工具(无需读源码): ```bash # 列出全部模板 python python/prompt_cli.py --list-templates # 查看某个模板详情 python python/prompt_cli.py --show-template flutter_bug_analysis # 渲染模板 Prompt(可直接复制调试) python python/prompt_cli.py --render-template flutter_bug_analysis --question "点击详情页返回后列表状态丢失,如何定位并修复?" # 导出模板元数据(可给前端配置中心读取) python python/prompt_cli.py --export-json templates.json # 导出时自动在文件名追加版本号(便于多版本并存) python python/prompt_cli.py --export-json templates.json --export-json-with-version # 导出最新版本并维护固定别名(前端可固定读取 latest 文件) python python/prompt_cli.py --export-json templates.json --export-json-with-version --latest-symlink templates.latest.json # 仅输出导出协议版本(适合 CI 快速校验) python python/prompt_cli.py --schema-version # 一键导出(推荐,内置版本化 + latest) ./scripts/export_prompt_templates.sh # 校验导出文件结构(CI 推荐) ./scripts/check_prompt_schema.sh # 一键执行导出 + 校验(CI 入口) ./scripts/prompt_ci_check.sh ``` 导出 JSON 包含 `schema_version`,用于前端做版本兼容判断;当前模板以 Flutter 为主,并预留了 `extensible_languages` 字段供后续扩展其他语言。 CI 已提供示例工作流:`.github/workflows/prompt-ci.yml`,在 PR/Push 时自动执行模板导出与 schema 校验,并始终上传模板产物(保留 7 天)方便排障。 ### 关键环境变量(`python/.env`) - `OLLAMA_BASE_URL`:默认 `http://127.0.0.1:11434` - `OLLAMA_MODEL`:默认 `qwen2.5:7b` - `OLLAMA_TIMEOUT_SECONDS`:默认 `60` - `OLLAMA_MAX_RETRIES`:默认 `3` 建议先用默认值;如果响应常超时,再逐步调大 `OLLAMA_TIMEOUT_SECONDS`。 ## 三个核心概念落地 - **System Prompt**:`python/prompt_engine.py` 的 `SystemPromptProfile` - **User Prompt**:`python/prompt_engine.py` 的 `UserPromptProcessor` - **Response**:`python/prompt_engine.py` 的 `ResponseParser` + Flutter `ChatService` ## 模型替换 修改 `python/.env`: ```bash OLLAMA_MODEL=llama3.1:8b ``` 无需改 Flutter 代码。