senseaudio-elderly-voice-assistant

银发族语音助手——老年人对着手机说话就能发消息、查天气、设闹钟、听戏曲,无需学任何操作。

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "senseaudio-elderly-voice-assistant" with this command: npx skills add scikkk/elderly-assistant

银发族语音助手 / Elderly Voice Assistant

老年人对着手机说话就能完成发消息、查天气、设闹钟、听新闻、听戏曲,不用学任何操作。

设计理念

  • 零门槛:界面只有一个超大麦克风按钮,没有文字菜单,所有功能语音触发
  • 口语容错:老年人说话啰嗦、重复、方言混杂、停顿长,LLM 做强容错意图理解
  • 语音反馈:所有执行结果用清晰、慢速、大音量的 TTS 播报,不依赖屏幕
  • 主动关怀:定时提醒吃药喝水、每天播报天气穿着、无交互时通知子女
  • 内容陪伴:根据偏好播放戏曲评书老歌,也可与 AI 聊天解闷

工作流程

[按住大按钮说话] → ASR识别(容错) → LLM意图理解 → 执行动作 → TTS语音播报结果

核心 API

语音识别(ASR)

curl https://api.senseaudio.cn/v1/audio/transcriptions \
  -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
  -F file="@recording.wav" \
  -F model="sense-asr" \
  -F language="zh" \
  -F response_format="text"
# 返回:那个就是跟我那个大儿子说一下明天那个不用来了

语音合成(TTS)— 适老化参数

curl -X POST https://api.senseaudio.cn/v1/t2a_v2 \
  -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "SenseAudio-TTS-1.0",
    "text": "好的,已经帮您给大儿子发了消息,内容是:明天不用来了。",
    "stream": false,
    "voice_setting": {
      "voice_id": "female_0001_a",
      "speed": 0.8,
      "vol": 3.0,
      "pitch": 0
    },
    "audio_setting": {
      "format": "mp3",
      "sample_rate": 32000
    }
  }'

适老化 TTS 参数说明:

参数推荐值说明
speed0.8慢速播报,老人听得清
vol3.0大音量,适合听力下降
voice_idfemale_0001_a温暖女声,亲切感强

口语容错与意图理解

ASR 转写后,LLM 对老年人口语做强容错意图提取。

容错示例

老人原话(ASR 转写)LLM 提取意图执行动作
那个……就是……跟我那个大儿子说一下……明天那个不用来了send_message(to="大儿子", content="明天不用来了")发消息
今天外头冷不冷啊,要不要穿厚点get_weather(query="今天气温")查天气
帮我定个……就是下午三点……三点钟吃药的那个闹钟set_alarm(time="15:00", label="吃药")设闹钟
给我放段那个……黄梅戏……就是天仙配play_content(type="戏曲", query="黄梅戏天仙配")播放内容
没意思,给我放点东西听听play_content(type="推荐", based_on="历史偏好")智能推荐
跟我聊聊天吧,一个人怪无聊的chat(mode="陪伴")AI 聊天

LLM 意图提取 Prompt

INTENT_SYSTEM_PROMPT = """你是一个专为老年人设计的语音助手的意图理解模块。
老年人说话有以下特点,你需要容错处理:
1. 大量口头禅和填充词:那个、就是、嗯、啊、这个
2. 重复表达:同一个意思说两三遍
3. 方言混杂:可能夹杂方言词汇
4. 长停顿:句子中间可能有很长的停顿导致断句不完整
5. 间接表达:不会直接说功能名,而是描述需求

请从用户的话中提取意图,返回 JSON:
{
  "intent": "send_message|get_weather|set_alarm|play_content|chat|unknown",
  "params": { ... },
  "confidence": 0.0-1.0
}

如果置信度低于 0.6,intent 设为 "confirm",并生成一句确认话术。
确认话术要亲切、简短、用老人听得懂的话,比如:
"您是想让我帮您给大儿子发消息吗?"
"""

支持的功能

1. 发消息

def handle_send_message(params: dict) -> str:
    """发消息给联系人"""
    to = params["to"]       # 联系人称呼:大儿子、老伴、小孙女
    content = params["content"]
    # 查找联系人映射 → 发送消息
    # ...
    return f"好的,已经帮您给{to}发了消息,内容是:{content}。要不要我再加点什么?"

2. 查天气

import requests

def handle_get_weather(params: dict) -> str:
    """查天气并生成适老播报"""
    city = params.get("city", "默认城市")
    weather = requests.get(f"https://wttr.in/{city}?format=%c+%t+%h&lang=zh", timeout=10).text.strip()
    # 生成适老播报:加穿衣建议
    return f"今天{city}的天气是{weather}。建议您今天出门多穿一件外套,注意保暖。"

