在树莓派上搭建家用 Agent 服务

使用树莓派搭建 dive-into-langgraph/app 服务,在家庭局域网内部使用。

一键部署脚本:agent-server

一、制作 TF 卡

Note: 你可以参考我的这篇博客《树莓派 5 装机指南》,它写得更详细一些。但部分信息已经过时,请注意甄别。

1)下载

你需要下载两样东西:

Ubuntu 镜像有两种版本:桌面版、服务器版,我们下载服务器版。下载的时候可以检查一下,安装包的文件名应该是这个 ubuntu-24.04.3-preinstalled-server-arm64+raspi.img.xz

2)将镜像写入 TF 卡

根据 Raspberry Pi Imager 的指引,完成镜像烧录的过程就好了。并没有什么难的。唯一需要注意的是,由于我们已经下载了 Ubuntu 镜像,所以这里要选「使用自定义镜像」。

二、首次启动 Ubuntu

烧录完成后,按以下步骤操作:

  1. 先断电,然后将 TF 卡插入板子
  2. 连接外接显示屏、键盘、网线
  3. 最后插入电源

一般来讲,插电即可点亮。这时回车一下,即可输入账号密码,初始账密是:

账号 ubuntu
密码 ubuntu

输完账密,它会接着让你设置新密码。这里流程设计得有点人机,需要注意看提示,不然容易卡关。温馨提示:你输入 ubuntu 的次数比你想象中更多。

三、环境配置

1)更新软件包

# 更新软件源的索引列表
sudo apt update

# 根据更新后的索引,升级所有可更新的软件包
sudo apt upgrade -y

2)安装 pipx 和 uv

先安装 pipx,再用它安装 uv

# 安装 pipx
sudo apt install -y pipx

# 安装 uv
pipx install uv

# 为 uv 添加环境变量
# 注:我的 uv 路径是 $HOME/.local/bin
export PATH="$HOME/.local/bin:$PATH"

# 确认 uv 被正确安装
uv --version

3)安装 jupyterlab

创建一个工作目录,用来放虚拟环境:

# 创建目录
mkdir -p ~/proj/jupyter

# 打开目录
cd ~/proj/jupyter

使用 uv 安装 jupyterlab

uv venv
source .venv/bin/activate
uv pip install jupyterlab -i https://mirrors.cloud.tencent.com/pypi/simple/

四、启动 jupyterlab

1)启动服务

记录当前设备的内网 IP:

ip addr

Note: 国内的内网 IP 形如 192.168.xxx.xxx

启动 jupyterlab 服务:

jupyter lab --ip=0.0.0.0 --port=8888 --notebook-dir=/ --no-browser --allow-root

这样,你就可以用笔记本电脑访问树莓派上的 jupyter lab 了。

2)访问服务

在访问服务之前,请确保笔记本电脑与树莓派连接的是同一个路由器。然后在笔记本电脑的浏览器,远程访问树莓派的 IP + 端口。比如:

http://192.168.xxx.xxx:8888

如果服务能正常打开,恭喜你!如果不能,请按以下思路排查。

  1. 服务端:jupyter lab 服务是否正常运行
  2. 网络:笔记本是否可以连接到服务器端口
  3. 浏览器:浏览器是否可以正常打开链接

🚀 服务端排查

# 查看树莓派 8888 端口的占用进程
lsof -i :8888

# 查看 jupyter 的运行状态
ps -ef | grep jupyter

🌍 网络排查

如果你的笔记本是 macOS 或者 Linux 系统,运行:

# 检查树莓派的 8888 端口是否处于可连接的状态
nc -zv 192.168.xxx.xxx 8888

如果输出 succeeded! 说明连接正常,接着排查浏览器。

💻 浏览器排查

首先换浏览器,尝试使用主流浏览器是否可以打开:

如果不行,请检查浏览器是否拥有「本地网络权限」。对于 macOS,打开 系统设置 –> 隐私与安全性 –> 本地网络 进行设置。

⚠️ Chrome 浏览器

如果你用 Chrome 浏览器无法打开链接,但其他浏览器可以。大概率是 Chrome 对本地网络更严格的安全措施导致的。请尝试以下步骤:

先关闭所有 Chrome 浏览器,然后在 Terminal 运行以下命令:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --explicitly-allowed-ports=8888,7860

这会打开一个新的 Chrome 窗口,该窗口临时解封本地网络的 8888 和 7860 端口。

PS: 如果这个方法对你有效,放进 ~/.bash_profile 以便下次使用:

vim ~/.bash_profile

alias chrome-dev='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --explicitly-allowed-ports=8888,7860'

五、Docker 的安装与配置

1)安装 Docker

# 创建存放 GPG 密钥的目录
sudo mkdir -p /etc/apt/keyrings

# 下载 Docker 官方的 GPG 公钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 将 Docker 官方软件源添加到 Ubuntu 的 APT 源列表
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 更新 APT 的软件源
sudo apt update

# 安装 Docker 核心组件
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 查看 Docker 客户端版本
sudo docker --version

# 查看 Docker 的状态信息
sudo docker info

2)配置镜像源

打开 daemon.json 文件:

sudo vim /etc/docker/daemon.json

将镜像源写入文件中:

{
  "registry-mirrors": [
    "https://dc.j8.work",
    "https://docker.m.daocloud.io",
    "https://dockerproxy.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://docker.nju.edu.cn"
  ]
}

重启 docker 使配置生效:

sudo systemctl restart docker

测试 docker 是否正常工作:

# 使用 hello-world 镜像创建容器
sudo docker run hello-world

Note: 将当前用户加入 docker 组,避免每次都 sudo

sudo usermod -aG docker $USER

六、启动 Agent 应用

打开工作目录:

cd ~/proj

拉取 dive-into-langgraph 项目代码:

git clone https://github.com/luochang212/dive-into-langgraph.git

dive-into-langgraph/app 目录移动到 agent-server

# 将 app 剪切到 proj 目录,并重命令为 agent-server
mv dive-into-langgraph/app agent-server

# 打开 agent-server
cd agent-server

使用样板文件,创建 .env 文件:

cp .env.example .env
vim .env

这里需要在 阿里百炼 申请 API_KEY,并配置到 .env 文件。

# 使用 docker compose 启动 Agent 应用
sudo docker compose up -d

启动后效果如下:

rpi-agent-server

Docker Compose 的其它常用命令:

# 查看实时日志流
sudo docker compose logs -f

# 删除容器和本地构建的镜像文件
sudo docker compose down --rmi local

# 重新构建镜像并在后台启动容器
sudo docker compose up -d --build

七、将 jupyter lab 设为自启

1)配置 systemd

创建 systemd 配置文件:

sudo vim /etc/systemd/system/jupyterlab.service

编写 systemd 配置:

[Unit]
Description=JupyterLab Service
After=network.target

[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu
ExecStart=/bin/bash -c 'source /home/ubuntu/proj/jupyter/.venv/bin/activate && \
  /home/ubuntu/proj/jupyter/.venv/bin/jupyter-lab \
  --ip=0.0.0.0 \
  --port=8888 \
  --no-browser \
  --notebook-dir=/home/ubuntu'

[Install]
WantedBy=multi-user.target

2)加载配置

# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 设置开机自启
sudo systemctl enable jupyterlab.service

# 立即启动服务
sudo systemctl start jupyterlab.service

# 查看服务状态
sudo systemctl status jupyterlab.service

3)重启检查

重启系统,然后检查 jupyter lab 是否成功自启。

# 重启系统
sudo reboot

八、设置静态 IP

如果你有 OpenWrt 之类的软路由,可以使用它的静态 IP 功能。这样 DHCP 服务会将树莓派的 MAC 地址绑定一个固定 IP。你可以长期使用这个内网 IP 访问树莓派上的服务。如果没有软路由,也可以尝试 dhcpcd 续租、IP 定时上报等配置思路。

九、私有 LLM

如果你想把这个 Agent 变成私有的 LLM 服务,需要修改两个地方:

  • app.py:里面有使用 Ollama 提供 LLM 服务的代码
  • tool_role.py:该工具默认使用阿里百炼的服务,需要修改或删除