打造 MacBook 本地大模型代理中心:New API 与 LiteLLM 部署记录

随着各大云厂商接连推出极具性价比的大模型 API,手里不知不觉囤了各种厂商(如阿里云、腾讯云、DeepSeek 等)的多个 API Key。为了在本地各种 AI 工具(Chatbox、VSCode、Cursor)中无缝切换和聚合管理这些模型,在本地搭建一个 LLM API 网关(Proxy)成为了刚需。

“New API (可视化管理, golang) + LiteLLM (高阶路由容灾, python)” 是目前最理想的两个本地大模型代理解决方案。本文记录了在 MacBook 上的部署踩坑指北。

架构概览

  • New API:基于 Docker 部署。负责对接国内各家云厂商的私有协议,转换为统一的 OpenAI / Anthropic 标准协议,并提供直观的 Web UI 进行额度和令牌管理。
  • LiteLLM:基于 Python 虚拟环境 + Supervisord 本地部署。套在 New API 壳外,提供极客级别的按需路由(Routing)和故障自动转移(Fallback)。

一、部署 New API:OrbStack 与网络环境破局

在 Mac 上跑 Docker,强烈推荐使用 OrbStack 替代臃肿的官方 Docker Desktop,它不仅启动极速,且内存占用极低。

但由于大陆地区的网络原因,在执行 docker-compose up -d 拉取 New API 镜像时,大概率会遇到 context deadline exceeded 的超时报错。

💡 破局重点:配置加速镜像
不需要复杂的代理规则折腾,最直接有效的方案是在 OrbStack 中配置有效的镜像源。
打开 OrbStack -> Settings -> 左侧选 Docker -> 找到 Daemon 选项卡,填入以下配置并 Apply & Restart

{
"registry-mirrors":[
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi"
]
}

配置完成后,镜像拉取速度还不错,但是可能不稳定,需要多重试几次。国内很多其他的镜像源(如阿里云、腾讯云等)目前都不可用了,只有上面这三个 jsDelivr 的镜像源还勉强能用,深感嘘唏……

附上精简版 docker-compose.yml

services:
new-api:
image: calciumion/new-api:latest
container_name: new-api
restart: always
ports:
- "127.0.0.1:3000:3000"
volumes:
- ./data:/data

ports 部分强烈建议只绑定到 127.0.0.1,以确保服务只在本地可访问,提高安全性。


二、部署 LiteLLM:虚拟环境与 Supervisord 进程守护

LiteLLM 基于 Python 开发。为了极致节省 Mac 系统资源,我没有选择让它也跑在 Docker 里,而是直接在宿主机使用 venv 创建独立虚拟环境,并使用 supervisord 进行后台进程守护与开机自启管理。

1. 创建虚拟环境并安装

# 创建并激活虚拟环境
python3 -m venv ~/.litellm-env
source ~/.litellm-env/bin/activate
# 安装 litellm
pip install 'litellm[proxy]'

2. 💡 配置重点:Supervisord 与虚拟环境的结合

使用 Supervisor 管理虚拟环境中的 Python 应用,最大的踩坑点是路径问题:千万不能依赖系统的环境变量,必须在配置中直指虚拟环境的绝对路径!

通过 Homebrew 安装 Supervisor (brew install supervisor) 后,在配置目录(M芯片通常为 /opt/homebrew/etc/supervisor.d/)下创建 litellm.ini

核心配置写法如下:

[program:litellm]
# 【关键】不要直接写 litellm,必须写 venv 环境下的绝对执行路径!
command=/Users/你的用户名/.litellm-env/bin/litellm --config /Users/你的用户名/LLM/litellm/config.yaml --port 4000

# 指定工作目录
directory=/Users/你的用户名/LLM/litellm
user=你的用户名

# 自动重启与日志
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stdout_logfile=/Users/你的用户名/LLM/litellm/stdout.log
stderr_logfile=/Users/你的用户名/LLM/litellm/stderr.log

写好后执行:

supervisorctl update
supervisorctl restart litellm

总结

通过 OrbStack (Docker) + New API 搞定全网模型协议的标准化,再通过 venv + Supervisord + LiteLLM 搞定本地轻量化守护与高阶路由。整套架构完全跑在本地,逐步有了点本地的 token hub 的感觉,既满足了对多模型的无缝切换,又极大地节省了系统资源。

计划外的第一次川西环线

今年春节比往年长一些。妞儿很早就提议,我们是不是可以出去走走。回想起去年春节全废,以及自己最近的状态,本来想直接来个附议。但春节叠加长假,又是拖两个娃,实际体验可能是炼狱。因此,妞儿提了挺多出发目的地都被我否决了。直到有一天她说起毕棚沟,我一听,这不就是两年前我们理小路之行的折返点,同时也是我两次路过,但是从来没有想过要去的景点吗?

每次旅途出发前的时刻是最惬意的,虽然凌晨才把零食用闪购订好,起床也要比往常早一些。不紧不慢,加完油出发也是快十点了。路上偶遇了妞儿的哥哥一行,驱车4小时后,我们四人有回到了两年前理小路的折返点。毕棚沟景区前面的路依然拥堵,不同的是这次我们都没有丝毫的焦躁。虽然来的路上有过争吵的插曲,但是路过毕棚沟门口的时候,我和妞儿都决定,这次也不进景区了。相对于目的地,此刻的我们都一致认为最好的风景其实在路上。

