侧边栏壁纸
博主头像
龍騰博客 博主等级

行动起来,活在当下

  • 累计撰写 157 篇文章
  • 累计创建 31 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

手把手搭建:本地AI家庭知识库语音助手

管理员
2026-06-21 / 0 评论 / 0 点赞 / 1 阅读 / 0 字

这套系统能做什么

对着小爱音箱说话,就能:

  • 问问题:"家庭百科 投影仪遥控器在哪" → 语音回答你存好的信息

  • 记事情:"记一下 下周三阿姨要来打扫卫生" → 自动记下来,几秒后就能被查到

全程不联网、不上传隐私数据,所有处理都在自己家里的设备上完成。

准备工作

开始之前,确认你已经有这些东西(如果还没有,需要先搭建好再继续本教程):

  • 一台能跑Docker的设备,比如NAS或迷你主机(教程里以IP 192.168.0.188 为例,记得换成你自己的)

  • 已经安装好 Ollama(本地大模型)

  • 已经安装好 Open WebUI(管理大模型对话的网页界面)

  • 已经安装好 Home Assistant(智能家居中枢,简称HA)

  • 一个能被HA控制的智能音箱(比如小爱音箱,已经接入HA)

如果以上任何一项还没有,建议先完成这些基础安装,再回来跟着本教程操作。


第一部分:让HA能用语音对话

如果你的HA已经能正常进行语音对话(比如已经可以说"打开客厅灯"),可以跳过这部分,直接看第二部分。

1.1 安装语音转文字模块(Whisper)

打开HA网页界面,左侧菜单点 设置 → 加载项 → 加载项商店

在商店里搜索 "Whisper",会出现一个官方应用,图标是OpenAI的标志,描述是"Speech-to-text with Whisper"。点进去,点 安装

安装完成后,点 配置 标签页,填入以下内容:

language: zh
model: small-int8
beam_size: 1

保存后回到信息页面,点 启动

1.2 安装文字转语音模块(Piper)

同样在加载项商店搜索 "Piper",安装。默认配置即可使用,启动它。

1.3 创建语音助手

设置 → 语音助手,点 添加助手(或者编辑已有的)。

按下面的方式配置:

  • 名称:随便取,比如"小爱"

  • 语言:中文

  • 对话代理:Home Assistant(中文-中国)

  • 语音转文字:选刚才装的 faster-whisper,语言选中文

  • 文字转语音:选刚才装的 piper,语言选 zh_CN

保存。

1.4 测试基础语音功能

打开手机上的Home Assistant App,点底部的麦克风图标(或者在网页上找到Assist对话框),说一句"打开客厅灯"(换成你家里真实存在的设备)。如果灯亮了或者有正确反馈,说明基础语音链路已经打通,可以继续下一部分。


第二部分:搭建家庭知识库

2.1 下载一个"语义理解"模型

打开你NAS或主机的终端(SSH连接进去),输入:

docker exec -it ollama ollama pull bge-m3

等待下载完成(这个模型不大,几分钟就能下完)。它的作用是让系统"听懂"你提问的意思,去匹配最相关的内容。

2.2 在Open WebUI里启用它

打开Open WebUI网页,点左下角头像 → 管理员面板 → 顶部 设置 → 左侧 文档

把这几项改成:

  • 嵌入模型引擎:Ollama

  • API地址http://192.168.0.188:11434(换成你自己机器的IP)

  • 嵌入模型bge-m3

  • 混合搜索:打开

拉到最下面点 保存

2.3 创建知识库

回到Open WebUI主界面(不是管理员面板),左侧菜单点 工作空间 → 知识库 → +创建知识库

填写:

  • 名称:家庭知识库

  • 描述:随便写,比如"家里的各种信息"

创建后会进入这个知识库的详情页,看浏览器地址栏,最后那一长串字母数字组合,例如:

96eda586-8274-4715-a82a-45138235e307

把这串内容复制保存下来,后面会反复用到,这是这个知识库的专属编号。

2.4 准备一份"家庭备忘录"文件

新建一个文本文件,命名为 家庭备忘录.txt,写入一些示例内容:

2026-06-15: 投影仪遥控器放在电视柜下方第二层抽屉
2026-06-10: 客厅空调滤网建议每3个月清洗一次
2026-06-01: 装修师傅联系方式:张工 138xxxxxxxx

回到知识库详情页,点 上传文件,把这个txt文件传上去。等待右边状态显示"已处理"。

2.5 测试知识库

回到Open WebUI主聊天界面,左上角选一个对话模型(比如 deepseek-r1:14b,如果没有这个模型,先用 docker exec -it ollama ollama pull deepseek-r1:14b 下载)。

在输入框打 # 号,会弹出知识库列表,选择"家庭知识库",然后输入问题:

#家庭知识库 投影仪遥控器放在哪?

如果回答正确引用了你刚才写的内容,说明知识库搭建成功。


第三部分:让HA能查询知识库

3.1 生成一把"钥匙"(API Key)

回到Open WebUI,点头像 → 设置 → 账户,往下滑找到 API Keys,点生成一个新的。

把生成的这串字符复制保存好,类似 sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,后面要用。

3.2 在HA里添加配置

打开HA的File editor加载项(如果没装,去加载项商店搜索 "File editor" 装一个),打开 configuration.yaml 文件,在文件末尾加入:

rest_command:
  ask_home_knowledge:
    url: "http://192.168.0.188:8081/api/chat/completions"
    method: POST
    headers:
      Authorization: "Bearer 把你的API_Key粘贴在这里"
      Content-Type: "application/json"
    payload: >
      {"model": "deepseek-r1:14b", "messages": [{"role": "user", "content": "{{ question }}"}], "files": [{"type": "collection", "id": "把你的知识库编号粘贴在这里"}]}
    timeout: 120

intent_script:
  AskHomeKnowledge:
    action:
      - service: rest_command.ask_home_knowledge
        data:
          question: "{{ query }}"
        response_variable: kb_result
      - stop: ""
        response_variable: kb_result
    speech:
      text: "{{ action_response.content.choices[0].message.content }}"

记得把里面两处提示替换成你自己的:

  • 把你的API_Key粘贴在这里 → 替换成 3.1 生成的那串Key

  • 把你的知识库编号粘贴在这里 → 替换成 2.3 复制的那串编号

保存文件。

3.3 添加语音触发词

在File editor里,找到HA配置文件夹(一般地址栏显示/homeassistant/),新建一个文件夹路径:

custom_sentences/zh-CN/

注意文件夹名字必须精确是 zh-CN(大写CN,中间一个短横线),不能写成别的。

在这个文件夹里新建文件 home_knowledge.yaml,内容是:

language: "zh"
intents:
  AskHomeKnowledge:
    data:
      - sentences:
          - "家庭百科 {query}"
          - "查询家庭知识 {query}"
          - "帮我查 {query}"
lists:
  query:
    wildcard: true

保存。

3.4 重启HA

设置 → 系统 → 重启 → 选择"重新启动Home Assistant",等待重启完成。

3.5 测试语音查询

对着小爱(或者你配置的语音助手名字)说:

家庭百科 投影仪遥控器在哪

应该能听到语音回答"投影仪遥控器放在电视柜下方第二层抽屉"。

如果没反应,去 开发者工具 → Assist → 语句解析器,把这句话粘进去测试,看是否能正确解析。


第四部分:让HA能记录新内容到知识库

4.1 准备备忘录文件存放位置

在File editor里,HA根目录下新建文件夹 data,在里面放刚才那份 家庭备忘录.txt(如果之前是在别处编辑的,现在统一移到这里:/homeassistant/data/家庭备忘录.txt)。

4.2 创建一个写入脚本

继续在File editor里,HA根目录下新建文件夹 scripts,在里面新建文件 append_note.sh,内容是:

#!/bin/bash
FILE="/config/data/家庭备忘录.txt"

RAW="$*"
CLEAN=$(echo "$RAW" | sed -E 's/^[[:space:],,。.!!??、]+//')

