[i=s] 本帖最后由 WT_0213 于 2026-7-31 14:21 编辑 [/i]
上视频
改了好多版本,这个算是比较完善的。还在继续优化中。模型都是用的免费的感觉也可以了。手机搭档这个版本我比较喜欢。也可以换成平板。想的是做个小镜子放到平板摄像头位置,类似学习机那种效果。时间不太够用,只能慢慢来了。初版就这样了。给娃娃定好任务。签到打卡兑奖。一句话搞定学习问题。养成良好习惯。
内容有些乱。边做边写。
这个项目有服务+Android
通过小安Ai-WV01-32S作为主控。直接问答。或者连接Android机,直接进行APP的操控。想着用磁吸了。因为手机不支持,没办法体现了。
Android 端可以调用相机,拍照直接给结果,比RTSP方案快很多。
更直观一些。
然后就是服务+BW21
RTSP 摄像头 BW21

之前做的 【电子DIY作品】基于BW21-CBV-Kit火灾隐患警报器
拍照识别作业是否正确给出建议。
想着 Ai-WV01-32S+BW21 + 小安派 R1/R2
结果发现,服务端配合AI就写了快二十天了,就晚上回来都睡下了,起来写一写,服务完善了以后,发现BW21 , RTSP流延迟非常高,调整服务和RTSP代码,后来限制清晰度,终于到了能用的状态。
Ai-WV01-32S 代码微调了一下,总体还是基于源代码做了一点点改动主要是串口数据部分,准备对接小安派R1的。站在前人的肩膀上了属于是。
做这个主要是想为家里宝贝规划任务,让宝贝能够清晰看到当天任务完成情况。兑换奖励激励更好的完成每日任务。服务端做的相对丰富一些。硬件部分有些着急感觉还能 做的更完善。
硬件一直想着能够模块化。想了好到方案,怎么组合这些硬件。
目前想到的 pogopin 、弹片连接器 这两种连接器不用插拔。
第一种比较占地方,第二种不好固定。想要做好东西还是比较难呀。
后来再试放弃了,直接插拔了,先设计外壳。下面是AI-WV01-32S的外壳示例图。


核心模块 AI-WV01-32S


可以复用。
硬件
AI-WV01-32S
Ai-WV01-32S 如果出厂固件是商用版,一定要先联网授权以后再,烧录开源版。不然商用版授权好像就没了。
仓库地址 : https://gitee.com/Ai-Thinker-Open/aipi-palchatv1
Ai-WV01-32S模组的使用可以参考
【小安AI】Ai-WV01-32S模组使用体验
参考电路:

也可以看下
【体验】Ai-WV02-32S 这不就跑起来了么
配网参考
安信可AiPi-PalChatV1 + 开箱 + 配网
配网逻辑都一样
Ai-WV01-32S 与 Ai-WV02-32S 对比

Ai-WV02-32S可用gpio更多一些
固件
有固件号的为官方正式固件,无固件号的为测试版固件。
| 适用型号 |
固件号 |
固件描述 |
版本 |
是否支持 UART-MCP |
下载链接 |
提示音 |
| AiPi-PalChatV1 |
X020 |
AiPi-PalChatV1 初版出厂固件 |
V1.9 |
❌ |
点击下载 |
/ |
| AiPi-PalChatV1 |
X020 |
AiPi-PalChatV1 兼容商用版 |
V2.1 |
❌ |
点击下载 |
/ |
| AiPi-PalChatV1 |
X020 |
AiPi-PalChatV1 支持MCP控制(⭐Ai-WV01 同款固件) |
V2.3 |
❌ |
点击下载 |
/ |
| AiPi-PalChatV1 离线语音芯片 |
X020 |
AiPi-PalChatV1 离线语音固件(适用于V1.9版本) |
V1.0 |
❌ |
点击下载 |
/ |
| AiPi-PalChatV1 UART-MCP |
/ |
AiPi-PalChatV1 串口MCP交互固件 |
V2.8 |
✅ |
点击下载 |
/ |
| AiPi-PalChatV1 |
/ |
角色“湾湾小何”提示音测试固件 |
V2.9 |
❌ |
点击下载 |
|
| AiPi-PalChatV1 |
/ |
角色“天才童声”提示音测试固件 |
V2.9 |
❌ |
点击下载 |
|
| AiPi-PalChatV1 |
/ |
角色“佩奇猪”提示音测试固件 |
V2.9 |
❌ |
点击下载 |
|
| AiPi-PalChatV1 |
/ |
角色“湾湾小何”提示音测试固件 |
V3.0 |
✅ |
点击下载 |
|
| AiPi-PalChatV1 |
/ |
英文版固件 |
V2.9 |
❌ |
点击下载 |
/ |
| AiPi-PalChatV1 |
/ |
角色“湾湾小何”提示音测试固件 |
V3.2 |
✅ |
点击下载 |
|
烧录固件
接线
| USB转TTL |
Ai-WV01-32S |
| 5V(可选) |
5V (功放) |
| 3V3 |
3V3 |
| GND |
GND |
| TXD |
RXD |
| RXD |
TXD |
| DTR |
IO8 |
| RTS |
EN |
这里如果打印了PCB就不用看这个了,直接插Type-c口就可以了


烧录
烧录方式直接照搬官方烧录方式即可。使用上面推荐的串口工具可以自动下载程序。
- 1.打开正确的 COM 口
- 2.勾选
enable,选择合并好的固件
- 3.点击烧录
- 4.烧录完成

