Skip to content

luoyuncn/JinJing

Repository files navigation

JinJing / 进境

进境是一款面向中文用户的 AI 健身智能体。它不是传统的打卡、视频课或课程库产品,而是一位可对话、会记录、能制定计划的 AI 私教。

当前一期方向已经从 iOS App 调整为飞书私聊机器人:先在飞书里打通 Agent、训练记录、计划生成、宝典前置召回和原生卡片交互,iOS App 后置。

产品定位

进境的核心差异化:

  • 对话式 AI 私教:用户通过自然语言和进境交流,获取训练建议、计划安排和训练反馈。
  • 真实数据落库:训练记录、用户档案、训练计划必须通过工具调用持久化,避免 AI 只在自然语言里“假装记住”。
  • 循证内容内核:每轮对话前由运行时检索健身宝典原文片段,作为 AI 私教回答的专业上下文。
  • 低打扰智能:Agent 能自己判断和记录时不打扰用户,只有影响正确性、安全性或计划质量时才主动追问。

MVP 方向

当前已确认的一期 MVP 是飞书私聊版本:

  • 飞书企业自建应用 + 机器人能力。
  • 只做私聊,不做群聊。
  • 使用飞书 WebSocket 长连接,本地即可接收消息和卡片回调。
  • 后端使用 ReAct-style tool-using Agent Runtime,不做固定工作流。
  • 参考 D:\dev\agent\yi-min-ai\ 的 Feishu Gateway、Adapter、CommandQueue 和卡片发送更新逻辑。
  • 飞书卡片使用 JSON 2.0 原生组件,不用 Markdown 承载正文。
  • 本地优先开发:Windows 跑后端和飞书 Gateway。
  • 数据层使用 SQLite,不上 Postgres、Redis、pgvector。
  • 健身宝典使用单 Markdown 源文件,启动时构建 SQLite chunks、FTS 和向量索引。
  • LLM 默认 DeepSeek,OpenAI 作为 fallback。
  • Web 搜索默认 Tavily,DuckDuckGo 兜底。

当前架构

进境后端现在由六个边界清晰的模块组成:

模块 核心文件 职责
飞书接入 app.gateway.adapters.feishu 连接飞书长连接、接收私聊消息和卡片回调,标准化为 NormalizedMessage
网关编排 app.gateway.server / command_queue.py 入站去重、同会话串行队列、占位卡、最终卡、追问卡和降级文本
Agent Runtime app.core.runtime / context.py 组装上下文、前置宝典召回、ReAct 循环、工具执行、pending question 和消息落库
宝典召回 app.manual.* / app.core.manual_recall_planner Markdown chunking、DashScope embedding、SQLite FTS/向量索引、混合召回和 prompt 注入
工具与领域 app.tools.* / skills/runtime/* 用户档案、训练记录、训练计划、追问、web search、message_send 和运行时 Skill 加载
存储与观测 app.storage.* / app.observability.* SQLite schema/repository、中文链路日志、可选 Langfuse

一次普通私聊的主链路:

FeishuAdapter
→ GatewayServer 预占消息并入队
→ AgentRuntime 还原用户输入
→ ManualRecallPlanner 生成宝典检索 query
→ recall_manual 注入宝典原文参考
→ ContextBuilder 注入 Soul / 时间 / AI 私教纲要 / profile / memories / skills
→ LLM ReAct:直接回答或调用业务工具
→ GatewayServer 更新飞书卡片
→ SQLite 写入消息、工具结果和运行状态

Agent 工具

MVP 暴露核心业务工具给 Agent;健身宝典不再作为模型可见 ReAct 工具,而是在第一次模型请求前由内部 recall_manual 召回原文片段并注入上下文。

  • user_profile_get / user_profile_update:读取和更新用户训练档案、偏好、限制。
  • training_log_create / training_log_recent:创建和查询训练记录。
  • training_plan_save / training_plan_get:保存和读取结构化训练计划。
  • skill_load:加载非宝典运行时 Skill,例如档案维护、训练记录复盘、训练计划设计。
  • askUserQuestion:必要时向用户追问,支持文本、单选、多选和数值输入。
  • web_search:进行外部搜索,Tavily 优先,失败不阻塞主链路。
  • message_send:向当前会话发送短消息。

宝典链路:

用户问题 + 最近对话 + 用户 profile + 长期记忆
→ ManualRecallPlanner 生成检索 query
→ recall_manual 执行 FTS + vector 混合召回
→ system prompt 注入 # AI 私教健身纲要 和 # 本轮宝典原文参考
→ ReAct 只处理业务工具

飞书体验

一期在飞书私聊里提供 ChatGPT-like 的对话体验:

  • 用户直接私聊“进境”机器人。
  • 收到消息后先回复占位卡片,再更新同一张卡片。
  • 普通回答、训练记录、训练计划、确认和追问都用飞书卡片展示。
  • 卡片使用飞书 JSON 2.0 原生组件:divcolumn_settablebuttonforminputselect_staticdate_picker
  • askUserQuestion 通过卡片按钮、输入框、选择器向用户追问。
  • 训练记录:用户自然语言汇报,Agent 自动解析、写入并给简短反馈。
  • 训练计划:Agent 生成并保存结构化计划,飞书卡片展示摘要。

一期暂不做 iOS、HealthKit、推送通知、APNs、本地通知、计划执行打卡流和用户全文编辑 Soul。

文档

开发计划

建议阶段:

  1. P0:飞书私聊一期设计文档与 README 落地。
  2. P1:Feishu Gateway + WebSocket 长连接 + 私聊消息标准化。
  3. P2:ReAct Agent Runtime + SQLite 业务工具 + 宝典前置召回。
  4. P3:飞书 JSON 2.0 原生卡片渲染器。
  5. P4:askUserQuestion 卡片交互、回调、pending/resume 状态机。
  6. P5:本地飞书私聊联调与验收。

当前实现

当前仓库已经包含飞书私聊一期 MVP 的 Python 后端骨架和核心实现:

  • app.gateway.adapters.feishu:基于 lark-oapi 长连接的飞书私聊消息与卡片回调适配器。
  • app.gateway.server:私聊消息去重、per-thread 队列、占位卡、同卡片更新、追问卡和降级文本。
  • app.gateway.cards:飞书 JSON 2.0 原生卡片渲染器,不使用 markdown 组件承载正文。
  • app.core.runtime:ReAct-style tool-using runtime,支持工具调用、pending question 和 callback resume。
  • app.core.manual_recall_planner:用主模型把用户问题、profile、历史和记忆整理为宝典检索 query。
  • app.manual:宝典 chunking、DashScope Embedding、hash-aware 索引、FTS/向量混合召回和 prompt 格式化。
  • app.tools:用户档案、训练记录、训练计划、askUserQuestion、web search、message_send 和运行时 Skill 加载。
  • skills/runtime:中文运行时流程指令,当前保留档案维护、训练记录复盘、训练计划设计。
  • app.storage:SQLite 表结构和仓储,覆盖消息、会话、训练、计划、卡片交互、pending question、manual chunks 和 vectors。

本地开发

安装依赖:

uv sync

创建本地环境变量文件:

cp .env.example .env

.env.example 刻意保持最简:

FEISHU_APP_ID=
FEISHU_APP_SECRET=
LLM_PROVIDER=deepseek
LLM_MODEL=deepseek-chat
DEEPSEEK_API_KEY=
DEEPSEEK_BASE_URL=https://api.deepseek.com
OPENAI_API_KEY=
TAVILY_API_KEY=
DASHSCOPE_API_KEY=
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
DASHSCOPE_EMBEDDING_MODEL=text-embedding-v4
DASHSCOPE_EMBEDDING_DIMENSIONS=1024
DASHSCOPE_EMBEDDING_BATCH_SIZE=10

DASHSCOPE_API_KEY 配置后会使用阿里云 DashScope OpenAI-compatible embeddings。DASHSCOPE_EMBEDDING_BATCH_SIZE 默认 10,用于避免 DashScope embedding 批量请求过大导致 400。未配置 DashScope 时,本地测试和开发会使用 deterministic embedding fallback,FTS 召回仍可用,但真实语义召回质量会明显下降。

如果只用长连接接收事件和卡片回调,默认不需要把 FEISHU_VERIFICATION_TOKENFEISHU_ENCRYPT_KEY 放进 env。

运行测试:

uv run pytest -q

检查本地 Gateway 配置和 workspace 路径:

uv run python -m app.gateway.main --check

日志默认使用中文链路输出:

链路=启动入口 阶段=配置加载完成
链路=飞书网关 阶段=消息处理开始
链路=Agent运行 ReAct步骤=1 阶段=模型请求
链路=Agent运行 阶段=工具调用开始 工具=training_log_create

可通过环境变量调整:

LOG_LEVEL=INFO
LARK_LOG_LEVEL=WARNING

LARK_LOG_LEVEL 默认是 WARNING,用于避免飞书 SDK 把带 access_keyticket 的 WebSocket URL 打进控制台。进境自己的 Gateway 和 Agent 日志仍会输出完整中文链路。

Langfuse 观测默认关闭。需要把 Agent 运行、ReAct 可观察步骤、模型请求、工具调用和工具结果上报到 Langfuse 时,在 .env 中增加:

LANGFUSE_ENABLED=true
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
LANGFUSE_HOST=https://cloud.langfuse.com
LANGFUSE_FLUSH_ON_RUN_END=true

实现方式参考 yi-min-ai:每条用户消息对应一个 agent.run trace,上下文构建对应 context.assemble span,每轮 ReAct 对应 react.step span,模型调用对应 llm.chat generation,工具调用对应 tool.<name> span。Langfuse 中体现的是可观察执行过程和工具链路,不包含隐藏 chain-of-thought。

本地联调

统一启动入口会加载同一个 .env、同一个 workspace,并构建一份共享的 AgentRuntime / JinjingRepository。不同流量入口只负责各自协议适配。

只启动小程序 BFF:

uv run python -m app.main --ingress miniprogram --workspace workspace --host 127.0.0.1 --port 8787 --channel-instance dev

同时启动飞书 Gateway 和小程序 BFF:

uv run python -m app.main --ingress feishu,miniprogram --workspace workspace --host 127.0.0.1 --port 8787 --channel-instance dev --adapter-id main

只启动飞书 Gateway:

uv run python -m app.main --ingress feishu --workspace workspace --adapter-id main

检查本地配置和 workspace 路径,不连接外部服务:

uv run python -m app.main --ingress miniprogram --workspace workspace --check

飞书入口需要先配置飞书企业自建应用、机器人能力、消息事件订阅和卡片回调订阅。小程序入口需要 LLM key;统一入口会从 .env 加载 LLM_PROVIDERDEEPSEEK_API_KEYOPENAI_API_KEY

Phase 2 小程序使用开发期本地身份:前端生成并持久化 mini_user_idsession_id,后端映射为 wechat_miniprogram 渠道;这里还没有接入完整微信登录。Chat 使用 wx.connectSocket 连接 /bff/miniprogram/chat,Training / Plan / Profile 使用 BFF 首屏 read view model。

小程序测试:

  1. 启动统一入口的小程序 BFF 命令。
  2. 用微信开发者工具打开 front_end/project.config.json
  3. 勾选开发环境不校验合法域名/TLS/HTTPS 证书。
  4. 进入 Chat,发送 你好,确认流式回复和工具状态能显示。
  5. 停掉后端再发送一次,确认出现错误和重试,而不是 mock 成功。
  6. 打开训练记录、训练计划、我的档案,确认空/错误/重试状态正常。

自动验证:

uv run pytest -q
npx -y -p typescript tsc -p front_end/tsconfig.json --noEmit

About

进境是一款面向中文用户的 **AI 健身智能体**,以 iOS App + 后端 SaaS 形态交付。 区别于市面上"打卡 / 追踪 / 视频课"类健身 App,进境的核心差异化是: - **对话式 AI 私教**:用户通过自然语言与 AI 交流,AI 主动指导训练。 - **循证内容内核**:训练建议来源于结构化的「健身宝典」知识源,而非模型自由发挥。 - **真实数据落库**:用户的训练记录、身体数据、计划进度全部经过工具调用持久化,杜绝 AI 幻觉式"我记住了"。 - **个性化训练计划**:基于用户档案与训练历史,AI 生成并迭代专属计划。

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors