使用说明
生物T传感器助手(LLM_App)
BioT Speech IoT项目的Python后端。主持人:
- A. FastAPI服务器 这暴露了
POST /chat对于Android应用程序。 - 一 LLM代理 (提供者不可知——Anthropic、OpenAI、DeepSeek、Gemini)。
- A. 正确的MCP服务器 (
FastMCP,流式HTTP,端口8002),暴露 传感器查询工具。 - 一 MQTT用户 将实时传感器读数镜像到SQLite中 代理可以查询的数据库。
系统角色: 这是BioT拆分的服务器端。 Android应用程序是客户端,它拥有手机上的Room数据库 实时图表。服务器的SQLite是一个单独的并行视图 相同的MQTT数据,仅由LLM使用。看 数据库架构.
目录
建筑
┌──────────────────────────────┐
│ Android app (BioT_Speech_IoT_App)
│ - Voice → VoiceCommandResolver
│ - QUERY_* + UNKNOWN → LlmQueryHandler
│ │
└──────┼───────────────────────┘
│ POST /chat { "message": "..." }
▼
┌────────────────────────────────────────┐
│ app/main.py (FastAPI, port 8001) │
│ ├── /health │
│ └── /chat ─► SensorAgent.run() │
│ │ │
│ ▼ │
│ app/agent.py │
│ (provider-agnostic) │
└──────┬─────────────────────┬────────────┘
│ HTTP │ tool calls
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Anthropic / OpenAI / │ │ mcp_server/ │
│ DeepSeek / Gemini API │ │ sensor_mcp_server.py │
│ (chosen by LLM_PROVIDER) │ │ FastMCP, port 8002 │
└───────────────────────────┘ └────────────┬───────────────┘
│ SELECT
▼
┌────────────────────────────┐
│ data/sensor_database.db │
│ (SQLite, read-only by MCP)│
└────────────▲───────────────┘
│ INSERT
┌─────────────────────┴─────────────────┐
│ mcp_server/mqtt_subscriber.py │
│ (background thread inside FastAPI) │
└─────────────────▲─────────────────────┘
│ subscribes Sensor/*
│
┌─────────────────┴─────────────────────┐
│ Mosquitto MQTT broker │
└─────────────────▲─────────────────────┘
│ publishes Sensor/*
┌─────────────────┴─────────────────────┐
│ ESP8266 + MPU-6050 + A3144 │
└───────────────────────────────────────┘
MCP服务器作为 子进程 FastAPI服务器-- app/main.py
在FastAPI生命周期启动期间生成它。代理通过HTTP到达它
上 localhost:8002。要公开部署,请更改 MCP_SERVER_URL 在 .env
而无需更改任何代码。
数据库架构
BioT系统具有 两个SQLite数据库。这是故意的 记录在这里,所以看起来不像是bug。
| 数据库 | 位置 | 编写人 | 读取人 | 目的 |
|---|---|---|---|---|
| 房间(电话) | /data/data/com.fhdw.biot.speech.iot/databases/sensor_database |
安卓 MainActivity 从MQTT消息 |
所有图表活动通过 LiveData |
反应式UI、离线图表、日期过滤器 |
| 服务器SQLite | LLM_App/data/sensor_database.db |
mqtt_subscriber.py 从MQTT消息 |
MCP工具(只读) | LLM历史查询、异常分析 |
两个数据库都使用 相同的模式 (参见 mqtt_subscriber._ensure_db_schema)
因此,代理的SQL查询对任何一个都以相同的方式工作。他们都订阅了
对于相同的MQTT主题,它们只是写入不同的文件。
为什么没有一个DB?
- Room位于Android应用沙箱中。MCP服务器无法访问它
没有
adb pull. - 将Room从Android应用程序中删除意味着重写每个图表
活动(
AccelActivity,GyroActivity,MagnetActivity,MainGraphActivity)从HTTP端点获取数据,并会破坏离线图表。 - 两个DB的“额外”成本是一个后台线程(
mqtt_subscriber)那个 不管怎样,他一直在跑步。与MQTT相比,磁盘开销可以忽略不计 系统处理的消息量。
先决条件
- Python 3.10+https://www.python.org/downloads/
uv(Astral的软件包管理器)。通过PowerShell安装:powershell -c "irm https://astral.sh/uv/install.ps1 | iex"- Mosquitto MQTT代理在同一台机器上运行(或可在局域网上访问)
- API密钥来自其中之一:Anthropic/OpenAI/DeepSeek/Gemini
快速开始
# 1. Clone and enter the project
cd C:\Users\Arun\Documents\School\BioT_Speech_IoT_LLM_App
# 2. Create a virtualenv and install dependencies
uv venv
.venv\Scripts\Activate.ps1
uv sync
# 3. Configure
copy .env.example .env
# … edit .env and set LLM_API_KEY
# 4. Make sure Mosquitto is running
net start mosquitto
# 5. Start the FastAPI server (which launches the MCP server + MQTT subscriber)
uv run python -m app.main
您应该看到以下日志行:
INFO | biot.app.main | Starting MCP sensor server on port 8002
INFO | biot.app.main | MCP server ready at http://localhost:8002/mcp
INFO | biot.app.main | Agent ready (provider=anthropic, model=claude-sonnet-4-6, mcp=http://localhost:8002/mcp)
INFO | biot.app.main | MQTT subscriber running (broker=127.0.0.1:1883)
INFO | uvicorn.error | Application startup complete.
快速烟雾测试:
curl.exe -X POST http://127.0.0.1:8001/chat `
-H "Content-Type: application/json" `
-d '{ "message": "How many gyro readings are in the database?" }'
端点
| 方法 | 路径 | 目的 |
|---|---|---|
GET |
/health |
活体检查-退货 { "status": "ok" } |
POST |
/chat |
发送自然语言查询,返回结构化JSON操作 |
/chat 请求
{ "message": "What is the latest gyro Y value?" }
/chat 回应
代理始终返回以下操作类型之一(请参见
docs/LLM_USE_CASES.md 对于完整模式):
{
"reply": "{ \"action\": \"answer\", \"tts\": \"Gyro axis Y is 0.45 degrees per second, 2 seconds ago.\" }"
}
Android应用程序的 LlmQueryHandler 解析内部JSON并分派操作。
项目布局
LLM_App/
├── app/
│ ├── main.py # FastAPI entry point + lifespan that starts MCP + MQTT
│ ├── agent.py # SensorAgent — provider-agnostic LLM orchestration
│ ├── database.py # Direct SQLite access helpers (used outside MCP)
│ ├── logger.py # Centralised rotating-file + console logger
│ └── providers/
│ ├── base.py # Abstract LLMProvider interface
│ ├── anthropic.py # Claude implementation
│ ├── openai.py # GPT implementation
│ ├── deepseek.py # DeepSeek implementation
│ ├── gemini.py # Gemini implementation
│ └── __init__.py # create_provider() factory
├── mcp_server/
│ ├── sensor_mcp_server.py # FastMCP server exposing 7 sensor tools
│ └── mqtt_subscriber.py # Background MQTT → SQLite writer
├── config/
│ └── settings.py # Settings class — reads from .env
├── docs/
│ └── LLM_USE_CASES.md # Source of truth for what the LLM must handle
├── data/
│ └── sensor_database.db # Server-side SQLite (created on first MQTT message)
├── logs/
│ └── biot.log # Rotating log file (5 MB × 3)
├── .env # Real credentials (gitignored)
├── .env.example # Safe template (committed)
├── pyproject.toml
└── README.md # ← you are here
环境变量
看 .env.example 对于规范列表。关键问题:
| 变量 | 必填 | 默认 | 备注 |
|---|---|---|---|
LLM_PROVIDER |
是的 | anthropic |
其中之一:人择、openai、deepseek、双子座 |
LLM_API_KEY |
yes | -- | 所选提供程序的密钥 |
LLM_MODEL |
否 | 每个提供者默认值 | 例如。 claude-sonnet-4-6 |
SQLITE_DB_PATH |
没有 | data/sensor_database.db |
服务器端数据库路径 |
SERVER_PORT |
没有 | 8001 |
FastAPI端口 |
MCP_SERVER_PORT |
没有 | 8002 |
MCP子进程端口 |
MQTT_BROKER_HOST |
没有 | 127.0.0.1 |
蚊子宿主 |
MQTT_BROKER_PORT |
没有 | 1883 |
莫斯基托港 |
切换LLM提供者
更改一行 .env:
LLM_PROVIDER=openai
LLM_API_KEY=sk-...
无需更改代码。工厂在 app/providers/__init__.py 解决
启动时正确执行。每个提供者都实现相同的 LLMProvider
抽象类,因此代理代码永远不知道使用的是哪一个。
要添加新的提供者(例如Mistral):
- 创建
app/providers/mistral.py子类化LLMProvider. - 添加
mistral到_SUPPORTED在app/providers/__init__.py. - 在中添加导入+返回分支
create_provider(). - 在中添加默认模型
config/settings.py.
添加新的MCP工具
- 添加一个
@mcp.tool()功能在mcp_server/sensor_mcp_server.py. - 添加相应
_TOOLS进入app/agent.py所以法学硕士知道 存在。 - 重新启动FastAPI服务器——MCP子进程随之重新启动。
该工具从以下位置调用 SensorAgent._dispatch_tool 通过HTTP,所以没有
SDK设置或注册模板超出了这两个文件。
故障排除
| 症状 | 可能原因 | 修复 |
|---|---|---|
MCP server unreachable at http://localhost:8002/mcp 在代理日志中 |
子进程在启动过程中崩溃 | 检查上面的终端输出是否有Python回溯——通常是缺少模块或端口冲突 |
Database file does not exist 从工具调用 |
MQTT订阅者尚未收到任何消息 | 确认Mosquitto正在运行,ESP8266正在发布,以及 MQTT_BROKER_HOST 匹配代理的IP |
FastAPI启动,但 /chat 总是返回“代理未就绪” |
LLM_API_KEY 为空或无效 |
在中设置密钥 .env 并重新启动 |
日志显示代理呼叫 execute_query 重复使用奇怪的SQL |
模型产生了列名幻觉 | 使用以下命令手动运行查询 sqlite3 要查看模式,请改进系统提示以明确提及列 |
| 端口8001正在使用 | 绑定到FastAPI端口的另一个进程 | 更改 SERVER_PORT 在 .env |
BioT语音物联网——LLM_App | FHDW汉诺威物联网2025-26