基于 Claude Code 练手开发的微信小程序健康 AI 对话项目。全程用自然语言驱动 Claude Code 编写前后端代码、Docker 部署、域名备案上线。
前端微信小程序,后端 Django + Daphne ASGI。核心是一个自研的 AI HealthAgent 对话管线,调用 DeepSeek V4 API 实现多轮健康咨询,支持 Function Calling 工具调用、流式输出、上下文压缩。用户可通过手机号注册登录,与三种人设(小康、小暖、小荷)的 AI 对话,获得饮食、运动、睡眠、心理等方面的健康建议。
HealthAgent 类位于 ai_engine/agent.py,586 行手写管线,零框架依赖:
五阶段处理管线
- 安全扫描。心理危机关键词拦截转人工热线,医疗紧急词强制就医指引
- 上下文压缩。50 轮或 80% token 自动触发,分层截断旧消息后调 LLM 生成 200 字摘要替换原文
- 联网搜索。用户消息含"最新/新闻/推荐"等触发词时调 Tavily API 搜索,结果注入上下文
- LLM 调用。组装 System Prompt(人设 + 用户画像 + 动态认知 + 会话摘要)+ 历史对话 + 用户消息,POST DeepSeek API
- 结果处理。Markdown 转 HTML,安全包装,卡片标记解析
Function Calling 工具
用 DeepSeek 原生 tool_calls 替代手写正则标记。四个工具:
get_user_data。查询用户成就、标签、健康画像、计划进度、菜谱收藏create_recipe_card。生成菜谱卡片,含食材清单、烹饪步骤、贴士create_plan_card。生成健康计划卡片,含内容、频率、持续天数create_assessment_card。生成测评邀请卡片
流程是第一次 LLM 调用带 tools → AI 判断是否调工具 → 后端执行工具 → 结果注入上下文 → 第二次 LLM 调用生成自然语言回复。卡片数据从 tool_calls[].function.arguments 提取,JSON Schema 约束参数格式,不存在正则截断问题。
双通道传输
- HTTP 通道。
chat()方法同步返回完整回复 - WebSocket 通道。
chat_stream()方法异步流式输出。第一轮非流式调用检测 tool_calls → 执行工具 → 第二轮流式调用推 token 到前端
System Prompt 组装
system_prompt.py 动态拼装 7 个 block:BASE_PROMPT、人设模块、安全规则、边界规则、用户画像、动态认知标签、会话摘要。三个关键设计:
- 历史对话用
【历史对话开始/结束】标记包裹,告诉 AI "参考信息内容但不模仿旧助手的身份" - 用户隐私(年龄性别)存在 prompt 里但要求 AI "绝对不要明确提及"
- 新人首次对话注入 onboarding prompt 引导自我介绍
自研分层压缩引擎 ai_engine/middleware/summarization.py:
触发条件为轮次 ≥ 50 或 token 数超过 4096 的 80%。压缩策略保留最近 10 轮原文不动,其余分两段——很旧的截断到 60 字每条的标签提取,较新的截断到 120 字每条的要点保留。调 DeepSeek 生成 200 字中文摘要存入 SessionSummary 表。被压缩的消息设 is_compressed=True,后续 _load_chat_history() 只加载未压缩消息。但成就统计的 _count_consecutive_days() 不加过滤,保留全部历史数据。
另外,用户点击"清空对话"也是软删除——设 is_compressed=True 而非物理删除,同样保护成就数据。
卡片化交互。AI 生成的菜谱、计划、测评三种卡片,前端 message-card 组件根据 cardData.type 渲染不同样式和按钮。卡片持久化到 MySQL + card_status 状态字段,切换页面后已接受或已放弃的卡片只显示状态条不展开。
内容推荐。Django 管理命令 generate_recommendations 调用 Tavily 搜索健康资讯 → BeautifulSoup 抓取原文 → DeepSeek 精炼为结构化文章。支持定时 cron 自动生成。
测评系统。5 类测评(饮食、运动、睡眠、心理、压力)支持 full 全局测评(25 题合并提交)。双评分机制:选择题走本地加权公式,开放题(>15 字)单独调 AI 增强,最终报告取平均分。AI 失败降级本地公式,测评始终可提交。
成就系统。9 个成就徽章,ChatService.update_achievements() 每次加载时扫描全局数据更新进度。_count_consecutive_days 按北京时间逐日回溯连续聊天天数,断一天就重置。
管理员。管理员可通过"我的"页面进入管理面板,搜索用户手机号,开关 AI 对话权限和审批新用户。
- 后端:Django 4.2 + DRF + Django Channels + Daphne ASGI
- AI:DeepSeek V4 Flash API,原生 Function Calling + Streaming
- 数据库:MySQL 8.0 utf8mb4 + Redis 7
- 搜索:Tavily API
- 图片识别:Baidu AI
- 部署:Docker + Nginx + Let's Encrypt,阿里云 ECS Ubuntu 22.04
- 前端:微信小程序原生开发,subpackages 分包(主包 518KB)
- 认证:JWT(simplejwt),手机号 + 密码登录
AI Health Consultant/
Django_Ai_HealthConsultant/ # 后端 Django 项目
ai_engine/
agent.py # HealthAgent 核心智能体(586行)
system_prompt.py # 动态 System Prompt 拼装
tools/ # 用户数据查询、联网搜索、图片识别
middleware/ # 安全扫描、上下文压缩
prompts/ # 人设模块、边界规则、安全规则
apps/
chat/ # 对话:HTTP + WebSocket
users/ # 用户:手机号登录、管理员
plans/ # 计划:创建、打卡
profiles/ # 个人:测评、成就、健康画像
recommendations/ # 推荐:资讯生成、收藏
config/ # Django 配置、路由、ASGI
MiniProgram_HealthConsultant/ # 前端微信小程序
pages/chat/ # AI 对话页(501行)
components/message-card/ # 消息卡片组件
utils/ws.js # WebSocket 客户端
- 配置
.env(参考.env.example,填入 DeepSeek / Tavily / 百度 API Key 和 MySQL 密码) - Docker 部署
docker compose up -d --build - 数据库迁移
docker compose exec django python manage.py migrate - 微信开发者工具打开
MiniProgram_HealthConsultant/,改utils/config.js中的后端地址
请在此处添加 12 张功能截图:
- AI 对话界面(展示流式打字效果)
- 菜谱卡片(收藏 / 询问 / 不需要按钮)
- 计划卡片(接受后跳转打卡页)
- 计划打卡追踪页
- 内容推荐资讯列表
- "我的"个人页面(含管理入口)
- 成就徽章墙(已解锁 / 未解锁对比)
- 健康画像雷达图(5 维)
- 健康测评答题与结果
- 管理员用户管理面板
- 三大人设切换(小康 / 小暖 / 小荷)
- 手机号登录注册页
本项目全程使用 Claude Code(Anthropic 的 AI 编程工具)通过自然语言对话完成开发。包括需求分析、架构设计、代码编写、bug 修复、Docker 部署、域名备案上线等全流程。踩过的主要坑:
- 微信小程序主包 7.2MB 超限 → 删掉 towxml 富文本库改用原生 rich-text → 518KB
- WebSocket 卡片事件静默丢失 → ws.js 构造函数 listeners 漏了
card: [] - 流式输出 TOOL 标记重复推文本 → 重构成 Function Calling 一次性拿到 tool_calls
- MySQL 容器密码传不进 Django → docker compose restart 不重读 .env,必须 down + up
MIT