BW21
BW21源码
#include "WiFi.h"
#include "StreamIO.h"
#include "VideoStream.h"
#include "RTSP.h"
#define CHANNEL 0
// Default preset configurations for each video channel:
// Channel 0 : 1920 x 1080 30FPS H264
// Channel 1 : 1280 x 720 30FPS H264
// Channel 2 : 1280 x 720 30FPS MJPEG
// ========== 视频编码核心配置 ==========
// 参数顺序:分辨率、帧率、编码格式、快照模式
// 错题识别推荐 720P,编码和带宽延迟更低;需1080P改回 VIDEO_FHD 即可
VideoSetting config(VIDEO_D1, CAM_FPS, VIDEO_H264, 0);
RTSP rtsp;
StreamIO videoStreamer(1, 1); // 1 Input Video -> 1 Output RTSP
char ssid[] = "WIFI"; // SSID (name) BW21可以连5GWIFI
char pass[] = "密码"; // password 密码
int status = WL_IDLE_STATUS;
void setup()
{
Serial.begin(115200);
// attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 2 seconds for connection:
delay(2000);
}
// ========== 优化2:编码侧核心低延迟参数 ==========
// 必须在 configVideoChannel 之前设置完成
config._gop = CAM_NN_GOP; // GOP=12,30fps下每0.4秒一个I帧,抓拍等待时间缩短60%+
config.setBitrate(1600000); // 1.6Mbps,720P文字识别完全足够
config._rc_mode = 1; // 强制 CBR 恒定码率,避免VBR波动导致接收端缓冲堆积
// 关闭B帧:设置H.264为 Baseline profile(天然无B帧,消除编码帧缓存)
// 参数:level=31(Level3.1), profile=66(Baseline), entropy_mode=0(CAVLC)
config.setH264EncParams(31, 66, 0);
// 配置视频通道 + 初始化视频系统
Camera.configVideoChannel(CHANNEL, config);
Camera.videoInit(); // 内部自动完成摄像头初始化,禁止手动调用camInit
// ========== 优化3:缩小编码输出队列,减少内部帧堆积 ==========
// 队列长度设为2,仅保留最少缓冲,避免已编码帧在板端堆积延迟
Camera.setQLen(CHANNEL, 2);
// 配置并启动 RTSP 服务
rtsp.configVideo(config);
rtsp.begin();
// 绑定视频流到 RTSP 输出
videoStreamer.registerInput(Camera.getStream(CHANNEL));
videoStreamer.registerOutput(rtsp);
if (videoStreamer.begin() != 0) {
Serial.println("StreamIO link start failed");
}
// 启动视频通道输出
Camera.channelBegin(CHANNEL);
delay(1000);
printInfo();
}
void loop()
{
// Do nothing
}
void printInfo(void)
{
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("- Summary of Streaming -");
Serial.println("------------------------------");
Camera.printInfo();
IPAddress ip = WiFi.localIP();
Serial.println("- RTSP -");
rtsp.printInfo(ip.get_address());
}
服务端
部署:
1、Windows系统
在Windwos系统下找个地方创建个文件夹将manager_windows_amd64.exe放进去,例如

直接运行 kids-task-manager_windows_amd64.exe 文件
文件会同步生成kids-task-data.db数据库文件就可以直接使用了。
这里增加了 小智mcp服务

2、Linux 系统
这里手上有个arm小板子,debian系统的高通410的WIFI棒子,高功耗低跑小小服务也够用了。
使用lucky反向代理可以用域名访问
https://mp.weixin.qq.com/s/-flZPg7SDjpZheZ-m6P1UA
免费域名
dnshe.com
加了这种扩展板 https://oshwhub.com/zy143l/ufi_hub_rj45_share

目前内存占用极低

创建项目存放目录
mkdir /opt/kids-task-manager/
user@WiFi-Debian:~$ ll /opt/kids-task-manager/
总用量 9120
drwxr-xr-x 1 user user 92 7月 16 11:13 .
drwxr-xr-x 1 root root 34 7月 14 22:46 ..
-rw-r--r-- 1 user user 94208 7月 16 11:13 kids-task-data.db
-rwxrwxrwx 1 user user 9240728 7月 16 10:55 kids-task-manager_linux_arm64
这里增加了 小智mcp服务