3. 设闹钟

def handle_set_alarm(params: dict) -> str:
    """设置提醒闹钟"""
    time_str = params["time"]   # "15:00"
    label = params["label"]     # "吃药"
    # 调用系统闹钟 API
    # ...
    return f"好的,已经帮您设好了下午{time_str}的闹钟,到时候提醒您{label}。"

4. 播放内容

CONTENT_CATEGORIES = {
    "戏曲": ["黄梅戏", "京剧", "越剧", "豫剧", "评剧"],
    "评书": ["三国演义", "水浒传", "岳飞传", "隋唐演义"],
    "老歌": ["邓丽君", "刘德华", "费玉清", "蔡琴"],
    "养生": ["养生堂", "健康之路", "中医养生"],
    "新闻": ["今日新闻", "国内要闻", "本地新闻"],
}

def handle_play_content(params: dict) -> str:
    content_type = params.get("type", "推荐")
    query = params.get("query", "")
    if content_type == "推荐":
        # 根据历史偏好推荐
        pass
    return f"好的,这就给您放{query},您听着,想换就跟我说。"

5. AI 陪伴聊天

CHAT_SYSTEM_PROMPT = """你是一位耐心、亲切的语音助手,正在陪一位老人聊天。
说话风格要求:
- 语速慢,句子短,每句不超过20个字
- 用"您"称呼,语气温暖像晚辈
- 多倾听,适当回应,不要长篇大论
- 聊家常话题:天气、吃饭、身体、往事
- 如果老人情绪低落,温柔安慰,必要时建议联系家人
"""

完整 Python 实现

import os
import json
import requests
import tempfile
import subprocess
from datetime import datetime

API_KEY = os.environ["SENSEAUDIO_API_KEY"]
ASR_URL = "https://api.senseaudio.cn/v1/audio/transcriptions"
TTS_URL = "https://api.senseaudio.cn/v1/t2a_v2"

# 适老化 TTS 参数
ELDERLY_TTS_PARAMS = {
    "model": "SenseAudio-TTS-1.0",
    "stream": False,
    "voice_setting": {
        "voice_id": "female_0001_a",
        "speed": 0.8,   # 慢速
        "vol": 3.0,     # 大音量
        "pitch": 0,
    },
    "audio_setting": {"format": "mp3", "sample_rate": 32000},
}


def asr_recognize(audio_path: str) -> str:
    """语音识别,返回转写文本"""
    with open(audio_path, "rb") as f:
        resp = requests.post(
            ASR_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"file": f},
            data={"model": "sense-asr", "language": "zh", "response_format": "text"},
            timeout=20,
        )
    resp.raise_for_status()
    return resp.text.strip()


def tts_speak(text: str) -> None:
    """TTS 合成并播放,适老化参数"""
    payload = {**ELDERLY_TTS_PARAMS, "text": text}
    resp = requests.post(
        TTS_URL,
        headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
        json=payload,
        timeout=20,
    )
    resp.raise_for_status()
    audio_bytes = bytes.fromhex(resp.json()["data"]["audio"])
    with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f:
        f.write(audio_bytes)
        tmp = f.name
    for cmd in [["afplay", tmp], ["play", tmp], ["mpg123", tmp]]:
        try:
            subprocess.run(cmd, check=True, capture_output=True)
            return
        except (FileNotFoundError, subprocess.CalledProcessError):
            continue


def extract_intent(text: str, llm_call) -> dict:
    """LLM 意图提取,容错老年人口语"""
    result = llm_call(
        system=INTENT_SYSTEM_PROMPT,
        user=text,
    )
    try:
        return json.loads(result)
    except json.JSONDecodeError:
        return {"intent": "unknown", "params": {}, "confidence": 0.0}