if [ -s "$FILE" ] && [ "$(tail -c 1 "$FILE")" != "" ]; then
  echo "" >> "$FILE"
fi
echo "$(date '+%Y-%m-%d'): $CLEAN" >> "$FILE"

保存。

4.3 在configuration.yaml里加调用配置

打开 configuration.yaml,在 rest_command: 这一块下面(和ask_home_knowledge同一缩进层级)加入新的一项:

shell_command:
  append_home_note: "bash /config/scripts/append_note.sh {{ note }}"

然后在 intent_script: 这一块下面(和AskHomeKnowledge同一缩进层级),加入:

  RecordHomeNote:
    action:
      - service: shell_command.append_home_note
        data:
          note: "{{ note }}"
    speech:
      text: "已经记下了"

保存。这一步之后,你的configuration.yaml整体结构大致应该是这样(仅展示新增部分的层级关系):

shell_command:
  append_home_note: "..."

rest_command:
  ask_home_knowledge:
    ...

intent_script:
  AskHomeKnowledge:
    ...
  RecordHomeNote:
    ...

4.4 添加"记录"语音触发词

custom_sentences/zh-CN/ 文件夹里(和home_knowledge.yaml同一个文件夹),新建文件 record_note.yaml

language: "zh"
intents:
  RecordHomeNote:
    data:
      - sentences:
          - "记一下 {note}"
          - "帮我记 {note}"
          - "记录一下 {note}"
          - "記一下 {note}"
          - "幫我記 {note}"
          - "記錄一下 {note}"
lists:
  note:
    wildcard: true

保存。

4.5 重启HA并测试

设置 → 系统 → 重启。

重启后对小爱说:

记一下 测试一下能不能记录成功

应该会听到"已经记下了"的回复。

去File editor打开 /homeassistant/data/家庭备忘录.txt,确认新的一行内容已经出现在文件末尾。


第五部分:让记录自动同步进知识库

做到这一步,新记录的内容已经写进txt文件了,但知识库里还是旧版本,需要手动同步一次才能被查到。这一部分让这个同步过程完全自动化。

5.1 给Ollama所在的设备装一个同步工具

SSH连接到运行Ollama和Open WebUI的那台设备(本教程里是 192.168.0.188),创建一个独立的Python环境来安装这个工具,这样以后想卸载也很干净:

python3 -m venv /root/oikb-env
source /root/oikb-env/bin/activate
pip install oikb

安装完成后测试:

oikb --version

能看到版本号说明安装成功。

5.2 让这台设备能访问到HA的文件

因为HA和Open WebUI可能跑在不同的设备上,需要先把HA那边的文件夹"借"过来用。

先在HA这边开启文件共享:去加载项商店搜索 "Samba share",安装并启动,设置一个访问账号和密码(记下来,下一步要用)。

再回到Open WebUI所在设备,把HA的文件夹挂载进来:

mkdir -p /mnt/haos-config
apt-get update
apt-get install -y cifs-utils
mount -t cifs //192.168.0.9/config /mnt/haos-config -o username=你的Samba账号,password=你的Samba密码,vers=3.0

192.168.0.9 换成你HA实际的IP地址,账号密码换成上一步设置的。

验证是否成功:

ls /mnt/haos-config/data

如果能看到 家庭备忘录.txt,说明成功了。

让这个挂载在重启后还能自动生效,运行:

echo "//192.168.0.9/config /mnt/haos-config cifs username=你的Samba账号,password=你的Samba密码,vers=3.0,_netdev 0 0" >> /etc/fstab

5.3 测试同步工具

确保你还在刚才那个Python环境里(命令行前面应该显示(oikb-env)),设置好连接信息:

export OPEN_WEBUI_URL=http://192.168.0.188:8081
export OPEN_WEBUI_API_KEY=把你的API_Key粘贴在这里

先预览一下会同步什么(不会真的上传):

oikb sync /mnt/haos-config/data --kb-id 把你的知识库编号粘贴在这里 --dry-run

确认没问题后,正式同步一次:

oikb sync /mnt/haos-config/data --kb-id 把你的知识库编号粘贴在这里