调整用户所属用户组
sudo chown -R $USER:$USER /opt/kids-task-manager
拉取文件
wget https://gitee.com/lazy-ai/kids-task-manager/raw/master/dist/kids-task-manager_linux_arm64
可执行
chmod 777 kids-task-manager_linux_arm64
创建服务
sudo nano /etc/systemd/system/kids-task.service
[Unit]
Description=Kids Task Manager Service
After=network.target
[Service]
User=user
Group=user
WorkingDirectory=/opt/kids-task-manager
ExecStart=/opt/kids-task-manager/kids-task-manager_linux_arm64
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
#重载服务
sudo systemctl daemon-reload
#设置开机自启
sudo systemctl enable kids-task.service
#立即启动服务
sudo systemctl start kids-task.service
这样服务就启动了
user@WiFi-Debian:~$ systemctl status kids-task
● kids-task.service - Kids Task Manager Service
Loaded: loaded (/etc/systemd/system/kids-task.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2026-07-16 10:56:07 CST; 3h 40min ago
Main PID: 413582 (kids-task-manag)
Tasks: 7 (limit: 511)
Memory: 8.1M
CPU: 3.371s
CGroup: /system.slice/kids-task.service
└─413582 /opt/kids-task-manager/kids-task-manager_linux_arm64
7月 16 10:56:07 WiFi-Debian kids-task-manager_linux_arm64[413582]: 🚀 宝贝任务管理服务已启动
7月 16 10:56:07 WiFi-Debian kids-task-manager_linux_arm64[413582]: 本机访问: http://localhost:8080
7月 16 10:56:07 WiFi-Debian kids-task-manager_linux_arm64[413582]: 局域网访问: (同一 WiFi / 网段下的手机、其他电脑可直接打开)
7月 16 10:56:07 WiFi-Debian kids-task-manager_linux_arm64[413582]: http://192.168.50.137:8080
7月 16 10:56:07 WiFi-Debian kids-task-manager_linux_arm64[413582]: 📁 数据库文件: kids-task-data.db
可以看到设备地址和端口
如果想使用文件url进行视觉识别,则需要创建一个静态文件的服务
这里将文件存到内存卡中了。
检查当前用户
id $user
user@WiFi-Debian:~$id $user
用户id=1000(user) 组id=1000(user) 组=1000(user),20(dialout),27(sudo),29(audio),44(video),46(plugdev)
调整挂载sdcard的用户uid=1000,gid=1000
sudo nano /etc/fstab
user@WiFi-Debian:~$ cat /etc/fstab
LABEL=arch64 / btrfs defaults,noatime,compress=zstd,commit=120 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
UUID=7DFE-5FCD /mnt/sdcard exfat defaults,uid=1000,gid=1000,nofail,x-systemd.device-timeout=30,x-systemd.requires=/dev/disk/by-uuid/7DFE-5FCD 0 0
这里使用的是 busybox
命令
busybox httpd -h /mnt/sdcard/images -p 0.0.0.0:8081
终端执行只是前台 / 临时后台进程,一旦断开 SSH、设备重启,服务直接消失。
一、做成 systemd 开机自启(推荐,Debian 标准方案)
1. 创建服务文件
sudo nano /etc/systemd/system/img-httpd.service
粘贴下面内容
[Unit]
Description=Busybox image static server
After=local-fs.target network.target
[Service]
Type=forking
# 如果你只给穿透调用,强烈建议 127.0.0.1:8081,不要0.0.0.0
ExecStart=/usr/bin/busybox httpd -h /mnt/sdcard/images -p 0.0.0.0:8081
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
2. 生效并设置开机启动
sudo systemctl daemon-reload
# 设置开机自启
sudo systemctl enable img-httpd
# 立即启动服务
sudo systemctl start img-httpd
使用 url/图片名称就可以访问了
演示:









宝贝任务管理服务 (Kids Task Manager)
用 Go 写的家庭任务与积分小系统,带一个网页管理界面。给孩子派任务、攒积分、换奖励,家长在后台统一管理。
数据用 SQLite 存(纯 Go 驱动 modernc.org/sqlite,不依赖 CGO),所以整个程序就是一个二进制文件,Windows / macOS / Linux(含 ARM64,树莓派之类)都能直接跑。
能做什么
- 家庭成员:加家长和小孩。家长把任务派给某个孩子,每个孩子的任务和积分是分开的。
- 任务排期:支持单次某天、日期区间、每天、每周、每月这几种方式。
- 积分与奖励:完成任务实时加分,顶栏显示当前成员余额。家长设奖励(可限制库存,库存填 -1 表示不限量),孩子用自己的积分兑换。兑换后支持「取消兑换」,积分和库存会退回去。
- 奖励定向:奖励可以设为所有人可兑换,也可以只给某个孩子(专属奖励只有本人能看到、能兑换)。
- 日历视图:月历按完成度上色,点某天能勾当天的任务;也支持按周、按月的概览。
- 作业检查:给每个孩子留一条作业检查记录,含检查内容/评语、附件图片、以及错题(题目/答案/备注)。也能直接调接口录入。
- AI 检查:在作业检查里上传作业图片或填图片地址,自动调用配置好的大模型识别,生成一条检查记录(科目/内容/附件/错题)。提示词可以在系统配置里改,也能一键恢复默认;模型繁忙(1305/429/503)会按设置的次数自动重试。
- 登录保护:首页要输密码才能进(默认
123456),局域网里别人也看不到数据。
搭建 Go 环境
项目用 Go 1.22+,标准库加纯 Go 的 SQLite 驱动,不需要 GCC,交叉编译开箱即用。
1. 装 Go
到 https://go.dev/dl/ 下载(国内用 https://golang.google.cn/dl/ 更快),选对应系统的包:
-
Windows:下 go1.22.x.windows-amd64.msi 双击装。
-
macOS:Intel 选 darwin-amd64.pkg,Apple Silicon 选 darwin-arm64.pkg。
-
Linux:下 linux-amd64.tar.gz 解到 /usr/local:
bash
wget https://go.dev/dl/go1.22.x.linux-amd64.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.22.x.linux-amd64.tar.gz
装完把 Go 的 bin 目录加进 PATH(Windows/macOS 安装包一般自动加;Linux 要自己加,比如往 ~/.bashrc 里写 export PATH=$PATH:/usr/local/go/bin)。
2. 验证
bash
go version # 能看到版本号就行,比如 go version go1.22.5 linux/amd64
go env GOPATH
3. 配代理(国内网络)
依赖 modernc.org/sqlite,国内直连可能超时:
bash
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=off
如果公司网络要走 HTTP 代理,再设 HTTP_PROXY / HTTPS_PROXY(不需要就跳过)。
本项目锁了 modernc.org/sqlite 的兼容版本。如果 go build 提示要自动升级工具链,执行 go env -w GOTOOLCHAIN=local 用本地 Go 版本即可。
4. 拉代码、构建
bash
git clone https://gitee.com/lazy-ai/kids-task-manager.git
cd kids-task-manager
go mod download
go run . # 直接跑,浏览器开 http://localhost:8080
go build -o app . # 编译当前平台
快速开始
用预编译二进制
dist/ 里已经是各平台的成品:
bash
dist/kids-task-manager_windows_amd64.exe # Windows
dist/kids-task-manager_darwin_amd64 # macOS Intel
dist/kids-task-manager_darwin_arm64 # macOS Apple Silicon
dist/kids-task-manager_linux_amd64 # Linux x86_64
dist/kids-task-manager_linux_arm64 # Linux ARM64 / aarch64(树莓派、高通 Snapdragon 410 等)
跑起来后浏览器打开 http://localhost:8080 。
自己用 Go 跑 / 编译
bash
cd kids-task-manager
go run .
go build -o app .
交叉编译
bash
bash build.sh # macOS / Linux / Git Bash
powershell -File build.ps1 # Windows PowerShell
因为 SQLite 驱动是纯 Go 的,交叉编译不用 gcc。
自定义启动参数
bash
./kids-task-manager -addr :9000 -data mydata.db
-addr:监听地址,默认 :8080
-data:SQLite 文件路径,默认 kids-task-data.db
Linux 部署脚本
deploy.sh 会自动识别架构(x86_64 → linux_amd64,aarch64/arm64 → linux_arm64),挑 dist/ 里对应的二进制以守护进程方式跑起来:
bash
chmod +x deploy.sh
./deploy.sh start # 后台启动,默认 :8080
./deploy.sh status # 看运行状态
./deploy.sh restart # 重启
./deploy.sh stop # 停
./deploy.sh logs # 实时看日志
KTM_ADDR=:9000 KTM_DATA=/var/lib/ktm.db ./deploy.sh start # 自定义端口/数据文件
./deploy.sh build # dist/ 里没有对应二进制时,本机现场编译
脚本会把 PID 写进 kids-task-manager.pid,日志写进 kids-task-manager.log。优先用 dist/ 里的预编译文件,没有才 go build。远程访问记得开防火墙端口,用服务器 IP 代替 localhost。
怎么用
- 第一次启动会自动建好「家长」和「宝贝」两个成员。
- 点右上角 👪 成员 加孩子(也能加多个家长)。
- 切到某个成员视角,在 📋 任务 页点 + 添加任务:填标题、积分、指派给谁、排期方式。
- 在 🎁 奖励 页加可兑换的奖励;切到孩子视角点「兑换」就扣他的积分。
- 📊 统计 页看日历、完成度、积分汇总和最近动态。
- 📝 作业检查 页给某个孩子加一条检查记录:填科目、检查内容/评语,可传附件(作业照片),逐条登错题(题目/答案/备注)。也可以直接
POST /api/checks 批量写。
顶部的成员切换器决定当前视角:家长能看到所有孩子的任务并管理一切;孩子只看到自己的任务、奖励和积分。
登录
服务默认要登录:首页先弹登录框,输对密码才能看数据,避免局域网里别人随便访问。
- 默认密码
123456(没单独改过时生效)。
- 登录后令牌存在浏览器本地,刷新页面不用重登;重启服务后令牌作废,要再登一次。
- 改密码:进 ⚙️ 系统配置 最下面的 🔐 访问控制,填新密码点「保存密码」。留空会恢复成默认
123456。
AI 检查提示词
⚙️ 系统配置 的「大模型配置」里有一个提示词文本框:
- AI 检查时会把这段提示词连同作业图片一起发给大模型,让它识别并生成检查记录。
- 默认是一段内置提示词(要求模型只返回可解析的 JSON)。如果识别效果不理想,可以在这里改——比如强调科目顺序、错题格式、评语详略等。
- 点「恢复默认提示词」就还原成内置的那版。
目录结构
kids-task-manager/
├── go.mod # 模块定义(依赖 modernc.org/sqlite,纯 Go)
├── main.go # 服务入口、路由、内嵌前端
├── store.go # 数据模型 + SQLite 持久化
├── handlers.go # REST API 与业务逻辑
├── calendar.go # 日历/排期计算
├── api_test.go # 单元测试(内存路由,不需要端口)
├── build.sh # 跨平台构建脚本(bash)
├── build.ps1 # 跨平台构建脚本(PowerShell)
├── web/
│ ├── index.html # 管理页面
│ ├── style.css # 样式
│ └── app.js # 前端逻辑
└── kids-task-data.db # 运行时生成的 SQLite 数据库
API 一览
| 方法 |
路径 |
说明 |
| GET |
/api/members |
家庭成员列表 |
| POST |
/api/members |
新增成员 {name,role,emoji,color} |
| PUT |
/api/members/{id} |
编辑成员 |
| DELETE |
/api/members/{id} |
删除成员(级联删其任务/积分) |
| GET |
/api/tasks?member={id} |
任务列表(按成员隔离) |
| GET |
/api/tasks/range?start=&end=&member= |
按日期区间展开任务(缺省查当天) |
| POST |
/api/tasks |
新建任务 {title,points,member_id,mode,date,start_date,end_date,weekdays,monthdays,color} |
| PUT |
/api/tasks/{id} |
编辑任务 |
| DELETE |
/api/tasks/{id} |
删除任务 |
| POST |
/api/instances/toggle |
切换某次任务完成 {task_id,key} |
| GET |
/api/rewards |
奖励列表 |
| POST |
/api/rewards |
新建奖励 |
| PUT |
/api/rewards/{id} |
编辑奖励 |
| DELETE |
/api/rewards/{id} |
删除奖励 |
| POST |
/api/rewards/{id}/redeem |
兑换 {member_id};专属奖励非本人会被拒 |
| POST |
/api/redemptions/{id}/cancel |
取消兑换(仅本人、每笔一次,退积分/回补库存){member_id} |
| GET |
/api/redemptions?member= |
兑换记录列表(按成员过滤,含奖励标题) |
| DELETE |
/api/redemptions/{id} |
删除兑换记录并退积分 {member_id} |
| GET |
/api/calendar?member=&year=&month= |
月历数据 |
| GET |
/api/summary?member= |
积分汇总 |
| GET |
/api/history?member= |
最近动态(含 earn/redeem/refund) |
| GET |
/api/checks?member= |
作业检查记录列表(按成员过滤) |
| POST |
/api/checks |
新增检查记录(见下方「作业检查接口」) |
| PUT |
/api/checks/{id} |
编辑检查记录 {member_id,subject,content,attachments,wrong_questions} |
| DELETE |
/api/checks/{id} |
删除检查记录 |
| POST |
/api/login |
登录校验 {password},成功返回 {token}(公开接口) |
| POST |
/api/logout |
退出登录(使当前令牌失效) |
| GET |
/api/settings/access |
读取当前登录密码(需登录) |
| PUT |
/api/settings/access |
修改登录密码 {password},留空恢复默认 123456(需登录) |
| GET |
/api/settings/ai |
读取大模型配置(含 enabled/api_key/model/base_url/retry/prompt/default_prompt,default_prompt 是内置默认提示词,供「恢复默认」用)(需登录) |
| PUT |
/api/settings/ai |
保存大模型配置(同上字段,留空字段不覆盖已有值)(需登录) |
| POST |
/api/checks/ai |
AI 检查:传作业图片(attachments,data URL 数组)或图片 url,调大模型识别并自动建一条检查记录;需带 member(归属成员 id)和可选 subject(需登录) |
所有 /api/** 接口都开了 CORS(Access-Control-Allow-Origin: *),外部网页/小程序能直接调;跨域请求浏览器会先发 OPTIONS 预检,服务端已处理。
除 POST /api/login 和 GET /api/health 外,其余接口都要带登录后的会话令牌(请求头 Authorization: Bearer <token> 或 X-Auth-Token),否则返回 401。令牌存在浏览器 localStorage,重启服务后失效。
数据模型
- 成员 (members):
id, name, role(家长/孩子), color, emoji, balance
- 任务 (tasks):
id, member_id, title, points, mode(once/range/daily/weekly/monthly), date, start_date, end_date, weekdays, monthdays, color, active
weekly:weekdays 是逗号分隔的星期几(0=周日..6=周六,如 "1,3,5" 表示周一三五);为空时回退周日
monthly:monthdays 是逗号分隔的号(1..31,如 "1,15,20");为空回退每月 1 号;某月没有这个号(如 2 月 30 号)自动跳过
- 任务实例 (instances):某次出现(按
key,具体日期)的完成状态。每周/每月一个周期可能多天,所以每天独立记完成
- 奖励 (rewards):
id, title, cost, stock(-1 不限量), emoji, member_id(空=所有人可兑换;填某成员 id=仅其可见可兑换)
- 兑换记录 (redemptions):
id, reward_id, member_id, points, at, cancelled, cancelled_at
- 检查记录 (checks):
id, member_id, subject, content, attachments(JSON), wrong_questions(JSON), created_at
- 流水 (ledger):每次积分变动记录,类型
earn(获得) / redeem(兑换) / refund(取消或删除兑换后归还),用于历史和余额对账
- 系统设置 (settings):键值表,存
ai_config(大模型配置 JSON:enabled/api_key/model/base_url/retry/prompt)和 admin_password(登录密码,空或未设置时回退默认 123456)
删除成员会级联删其任务、实例、兑换和流水;删除任务模板会一并删完成记录。
接口调用示例
后端对所有 /api/** 开了 CORS,任意前端、脚本或小程序都能直接调。下面用 curl 演示「查奖励 → 兑换 → 删兑换记录退积分」:
bash
# 1) 查某成员的可用奖励(专属奖励已按 member 过滤)
curl "http://localhost:8080/api/rewards?member=m_child_001"
# 2) 用该成员身份兑换某个奖励
curl -X POST "http://localhost:8080/api/rewards/r_xxx/redeem" \
-H "Content-Type: application/json" \
-d '{"member_id":"m_child_001"}'
# => {"balance":50,"redemption_id":"rd_xxx"}
# 3) 查该成员的兑换记录
curl "http://localhost:8080/api/redemptions?member=m_child_001"
# 4) 删该兑换记录(退积分)
curl -X DELETE "http://localhost:8080/api/redemptions/rd_xxx" \
-H "Content-Type: application/json" \
-d '{"member_id":"m_child_001"}'
# => {"balance":100}
按日期区间查任务
GET /api/tasks/range 把各类重复任务(每天/每周/每月/指定日/区间)按天展开到给定区间,每天返回当天该做的任务、完成状态和可得积分。适合外部系统拉「今日待办」或「某段时间的计划」。
查询参数(都可省略):
| 参数 |
说明 |
缺省 |
start |
区间起始 YYYY-MM-DD |
今天 |
end |
区间结束 YYYY-MM-DD(含当天) |
等于 start(即查单天) |
member |
只查该成员 |
全部成员 |
bash
# 查某成员 2026/07/09 ~ 2026/07/10 的任务
curl "http://localhost:8080/api/tasks/range?member=m_child_001&start=2026-07-09&end=2026-07-10"
# 不传 start/end,默认查今天
curl "http://localhost:8080/api/tasks/range?member=m_child_001"
返回结构:
json
{
"start": "2026-07-09",
"end": "2026-07-10",
"member": "m_child_001",
"days": [
{
"date": "2026-07-09",
"weekday": 4,
"tasks": [
{"id": "i_xxx", "template_id": "t_xxx", "title": "刷牙", "points": 5, "done": true}
],
"done": 1,
"total": 2,
"points": 15
}
],
"summary": {"days": 2, "total_tasks": 4, "done_tasks": 1, "pending": 3}
}
days[].tasks[].id 是任务实例 id(没完成过就是空字符串),配合 template_id 和日期 date 就能调 POST /api/instances/toggle 勾选完成。
作业检查接口
「作业检查」的数据能直接通过 /api/checks 读写,适合家长用脚本、小程序或外部系统批量录入某次作业的检查结果(含图片附件和错题)。
字段说明
| 字段 |
类型 |
说明 |
member_id |
string |
必填,记录归属的孩子成员 id(对应的成员不存在会报 400) |
subject |
string |
科目,如「数学」「语文」(可选) |
content |
string |
检查内容 / 评语(可选,但 content / attachments / wrong_questions 至少填一个) |
attachments |
array |
附件列表,每项 {name, type, data},data 是 data:;base64,xxxx 形式的 data URL(比如作业照片) |
wrong_questions |
array |
错题列表,每项 {title, answer, note},对应题目 / 正确答案或解析 / 备注 |
新增一条检查记录
bash
# 给 m_child_001 加一条数学作业检查:评语 + 一张图片附件 + 一道错题
curl -X POST "http://localhost:8080/api/checks" \
-H "Content-Type: application/json" \
-d '{
"member_id": "m_child_001",
"subject": "数学",
"content": "竖式计算粗心,已订正",
"attachments": [
{
"name": "homework.jpg",
"type": "image/jpeg",
"data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDA...(省略 base64 内容)"
}
],
"wrong_questions": [
{"title": "23 + 19 = ?", "answer": "42", "note": "个位 3+9=12 进位漏写"},
{"title": "100 - 56 = ?", "answer": "44", "note": "退位错误"}
]
}'
# => {"id":"c_xxx","member_id":"m_child_001","subject":"数学","content":"竖式计算粗心,已订正",
# "attachments":[...],"wrong_questions":[...],"created_at":1752547200}
查询 / 编辑 / 删除
bash
# 查某成员的全部检查记录(不传 member 就查全部)
curl "http://localhost:8080/api/checks?member=m_child_001"
# 编辑某条记录(要带 member_id 做归属校验)
curl -X PUT "http://localhost:8080/api/checks/c_xxx" \
-H "Content-Type: application/json" \
-d '{"member_id":"m_child_001","subject":"数学","content":"已重新检查,全部正确"}'
# 删除某条记录
curl -X DELETE "http://localhost:8080/api/checks/c_xxx"
# => {"ok":true}
业务规则:
- 取消兑换(
POST /api/redemptions/{id}/cancel)和删除记录(DELETE /api/redemptions/{id})都会退积分;前者留着记录标「已取消」,后者直接删掉。两者都限本人操作,已取消的记录不再重复退。
- 只有限量奖励(
stock ≥ 0)且仍上架时,取消/删除才会回补库存。
- 专属奖励(有
member_id)对别人不可见也不可兑换,归属校验在服务端强制做。
- 检查记录创建时服务端会校验
member_id 对应的成员是否存在;content、attachments、wrong_questions 至少填一个,否则返回 400。
AI 检查与大模型配置接口
「作业检查 → 🤖 AI 检查」也能直接调接口。服务有登录保护,调用前先 POST /api/login 拿令牌,放到请求头 Authorization: Bearer <token>。
1) 配置大模型(以智谱 GLM 视觉模型为例)
bash
# 先登录拿令牌(默认密码 123456)
TOKEN=$(curl -s -X POST "http://localhost:8080/api/login" \
-H "Content-Type: application/json" -d '{"password":"123456"}' | sed -n 's/.*"token":"$[^"]*$".*/\1/p')
# 保存大模型配置:启用、API Key、模型、接口地址、重试次数、提示词(可选,留空用默认)
curl -X PUT "http://localhost:8080/api/settings/ai" \
-H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
-d '{
"ai": {
"enabled": true,
"api_key": "你的_API_Key",
"model": "glm-4.6v-flash",
"base_url": "https://open.bigmodel.cn/api/paas/v4/chat/completions",
"retry": 2
}
}'
# => {"ok":true}
# 读当前配置(default_prompt 是内置默认提示词,可用来「恢复默认」)
curl "http://localhost:8080/api/settings/ai" -H "Authorization: Bearer $TOKEN"
2) 调用 AI 检查(上传图片)
bash
# 传一张作业图片(data URL),让大模型识别并自动建一条检查记录
curl -X POST "http://localhost:8080/api/checks/ai" \
-H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
-d '{
"member": "m_child_001",
"subject": "数学",
"attachments": [
{"name":"homework.jpg","type":"image/jpeg","data":"data:image/jpeg;base64,/9j/4AAQ...(省略)"}
]
}'
# => {"id":"c_xxx","member_id":"m_child_001","subject":"数学",
# "content":"...","attachments":[...],"wrong_questions":[...],"created_at":...}
# 也可以只传图片 URL(不传 attachments,改用 url 字段):
# -d '{"member":"m_child_001","url":"https://example.com/homework.jpg"}'
大模型返回的内容要能解析成 JSON(含 subject/content/wrong_questions 等字段),解析失败会返回具体错误。遇到模型繁忙(如 1305 访问量过大/429/503)会按设置里的重试次数自动重试,全失败则返回最后一条错误。
注册智谱
并创建API_KEY。
通过我的专属邀请链接注册即可获得额外GLM-4-Air 2000万Tokens好友专属福利,期待和你一起在BigModel上探索AGI时代的应用;链接:
注册连接
注册过程就不多说了。注册成功后,登录就行了。
1、登录智谱