def handle_intent(intent_result: dict) -> str:
    """根据意图执行动作,返回播报文本"""
    intent = intent_result.get("intent")
    params = intent_result.get("params", {})
    confidence = intent_result.get("confidence", 1.0)

    if confidence < 0.6 or intent == "confirm":
        return intent_result.get("confirm_text", "您刚才说的是什么意思,能再说一遍吗?")

    if intent == "send_message":
        to = params.get("to", "家人")
        content = params.get("content", "")
        # TODO: 调用消息发送接口
        return f"好的,已经帮您给{to}发了消息,内容是:{content}。"

    elif intent == "get_weather":
        city = params.get("city", "")
        weather = requests.get(
            f"https://wttr.in/{city or ''}?format=%c+%t+%h&lang=zh", timeout=10
        ).text.strip()
        return f"今天的天气是{weather}。出门记得看看冷不冷,注意保暖。"

    elif intent == "set_alarm":
        time_str = params.get("time", "")
        label = params.get("label", "提醒")
        # TODO: 调用系统闹钟接口
        return f"好的,已经帮您设好了{time_str}的闹钟,到时候提醒您{label}。"

    elif intent == "play_content":
        query = params.get("query", "")
        content_type = params.get("type", "内容")
        # TODO: 调用内容播放接口
        return f"好的,这就给您放{query or content_type},您听着,想换就跟我说。"

    elif intent == "chat":
        # 返回空字符串,由上层进入聊天模式
        return ""

    else:
        return "对不起,我没听清楚您说的。能再说一遍吗?说慢一点也没关系。"


class ElderlyVoiceAssistant:
    def __init__(self, llm_call):
        self.llm_call = llm_call
        self.last_active = datetime.now()
        self.preferences = {}  # 历史偏好

    def process_voice(self, audio_path: str) -> None:
        """主流程:录音 → 识别 → 意图 → 执行 → 播报"""
        self.last_active = datetime.now()

        # 1. ASR
        text = asr_recognize(audio_path)
        print(f"[识别] {text}")

        # 2. 意图理解
        intent_result = extract_intent(text, self.llm_call)
        print(f"[意图] {intent_result}")

        # 3. 执行 + 播报
        if intent_result.get("intent") == "chat":
            reply = self.llm_call(system=CHAT_SYSTEM_PROMPT, user=text)
            tts_speak(reply)
        else:
            response_text = handle_intent(intent_result)
            if response_text:
                tts_speak(response_text)

主动关怀系统

import threading
import time as time_module

class ProactiveCareScheduler:
    """主动关怀调度器"""

    def __init__(self, assistant: ElderlyVoiceAssistant, notify_family_callback):
        self.assistant = assistant
        self.notify_family = notify_family_callback
        self.reminders = []  # [(hour, minute, text), ...]

    def add_medication_reminder(self, hour: int, minute: int, medicine: str):
        self.reminders.append((hour, minute, f"该吃{medicine}了,记得喝水。"))

    def morning_briefing(self):
        """每天早上主动播报天气和穿着建议"""
        weather = requests.get("https://wttr.in/?format=%c+%t&lang=zh", timeout=10).text.strip()
        tts_speak(f"早上好!今天天气{weather}。记得吃早饭,注意身体。")

    def check_inactivity(self):
        """超过24小时无交互,通知子女"""
        delta = datetime.now() - self.assistant.last_active
        if delta.total_seconds() > 86400:
            self.notify_family("老人今天还没有使用语音助手,请关注一下。")

    def run(self):
        """后台运行调度循环"""
        def loop():
            while True:
                now = datetime.now()
                # 早上8点播报天气
                if now.hour == 8 and now.minute == 0:
                    self.morning_briefing()
                # 检查自定义提醒
                for h, m, text in self.reminders:
                    if now.hour == h and now.minute == m:
                        tts_speak(text)
                # 检查无交互
                self.check_inactivity()
                time_module.sleep(60)

        threading.Thread(target=loop, daemon=True).start()

错误处理与容错

def safe_process_voice(assistant: ElderlyVoiceAssistant, audio_path: str):
    """带容错的语音处理"""
    try:
        assistant.process_voice(audio_path)
    except requests.exceptions.Timeout:
        tts_speak("网络有点慢,请稍等一下再试。")
    except requests.exceptions.ConnectionError:
        tts_speak("网络好像断了,请检查一下网络连接。")
    except Exception:
        tts_speak("出了点小问题,请再说一遍,或者让家人帮您看看。")

相关资源

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Leads

Leads - command-line tool for everyday use

Registry SourceRecently Updated
General

Bmi Calculator

BMI计算器。BMI计算、理想体重、健康计划、体重追踪、儿童BMI、结果解读。BMI calculator with ideal weight, health plan. BMI、体重、健康。

Registry SourceRecently Updated
General

Blood

Blood — a fast health & wellness tool. Log anything, find it later, export when needed.

Registry SourceRecently Updated
General

Better Genshin Impact

📦BetterGI · 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄地 | 一条龙 | 全连音游 - UI A better genshin impact, c#, auto-play-game, automatic, g...

Registry SourceRecently Updated