去Open WebUI网页确认知识库里的家庭备忘录.txt内容已经更新成最新版本。

5.4 写一个小服务,让HA能"喊"它同步

创建这个文件:

cat > /root/sync_trigger_server.py << 'PYEOF'
from fastapi import FastAPI
from fastapi.responses import JSONResponse
import subprocess
import uvicorn

app = FastAPI()

OIKB_BIN = "/root/oikb-env/bin/oikb"
SYNC_DIR = "/mnt/haos-config/data"
KB_ID = "把你的知识库编号粘贴在这里"
OPEN_WEBUI_URL = "http://192.168.0.188:8081"
OPEN_WEBUI_API_KEY = "把你的API_Key粘贴在这里"

@app.post("/trigger-sync")
def trigger_sync():
    env = {
        "OPEN_WEBUI_URL": OPEN_WEBUI_URL,
        "OPEN_WEBUI_API_KEY": OPEN_WEBUI_API_KEY,
        "PATH": "/usr/bin:/bin",
    }
    result = subprocess.run(
        [OIKB_BIN, "sync", SYNC_DIR, "--kb-id", KB_ID],
        capture_output=True, text=True, timeout=60, env=env,
    )
    return JSONResponse({
        "success": result.returncode == 0,
        "stdout": result.stdout,
        "stderr": result.stderr,
    })

@app.get("/health")
def health():
    return {"status": "ok"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=9100)
PYEOF

记得把里面的知识库编号和API Key替换成你自己的。

5.5 让这个服务一直在后台运行,开机自启

cat > /etc/systemd/system/oikb-sync-server.service << 'EOF'
[Unit]
Description=oikb sync trigger server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
ExecStart=/root/oikb-env/bin/python3 /root/sync_trigger_server.py
Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/oikb-sync-server.log
StandardError=append:/var/log/oikb-sync-server.log

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable oikb-sync-server
systemctl start oikb-sync-server

检查是否正常运行:

systemctl status oikb-sync-server

看到 active (running) 这样的绿色状态就说明成功了。

本地测试一下这个服务能不能正常触发同步:

curl -X POST http://localhost:9100/trigger-sync

应该会返回一段包含 "success":true 的文字。

5.6 让HA每次记录后自动通知这个服务

回到HA,打开 configuration.yaml,在 rest_command: 这一块下面,ask_home_knowledge旁边,加入新的一项:

  trigger_kb_sync:
    url: "http://192.168.0.188:9100/trigger-sync"
    method: POST
    timeout: 60

然后修改 intent_script: 里的 RecordHomeNote,把它改成这样:

  RecordHomeNote:
    action:
      - service: shell_command.append_home_note
        data:
          note: "{{ note }}"
      - service: rest_command.trigger_kb_sync
    speech:
      text: "已经记下了,知识库也同步更新了"

保存,重启HA。


第六部分:完整测试

重启完成后,进行最终的端到端测试:

测试1:语音记录

对小爱说:

记一下 下周六我们去看荷花

应该听到"已经记下了,知识库也同步更新了"。

测试2:语音查询刚记录的内容

等几秒钟,对小爱说:

家庭百科 下周六要做什么

应该能听到正确的回答"下周六我们去看荷花"。

测试3:确认知识库没有重复堆积

去Open WebUI网页,进"家庭知识库",确认 家庭备忘录.txt 始终只有一份,不会越记越多。

如果三个测试都通过,恭喜你,整套语音问答+语音记录+自动同步的家庭知识库系统已经搭建完成!以后只要对着音箱说话,就能随时记录和查询家里的各种信息。


日常使用小贴士

  • 想记什么就直接说"记一下 + 内容",不需要想太多句式,系统会自动整理保存

  • 想查什么就说"家庭百科 + 你想问的内容"

  • 如果一段时间不用,担心服务掉线,可以SSH登录设备执行 systemctl status oikb-sync-server 检查同步服务是否还在正常运行

  • 知识库文件除了用语音记录,也可以随时去 Open WebUI 网页里手动上传新的文档(比如新买的电器说明书),同样能被语音查询到

0

评论区