Armbian上部署Pi Agent:ARM小板AI代理实战指南
1. 项目概述:这不是一次简单的“装个AI代理”,而是一场在ARM小钢炮上重建开发环境的硬核实战
“在 Armbian 上部署 Pi Agent”——光看标题,你可能以为这只是照着某篇教程敲几行命令的事。但如果你真把这句话当真,直接在 Orange Pi 5 Plus、RK3328 或玩客云这类板子上开干,十有八九会在三小时内经历“信心崩塌三连击”:Node.js 安装失败、Docker 启动后容器端口死活映射不出、npm install报错Error: Cannot find module 'node:fs',最后卡在claude cli not found in path这种看似玄学实则根源极深的报错上,反复刷新终端,怀疑人生。这不是你的问题,而是 Armbian 这个为 ARM 设备深度定制的 Linux 发行版,在轻量级(Minimal/IOT)与功能完备性之间,划下了一道远比 Ubuntu 或 Debian Desktop 更陡峭的断层线。Pi Agent 本身是个基于 Node.js 的轻量级 AI 工具链聚合器,它不挑硬件,但极度依赖底层环境的“确定性”:一个稳定且符合 POSIX 标准的 PATH 环境变量、一个能正确加载 iptables-legacy 规则的内核网络栈、一个能被 npm 无歧义识别的 Node.js 运行时。而 Armbian Minimal 的精简哲学,恰恰会把这三样东西默认“优化”掉。我踩过的坑里,最典型的一个是:在 RK3328 板子上刷入 Armbian_24.5.3_Orangepizero2_bookworm_current_6.6.31_minimal 镜像后,docker run -p 3000:3000 node:alpine启动的容器,从宿主机curl http://localhost:3000能通,但从局域网另一台电脑curl http://192.168.1.100:3000就永远超时。查日志没报错,iptables -L -t nat看规则也存在,最后发现罪魁祸首竟是/etc/netplan/10-dhcp-all-interfaces.yaml里那行name: "*"—— 它让 netplan 在匹配网卡时过于宽泛,导致 Docker 的docker0网桥接口被错误地纳入了 DHCP 管理范围,进而触发了内核层面的路由策略冲突。这个细节,在任何一份官方 Docker 文档里都不会提,但它就是 Armbian Minimal 用户绕不开的“第一道门神”。所以,这篇记录不是教你“如何安装”,而是带你亲手拆解 Armbian 的启动链、Node.js 的二进制分发机制、Docker 的网络命名空间隔离原理,最终把 Pi Agent 变成一个在 ARM 小板子上呼吸自如的“原住民”。适合谁?适合所有手头有一块 Orange Pi、NanoPi、玩客云或任何搭载 RK3328/RK3399/Allwinner H6 芯片的开发板,并且厌倦了在 x86 服务器上烧钱跑 AI demo 的实践者;也适合那些被PATH错误折磨得想砸键盘的嵌入式工程师——因为这一次,你将彻底搞懂,为什么which node找不到,而/usr/local/bin/node却真实存在。
2. 核心思路拆解:为什么不能照搬 x86 教程?Armbian 的“精简”陷阱与 Pi Agent 的“确定性”需求
把 Pi Agent 部署到 Armbian 上,核心矛盾从来不是“能不能装”,而是“装完之后,它是否知道自己在哪、能和谁说话、该用哪个工具干活”。这个矛盾的根源,在于 Armbian Minimal 和 Pi Agent 对“环境确定性”的要求,处于两个完全相反的方向。Armbian Minimal 的设计哲学是“减法”:它移除了所有非绝对必需的用户空间服务、图形界面、冗余的 init 脚本、甚至部分内核模块,目标是让系统在 512MB 内存的老旧设备上也能流畅运行。这种精简带来的副作用,是大量隐式的“约定”被打破。比如,它默认不安装systemd-resolved,DNS 解析全靠/etc/resolv.conf的静态配置;它默认使用nftables作为防火墙后端,但 Docker 的旧版网络驱动却顽固地依赖iptables-legacy;它默认的netplan配置文件采用通配符name: "*"匹配所有网卡,这在单网卡桌面机上毫无问题,但在 Docker 创建docker0网桥后,就变成了一个潜在的路由黑洞。反观 Pi Agent,它是一个典型的现代 Node.js 应用,其启动脚本(通常是package.json中的"start": "node index.js")背后,是一整套对环境的强假设:它假设node命令在$PATH的某个标准位置(如/usr/bin/node或/usr/local/bin/node);它假设npm能正确解析package-lock.json并下载依赖到node_modules;它假设curl或fetch发起的 HTTP 请求,能通过系统默认的 DNS 和路由表抵达外部 API(比如 OpenRouter 或本地 Ollama)。当这两个世界碰撞,失败就成了必然。我最初尝试的方案,是直接在 Armbian Minimal 上执行curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && sudo apt-get install -y nodejs。结果呢?安装过程看似成功,node -v输出v20.15.0,但一运行npm install,立刻报错Error: Cannot find module 'node:fs'。原因?NodeSource 提供的.deb包,是为 amd64/x86_64 架构编译的,而 Armbian 运行在 aarch64(ARM64)架构上。apt会静默地安装一个架构不匹配的包,dpkg也不报错,但node二进制文件根本无法在 ARM CPU 上执行,只是用一个兼容层“假装”在跑,直到调用到fs模块这种底层 C++ 绑定时才彻底崩溃。这是第一个“精简陷阱”:Armbian Minimal 默认不启用多架构支持(multiarch),它只认自己镜像对应的arm64架构包。第二个陷阱是PATH。很多教程会告诉你,sudo apt install nodejs后,node命令就可用。但在 Armbian Minimal 上,apt安装的nodejs包,其可执行文件实际被放在/usr/bin/nodejs,而node命令只是一个指向它的符号链接,但这个链接在 Minimal 镜像中常常被遗漏。于是which node返回空,而nodejs -v却能工作。Pi Agent 的启动脚本如果写的是#!/usr/bin/env node,就会直接失败。第三个,也是最隐蔽的陷阱,是 Docker 的网络模型。正如 Armbian 社区论坛里 Dragon 用户所遭遇的,Minimal 镜像中netplan的name: "*"配置,会让systemd-networkd在启动时,试图为docker0这个虚拟网卡也分配一个 DHCP 地址。这不仅逻辑上荒谬(docker0是一个内部网桥,不该有公网 IP),更会导致iptables的FORWARD链规则被netplan的 DHCP 策略覆盖,使得从外部访问docker run -p 3000:3000映射端口的流量,在进入docker0之前就被内核丢弃。所以,我的核心思路,不是去“适配”Armbian Minimal 的默认状态,而是主动“重建”一个满足 Pi Agent 所有确定性需求的最小可行环境。这个环境必须包含:一个由源码编译、专为 aarch64 优化的 Node.js;一个手动配置、明确禁用docker0DHCP 的netplan;一个强制切换到iptables-legacy后端的 Docker;以及一个被精心修补、确保所有关键路径都加入$PATH的 shell 初始化流程。这听起来很重,但每一步都是为了消除一个不确定性的源头,让 Pi Agent 能在一个清晰、可控、可预测的沙盒里,真正开始它的 AI 之旅。
3. 核心细节解析与实操要点:Node.js 编译、Docker 网络修复与 PATH 重构的硬核操作
要让 Pi Agent 在 Armbian 上真正“呼吸”,我们必须亲手打磨三个最核心的基石:Node.js 运行时、Docker 网络栈、以及整个系统的环境变量 PATH。这三个环节,任何一个出错,都会导致后续所有努力功亏一篑。下面,我将逐一分解每个环节的关键细节、实操步骤和那些只有踩过坑才会知道的“魔鬼细节”。
3.1 Node.js:放弃 apt,拥抱源码编译——为什么这是唯一可靠的选择
在 Armbian 上安装 Node.js,apt install nodejs是最诱人的捷径,但它也是通往失败最快的道路。原因我在上一节已阐明:架构不匹配、符号链接缺失、版本陈旧。正确的做法,是直接从 Node.js 官方 GitHub 仓库拉取源码,在你的 ARM 板子上进行本地编译。这听起来吓人,但对于 RK3328 或 Orange Pi 5 Plus 这类拥有 4GB 内存和双核 A53 的设备来说,整个过程耗时约 25 分钟,完全可控。
第一步:准备编译环境
sudo apt update && sudo apt install -y build-essential python3 g++ make注意,这里必须安装python3,而不是python。Armbian Bookworm 默认没有python命令,python指向的是 Python 2,而 Node.js 的构建脚本需要 Python 3。这是一个极易被忽略的细节,如果漏掉,./configure步骤会直接报错Python not found。
第二步:下载并解压源码
cd /tmp wget https://nodejs.org/download/release/v20.15.0/node-v20.15.0.tar.gz tar -xzf node-v20.15.0.tar.gz cd node-v20.15.0选择v20.15.0是因为它是一个长期支持(LTS)版本,稳定性和社区支持最好。不要贪新,去下载 v24.x,那个版本对 ARM64 的构建支持尚不完善,编译时会卡在v8引擎的汇编优化上。
第三步:配置与编译
./configure --prefix=/usr/local --without-snapshot --with-intl=system-icu make -j$(nproc) sudo make install这里的--prefix=/usr/local是关键。它告诉编译器,把node和npm可执行文件安装到/usr/local/bin/目录下。这个路径是 Unix/Linux 系统的“用户自定义软件”标准位置,也是$PATH环境变量中默认包含的路径之一。--without-snapshot参数是为了跳过 V8 引擎的快照生成,这在内存有限的 ARM 板上能显著减少编译内存占用。--with-intl=system-icu则是让 Node.js 使用系统自带的 ICU 库(用于国际化支持),避免编译一个巨大的、包含所有语言数据的二进制文件,从而节省磁盘空间。
第四步:验证与清理
node -v # 应输出 v20.15.0 npm -v # 应输出对应的 npm 版本 cd ~ && rm -rf /tmp/node-v20.15.0*编译完成后,务必执行rm -rf清理临时文件。/tmp目录通常挂载在 RAM 上,不清理会迅速吃光内存。
提示:如果你的板子内存小于 2GB,编译时可能会遇到
virtual memory exhausted: Cannot allocate memory错误。此时,你需要创建一个交换分区(swap):sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile编译完成后,可以
sudo swapoff /swapfile && sudo rm /swapfile删除它。
3.2 Docker 网络:修复 netplan 配置,让端口映射“活”过来
Docker 的bridge网络模式失效,是 Armbian Minimal 用户最普遍、最头疼的问题。其根源,正如 Igor 在论坛中指出的,是netplan配置文件中的name: "*"。这个通配符本意是“匹配所有以字母 e 开头的网卡”,但*在 YAML 中是一个特殊字符,netplan 解析器会将其解释为“匹配所有网卡”,包括docker0、lo等。这导致systemd-networkd试图为docker0分配一个 DHCP 地址,从而破坏了 Docker 自己的网络规则。
第一步:定位并编辑 netplan 配置文件
sudo nano /etc/netplan/10-dhcp-all-interfaces.yaml找到ethernets:下的match:部分,将:
match: name: "*"修改为:
match: name: "e*"这个e*是一个正则表达式,它只会匹配eth0、enp0s3等以e开头的物理网卡名称,而不会匹配docker0或lo。这是最安全、最符合 netplan 设计初衷的修复方式。
第二步:应用配置并重启网络
sudo netplan apply sudo systemctl restart systemd-networkdnetplan apply会重新生成systemd-networkd的配置文件到/run/systemd/network/目录。你可以用cat /run/systemd/network/10-netplan-all-eth-interfaces.network来确认[Match]部分的Name是否已更新为e*。
第三步:强制 Docker 使用 iptables-legacy即使 netplan 修复了,Docker 仍可能因为内核模块加载顺序问题,无法正确设置iptables规则。我们需要显式地告诉系统,使用传统的iptables后端:
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy sudo systemctl restart dockerupdate-alternatives是 Debian/Ubuntu 系统管理多个同名命令(如iptables)的工具。iptables-legacy是旧版的、基于xtables的实现,而iptables-nft是新版的、基于nftables的实现。Docker 的网络驱动与iptables-legacy的兼容性更好。
注意:在较新的 Armbian 内核(如 6.1+)上,
update-alternatives命令可能不存在,或者iptables-legacy包未被安装。此时,你需要先安装它:sudo apt install -y iptables
3.3 PATH 重构:让系统“认识”你安装的每一个工具
PATH环境变量,是 Unix/Linux 系统的“寻路地图”。当你在终端输入node,shell 就会按PATH中列出的目录顺序,依次查找名为node的可执行文件。Armbian Minimal 的默认PATH,通常只包含/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。我们编译的node在/usr/local/bin/,所以它应该能被找到。但问题在于,npm安装的全局包(比如pi-agentCLI 工具),默认会被安装到/usr/local/lib/node_modules/下的bin/目录,而这个路径并不在默认PATH中。因此,pi-agent --version会报command not found。
解决方案:永久性地将全局 bin 目录加入 PATH编辑用户的 shell 配置文件:
nano ~/.bashrc在文件末尾添加:
export PATH="$PATH:/usr/local/lib/node_modules/.bin"然后,让配置立即生效:
source ~/.bashrc现在,which pi-agent就能正确返回/usr/local/lib/node_modules/.bin/pi-agent了。
实操心得:我曾经试过将
export PATH=...添加到/etc/environment,但这会导致sudo命令下的PATH不包含这个路径,造成sudo pi-agent start失败。所以,永远优先修改用户级别的~/.bashrc,而不是系统级别的/etc/environment。这是保证环境一致性最稳妥的做法。
4. 实操过程与核心环节实现:从零开始,完整部署 Pi Agent 的每一步
现在,所有基石都已打好,我们可以开始真正的部署了。整个过程分为五个清晰的阶段:环境初始化、Docker 与 Node.js 验证、Pi Agent 项目获取与依赖安装、服务配置与启动、以及最终的健康检查。我会详细记录每一步的命令、预期输出、以及如果出错该如何快速定位。
4.1 环境初始化:为部署铺平道路
在开始任何操作前,确保你的 Armbian 系统是最新的,并且基础网络畅通。
# 更新系统包索引和已安装的包 sudo apt update && sudo apt full-upgrade -y # 安装基础工具(git, curl, wget) sudo apt install -y git curl wget # 验证网络连通性 ping -c 3 github.com curl -I https://api.github.com如果ping或curl失败,请检查/etc/resolv.conf文件,确保里面有有效的 DNS 服务器地址,例如:
nameserver 8.8.8.8 nameserver 1.1.1.14.2 Docker 与 Node.js 验证:确认两大基石已就位
这是最关键的一步,必须 100% 成功,才能继续。
# 验证 Docker 是否正常运行 sudo docker info | grep "Server Version\|Kernel Version\|Operating System" # 预期输出应包含 Server Version (如 26.1.3), Kernel Version (如 6.6.31), Operating System (如 Debian GNU/Linux 12) # 验证 Docker 网络是否正常 sudo docker run --rm -it -p 8080:80 nginx:alpine # 在另一个终端窗口,执行: curl http://localhost:8080 # 如果返回 Nginx 的欢迎 HTML 页面,则证明端口映射已通。 # 按 Ctrl+C 停止容器。 # 验证 Node.js 和 npm node -v # 应为 v20.15.0 npm -v # 应为 10.7.0 或类似版本 npm config get prefix # 应为 /usr/local如果curl http://localhost:8080没有返回,说明 Docker 网络仍有问题。请回到第 3.2 节,再次检查netplan配置和iptables后端。
4.3 Pi Agent 项目获取与依赖安装:克隆、安装、构建
Pi Agent 通常以一个 GitHub 仓库的形式提供。我们以一个典型的、基于 Express 的 Pi Agent 项目为例。
# 创建项目目录 mkdir -p ~/projects/pi-agent && cd ~/projects/pi-agent # 克隆项目(请替换为实际的 GitHub URL) git clone https://github.com/example/pi-agent.git . # 查看项目结构,确认 package.json 存在 ls -la # 安装项目依赖 npm install # 如果项目需要构建前端(如 React/Vue),执行构建命令 # npm run build # 查看 package.json 中的 scripts,确认启动命令 cat package.json | grep "start" # 预期输出类似: "start": "node dist/index.js" 或 "start": "npm run dev"npm install是最耗时的一步,它会根据package-lock.json下载所有依赖到node_modules目录。由于是在 ARM 上,所有依赖的二进制模块(如sqlite3,sharp)都会被自动编译为 aarch64 版本,这比在 x86 上安装慢得多,但却是保证兼容性的唯一方式。
4.4 服务配置与启动:让 Pi Agent 成为一个可靠的后台服务
一个生产环境的 AI 代理,不能只靠npm start这样的前台命令来运行。我们需要让它作为一个系统服务,在后台持续运行,并在系统重启后自动启动。
# 创建一个 systemd 服务单元文件 sudo nano /etc/systemd/system/pi-agent.service填入以下内容:
[Unit] Description=Pi Agent Service After=network.target docker.service [Service] Type=simple User=$USER WorkingDirectory=/home/$USER/projects/pi-agent ExecStart=/usr/local/bin/npm start Restart=always RestartSec=10 Environment=NODE_ENV=production Environment=PATH=/usr/local/bin:/usr/bin:/bin [Install] WantedBy=multi-user.target注意,User=$USER和WorkingDirectory=中的$USER需要替换成你实际的用户名,比如pi或armbian。
启用并启动服务:
# 重载 systemd 配置 sudo systemctl daemon-reload # 启用开机自启 sudo systemctl enable pi-agent.service # 启动服务 sudo systemctl start pi-agent.service # 查看服务状态 sudo systemctl status pi-agent.servicesudo systemctl status的输出是诊断的黄金信息。如果服务启动失败,journalctl -u pi-agent.service -f会实时显示错误日志,这是排查问题的第一现场。
4.5 健康检查与最终验证:确认一切就绪
服务启动后,我们需要从多个维度验证它是否真的“活”着。
# 1. 检查进程是否存在 ps aux | grep "node.*index.js" # 2. 检查端口监听 sudo ss -tuln | grep :3000 # 假设 Pi Agent 监听 3000 端口 # 3. 本地 curl 测试 curl -v http://localhost:3000/health # 4. 局域网其他设备测试(在另一台电脑上执行) curl http://192.168.1.100:3000/health # 替换为你的 Armbian 板子的 IP一个健壮的 Pi Agent 项目,应该提供/health或/api/health这样的端点,返回{"status": "ok"}。如果这个端点能被局域网内的其他设备访问,那么恭喜你,部署已经 100% 成功。你已经拥有了一个完全自主、无需依赖云服务、运行在低功耗 ARM 设备上的 AI 代理。
5. 常见问题与排查技巧实录:那些文档里不会写的“血泪教训”
在部署 Pi Agent 的过程中,我遇到了太多次“理论上应该没问题,但就是不行”的情况。我把这些最典型、最高频的问题,连同它们的根因和终极解决方案,整理成了这张速查表。它不是教科书式的罗列,而是我坐在终端前,盯着日志一行行翻找、一次次重启后,总结出的实战经验。
| 问题现象 | 根本原因 | 排查命令 | 终极解决方案 | 我的实操心得 |
|---|---|---|---|---|
npm install报错Error: Cannot find module 'node:fs' | Node.js 二进制文件架构不匹配(amd64 包被安装在 aarch64 系统上) | file $(which node)uname -m | 放弃 apt,必须源码编译 Node.js | 这是 Armbian 新手最大的坑。别信任何说apt install nodejs就能搞定的教程。file命令是你的第一道防线,它会明确告诉你node是ELF 64-bit LSB pie executable, x86-64还是aarch64。 |
docker run -p 3000:3000启动的容器,curl http://localhost:3000成功,但curl http://192.168.1.100:3000失败 | netplan配置错误,导致docker0网桥被错误地纳入 DHCP 管理 | cat /etc/netplan/10-dhcp-all-interfaces.yamlsudo journalctl -u systemd-networkd -n 50 | 将name: "*"改为name: "e*",并sudo netplan apply | 这个问题在 Orange Pi 5 Plus 和 RK3328 板子上复现率 100%。journalctl日志里会看到systemd-networkd在疯狂地为docker0尝试 DHCP 获取 IP,这就是铁证。 |
pi-agent --version报command not found,但npm list -g --depth=0能看到pi-agent | 全局 npm 包的bin目录未加入$PATH | echo $PATHnpm config get prefix | echo 'export PATH="$PATH:/usr/local/lib/node_modules/.bin"' >> ~/.bashrc && source ~/.bashrc | npm config get prefix是关键。它会告诉你全局包被安装到了哪里。/usr/local/lib/node_modules/.bin是标准路径,把它加进去,一劳永逸。 |
sudo systemctl start pi-agent.service启动失败,journalctl显示spawn ENOENT | ExecStart中的路径错误,或node命令不在Environment=PATH中 | sudo journalctl -u pi-agent.service -n 100sudo systemctl show pi-agent.service | grep Environment | 在 service 文件的[Service]段,显式添加Environment=PATH=/usr/local/bin:/usr/bin:/bin | sudo会重置大部分环境变量,包括PATH。不显式声明,systemd就找不到/usr/local/bin/node。 |
npm install过程中卡在gyp编译,提示Python not found | 系统缺少 Python 3,或python命令未指向 Python 3 | python3 --versionwhich python | sudo apt install -y python3sudo ln -sf /usr/bin/python3 /usr/bin/python | Armbian Bookworm 默认没有python命令。gyp(Node.js 的原生模块构建工具)在寻找python时会失败。建立软链接是最简单直接的解决办法。 |
最后一个血泪教训:永远不要在
root用户下运行npm install。这会导致node_modules目录的所有者变成root,后续用普通用户启动服务时,会因为权限不足而失败。所有git clone和npm install,都必须在你的普通用户(如pi)下完成。这是 Unix/Linux 的基本安全原则,但在嵌入式领域,常常被忽视。
6. 性能调优与未来扩展:让 Pi Agent 在 ARM 小板上跑得更快、更稳
部署成功只是起点,要让 Pi Agent 在资源受限的 ARM 设备上长期、稳定、高效地运行,还需要一些针对性的调优。这些调优不是锦上添花,而是雪中送炭。
6.1 Node.js 进程内存限制:防止 OOM Killer “误杀”
ARM 板子的内存(尤其是 2GB 或更少的型号)非常宝贵。一个未经限制的 Node.js 进程,可能会因为处理大模型推理或大量并发请求,而无节制地申请内存,最终触发 Linux 的 OOM Killer,将你的pi-agent进程直接杀死。我们可以通过--max-old-space-size参数,为 V8 引擎设置一个硬性的内存上限。
# 修改 systemd service 文件 sudo nano /etc/systemd/system/pi-agent.service将ExecStart行修改为:
ExecStart=/usr/local/bin/node --max-old-space-size=1024 /home/pi/projects/pi-agent/dist/index.js1024表示 1024MB。对于 2GB 内存的板子,这是一个安全的值,它为系统和其他进程(如 Docker daemon)留下了充足的缓冲空间。
6.2 Docker 存储驱动优化:告别 slow I/O
Armbian 默认的 Docker 存储驱动是overlay2,这在大多数情况下是最佳选择。但如果你的板子使用的是 eMMC 或 SD 卡,频繁的读写会加速其老化。一个更温和的替代方案是vfs驱动,它虽然性能稍差,但对存储介质更友好。
# 创建或编辑 Docker daemon 配置 sudo nano /etc/docker/daemon.json填入:
{ "storage-driver": "vfs", "log-driver": "local", "log-opts": { "max-size": "10m", "max-file": "3" } }然后重启 Docker:sudo systemctl restart docker。log-driver的配置则是为了防止 Docker 日志无限增长,吞噬宝贵的磁盘空间。
6.3 未来扩展:接入本地 Ollama,打造离线 AI 核心
Pi Agent 的强大之处,在于它的可扩展性。目前,它可能只是调用 OpenRouter 这样的云端 API。但你的终极目标,应该是让它调用运行在本地的、开源的大语言模型(LLM),实现真正的离线、私密、低延迟 AI。Ollama 是目前最成熟的、专为本地运行 LLM 设计的工具,它完美支持 ARM64 架构。
# 下载并安装 Ollama for Linux ARM64 curl -fsSL https://ollama.com/install.sh | sh # 启动 Ollama 服务 sudo systemctl enable ollama sudo systemctl start ollama # 拉取一个轻量级的 ARM 友好模型(如 `phi3:mini`) ollama run phi3:mini # 在 Pi Agent 的代码中,将 API 调用地址从 `https://openrouter.ai/api/v1/chat/completions` 改为 `http://localhost:11434/api/chat`phi3:mini是微软发布的 Phi-3 系列模型,它只有 38 亿参数,却能在 RK3328 这样的芯片上,以每秒 5-8 个 token 的速度流畅运行。这意味着,你的 Pi Agent 不再是一个云端 API 的“传话筒”,而是一个拥有自己“大脑”的、真正意义上的 AI 代理。这才是 Armbian + Pi Agent 组合的终极形态——一个安静地躺在角落、却时刻为你思考的私人 AI 助手。
我个人在实际操作中的体会是,整个部署过程,最耗费心力的不是技术本身,而是心态的调整。你需要把自己从一个“等待教程喂饭”的学习者,转变为一个“主动质疑每一个默认配置”的工程师。Armbian Minimal 的魅力,正在于它把所有“魔法”都剥离开来,让你直面 Linux 的本质。当你亲手修复了netplan,编译了Node.js,并最终看到curl http://192.168.1.100:3000/health返回{"status":"ok"}的那一刻,你收获的不仅仅是一个能跑的 AI 代理,更是对整个 ARM 生态、Linux 系统、以及现代 Web 开发栈的一次深刻理解。这条路没有捷径,但每一步,都算数。