2、控制台

3、创建KEY

点击 添加新的API Key

填写 API key 名称,确定后创建

创建成功后会在列表中展示出来,点击 复制
附加(非必要,但建议)
实名认证,赠送免费资源包。

进入个人中心,点击 认证

个人实名认证

填写实名信息
支付宝扫码,进行人脸认证。
认证完成后,点击 已完成刷脸认证

点击 查看资源包

还有免费模型

免费模型唯一不足的地方就是容易提示访问量过大,服务中加了重试机制可以重试。
有条件的话可以买一些更好的模型,效果会更好一些。这里就先使用免费的。
目前服务端只支持智普模型,其他模型没有做适配。
增加了小智MCP功能
源码地址
https://gitee.com/lazy-ai/go-mcp-task.git
go-mcp-task(MCP 任务服务 / Sidecar)
一个用 Go 写的 MCP(Model Context Protocol)服务,作为 kids-task-manager 的伴随进程(sidecar)运行。它把 kids-task-manager 的本地能力——摄像头抓拍、作业识别、成员/检查记录查询、计算器——包装成 MCP 工具,既能通过 stdio 被本地 MCP 客户端调用,也能通过 WebSocket 连上小智(云端 MCP 接入点),让云端 AI 直接调用这些工具。
本项目是 kids-task-manager 的「MCP 桥」:kids-task-manager 负责数据、Web UI、RTSP 摄像头、大模型识别;go-mcp-task 只负责把这些能力暴露给 MCP 客户端 / 云端 AI。两个仓库互相独立,部署时二进制放在同一目录即可。
它是怎么工作的
- 作为 kids-task-manager 的子进程自动拉起(系统配置里「自动启动任务服务」默认开启),运行同目录下的
go-mcp-task_<goos>_<goarch>[.exe]。
- 启动时从命令行参数(或环境变量)读取 kids-task-manager 的基址、登录密码 / 会话令牌。
- 两条通信链路并存:
- stdio:本地 MCP 客户端按行读写 JSON-RPC 2.0(
initialize / tools/list / tools/call / ping)。
- WebSocket(可选):配置了
-mcp-endpoint(小智接入点 wss://...?token=...)后,作为 WebSocket client 连上该接入点,在连接内充当 MCP server,云端 AI 即可调用本地工具;连接断开后自动指数退避重连。
暴露的工具
| 工具 |
说明 |
calculator |
安全数学求值,支持 sin/cos/sqrt/log/pow/abs/floor/ceil/round/factorial 等函数与 pi/e/tau/phi 常量,以及 rand() 系列。 |
get_config |
回显运行期配置(含 -mcp-endpoint 注入的接入点地址与 base_url)。验证「改了接入点是否生效」时调用(改 endpoint 会触发 sidecar 重启)。 |
list_cameras |
列出 kids-task-manager 已配置的摄像头,返回 [{id,name,url,enabled,...}]。capture_frame / check_homework 需要先拿 device_id。 |
list_members |
列出家庭成员,check_homework 需要其中的 member_id。 |
capture_frame |
调用「摄像头识别 → 获取视频帧」接口抓一帧,返回 base64 图片与元数据。参数 device_id。 |
check_homework |
抓帧 + 大模型作业识别,返回识别结果(科目 / 内容 / 错题等)。参数 device_id + member_id,可选 subject(覆盖模型推断的科目)。 |
list_checks |
列出最近作业检查记录(科目 / 内容 / 错题 / 时间等)。 |
工具级业务错误(success=false)会映射为 MCP 的 isError=true;工具内部 panic 会被兜底为错误响应,不会拖垮整个 stdio 服务。
命令行参数
| 参数 |
说明 |
默认 |
-base-url |
kids-task-manager 基址,如 http://127.0.0.1:8080 |
http://127.0.0.1:8080 |
-password |
登录密码(也可设环境变量 KTM_PASSWORD);未配置则尝试匿名,但受保护接口需鉴权 |
空 |
-token |
会话令牌,直接指定可跳过登录(也可设 KTM_TOKEN) |
空 |
-timeout |
HTTP 请求总超时,含摄像头抓拍 + 大模型作业识别耗时,建议 ≥60s |
120s |
-mcp-endpoint |
小智 MCP 接入点地址(wss://api.xiaozhi.me/mcp/?token=...);配置后作为 WebSocket client 连上云端,本地工具即被云端 AI 调用 |
空 |
-status-addr |
本地状态端点监听地址(如 127.0.0.1:8123);非空时暴露 GET /status,供 kids-task-manager 代理展示。为空则不启动 |
空 |
所有参数都有对应的环境变量(KTM_ 前缀),命令行参数优先于环境变量默认值。
环境变量
| 变量 |
对应参数 |
KTM_BASE_URL |
-base-url |
KTM_PASSWORD |
-password |
KTM_TOKEN |
-token |
KTM_MCP_ENDPOINT |
-mcp-endpoint |
KTM_STATUS_ADDR |
-status-addr |
身份鉴权
- 未传
-token 且有 -password 时,首次访问受保护接口会自动 POST /api/login 换取令牌并缓存于进程内存。
- 缓存的令牌随进程重启失效;kids-task-manager 重启 sidecar 时会用最新配置重新拉起。
本地状态端点(调试用)
配置了 -status-addr(kids-task-manager 默认注入 127.0.0.1:8123)时暴露:
GET /status:JSON 状态快照,包含
cloud:小智连接状态(configured / connected / state / endpoint / last_error);
log:接收输入日志(in 请求 / out 响应,stdio 或 cloud 来源);
responses:写回的响应(排查「工具到底返回了什么 / 为何报错」);
calls:🔧 工具内部调用日志(check_homework / capture_frame 对 kids-task-manager 的 HTTP 请求、SSE 事件、耗时、报错)。这是定位 check_homework 卡死/超时的关键——MCP 响应只有在工具函数返回后才记录,而内部调用日志能在「请求发出 → 收到 HTTP 状态 → 收到各 SSE 事件 → 完成/报错」各阶段即时留痕,即便最终响应因连接断开丢失,也能看出卡在哪一步。
GET /healthz:简易存活探针。
kids-task-manager 的「📜 通信日志」面板会代理展示上述数据,并单独呈现「🔧 工具内部调用」区块。
连接保护(防重连风暴)
- 云端 MCP 连接:每收到一帧 JSON-RPC 消息都在独立 goroutine 中处理并写回(写锁保护并发响应帧),读循环始终空闲、
ping 即时被应答。避免 check_homework 这类耗时数十秒的长任务阻塞读循环、导致云端心跳超时而反复重连(表现为日志里反复出现 initialize #0)。
- 断线重连:指数退避(1s → 封顶 600s),接入点地址已自带 token,无需额外 header;连接失败会记录次数与错误并自动重试。
构建
纯 Go + gorilla/websocket,无 CGO 依赖,交叉编译开箱即用:
# 构建当前平台
go build -o go-mcp-task .
# 交叉编译(示例:树莓派 / 高通 Snapdragon 410 = linux/arm64)
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o go-mcp-task_linux_arm64 .
# Windows
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o go-mcp-task_windows_amd64.exe .
通常由 kids-task-manager 的 build.sh 一并把本项目构建到其 dist/(命名规则 go-mcp-task_<goos>_<goarch>[.exe]),与 kids-task-manager 二进制同目录打包。
日志约定
- 所有诊断日志写 stderr,绝不污染 stdout 的 JSON-RPC 流,保证本地 MCP 客户端能可靠按行解析。
目录结构
go-mcp-task/
├── go.mod # 模块定义(依赖 gorilla/websocket)
├── main.go # 入口:解析参数、启动 cloud/status、stdio 读写循环
├── server.go # MCP stdio 服务端(JSON-RPC 分发、工具清单与调度)
├── ktm.go # ktmClient:调用 kids-task-manager REST API(鉴权 / SSE 解析 / 各工具实现 / 内部调用日志)
├── cloud.go # 小智 WebSocket 连接 + 自动重连 + 每消息并发处理
├── status.go # 本地状态端点(/status / /healthz)+ 连接状态与日志环形缓冲
├── eval.go # calculator 安全求值实现
├── *_test.go # 单元测试
└── dist/ # (可选)本地构建产物
与 kids-task-manager 的对接
- kids-task-manager 在「🧮 MCP 任务服务」设置里保存
autostart 与 endpoint;开启自动启动且未运行则立即拉起 go-mcp-task,关闭则停止;改 endpoint 会触发 sidecar 重启使之生效。
- 部署时把
kids-task-manager 与 go-mcp-task 两个二进制放到同一目录,前者即可自动发现并管理后者。详见 kids-task-manager/README.md。
附件
附件:外壳文件.zip
附件:AiPi-WV01-32s.zip