于是,带着妻儿,我们续上了两年前的那个国庆没有走完的理小路。即使是童话公路,冬日的肃杀还是有的。一路上,我熟稔的给他们介绍这雷神瀑布和壮丽的魔戒峰。带他们在我上次的几乎每一个停车点驻足打卡。大二普没有了秋日的彩色,远处的雪山依然巍峨。尤其带他们搓了一顿现切的牛肉串,一切都刚刚好。跟上次自己单车不同的是,穿出理小路山谷段,我们没有左转返回成都,而是右转夜宿在了小金县。酒店楼下名曰“会师广场”。24年理小路通车,断断续续,来了三次;而这次是最接近初心的一次;完成这次会师是不经意的,但却跨越了3年。

前一天的右转更多是自驾人不喜欢走回头路的习惯,但第二天天亮总得为这个习惯买单:今天我们怎么走?本着一条道走到黑的原则,打开了我很喜欢的一个视频up主五月的天分享的奥尔地图。只用上厕所的时间就没有任何计划的规划出了一条路线。反正妞儿也判断不出这个路线行不行,出发了再说吧😄

第一站中路藏寨。最后几公里路很狭窄,回车其实比较费劲,但是我们似乎是那个村子当天为数不多的几个客人,一路上都非常顺利。在村子里转了几圈以后,一个回头弯,一座笔直碉楼的碉楼矗立蔚蓝天空。那一秒,钟灵魂有一种刷新的震撼。驻足碉楼之下,不在对“他人沧海桑田,彼之浮尘”耿耿于怀,而是一种时间尺度压缩的踏实感。

第二站同样出现在一个山路的回头弯上——虽然在专心的开车,但是眼前被一抹明亮所吸引——沐浴在灿烂阳光下的雅拉雪山。虽然雪山见过不少了,但是这一抹亮色在那个时候是如此的独特与震撼。停车以后,久久的驻足、回望。

严格来说其实没有第三站。因为天色渐晚,我们又该找住处了。有时候不仅是最美的风景在路上,更是没有计划是最好的计划。从雪山观景台往新都桥的路上,翻过垭口,广袤的高山草原,牛马洒落,溪水蜿蜒,天际雪山围抱。这难道是曲水流觞的高原江南!

晚上住在康定的时候,我跟妞儿说,今天路过的地方正好经过了五月的天的民宿,今晚住的城市是自己很喜欢的小祝的根据地。以前我通过他们的视频了解了川西之美,没想到今天一天就都完成了打卡,也把自己去年自己生日想走的路线顺带完成了。更没想到的是,回成都路上,偶然发现这三天没有任何计划的出行居然完成了自己和家人的第一次川西环线。而这距离自己拥有第一辆车,对川西起心动念,已经跨越了12年。

如果不是这次的恣意而行,这次旅途的邂逅又会是多少年呢?20年?25年?也许永远都不会……路就在那里,鄙人就在成都,有些路,不妨出发的时候就只有出发。

值得关注的 Agent Skills

落笔之前,顺手翻了一下之前关于LLM领域的技术动向记录,发现一个有意思的事情:Anthropic 这家公司除了经常在用户使用协议和声名上经常搞很抽象的事,在工程和模型上面不得不说真的是个落地和推进都很强的团队,颇有点当年Google几篇论文教育行业的味道。

去年十月,Anthropic 发布了一个叫做 Agent Skills 的项目,目标是让大模型能够更好地适应和执行复杂任务。这个项目的核心思想是通过定义一套“技能”(Skills),让模型能够像人类一样,逐步学习和掌握各种任务的执行方法:Equipping agents for the real world with Agent Skills。我其实没有立即跟进,因为当时看到大家的讨论都觉得这个项目和颇有点从MCP又回到function calling的感觉,不仅没什么新意,反而有种背叛初心的意味。

几个月以后,重新审视了这个项目,发现它其实有一些值得我们深入探讨。Agent Skills提到的几个核心优势:

  • 可组合性:技能可以像积木一样组合,形成更复杂的行为。
  • 可重用性:技能可以在不同任务中复用,提高开发效率。
  • 专用性:为领域任务进行能力剪裁适配。

而这几个优势其实本质上都是基于LLM的function calling能力,但Anthropic通过“技能”这个概念,赋予了这些能力更高的抽象层次和组织结构,使得开发者能够更方便地管理和调用这些功能模块。而这种工程上的构建思路其实是非常值得借鉴的:

  • 当前的 Agent 其实都免不了在 workflow 与 task decomposition 上面下功夫,而agent本身也可以看所是一个复杂的function calling。
  • 这个世界本身就是一个无限嵌套循环的function calling过程,不断折叠的过程。
  • 这种无限循环嵌套的过程需要进行更高层次的抽象和组织,才能更好地管理和调用这些功能模块。
  • 而这个层次的抽象和组织,其实跟OpenAI定义的人工智能能力标准和方向不谋而合。

使用文件系统进行技能的构建很多人觉得“挺落后的”。而我认为这本身本身无可厚非。一方面技能本身是一个工程实践的产物,如果使用场景本身就是跟沙箱等环境相关联,那么使用文件系统进行技能的构建其实是非常合适的。另一方面,回归的本质,对于操作系统来说,万物皆文件,这本身也是更高层次抽象的成熟手段。

当前的技能更多的是介于子workflow与原子function calling之间的一个产物。因此,它当前面向的用户更多是开发者和Pro级用户,而非普通终端用户。因此,任何从普通终端用户视角对它的评判都可能会有失偏颇。但是它迈出了非常有意义的工程实践第一步:如果这种模式被证明是可以梯度降低使用门槛的,那么我们可以顺着这条路一直构建和梯度降低,最终让普通终端用户也能享受到这种能力。这个梯度过程,将会是工程实践与模型迭代不断双向奔赴的过程,而这是有可能点燃无限希望的过程。一年以后,我们回头再看。