npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@maplezzk/llm-proxy

v0.21.2

Published

本地统一 LLM 模型代理工具 — 多协议路由、协议互转、流式 SSE 转换、token 统计、协议抓包调试

Readme

llm-proxy

English | 简体中文

本地 LLM 代理服务,单端口同时提供管理 UI 和 AI API,支持多协议路由、协议互转、流式 SSE 转换、token 统计、协议抓包调试。

功能特性

  • 🔀 多协议支持:单端口提供 Anthropic、OpenAI、OpenAI Responses 三种协议
  • 🔄 协议互转:三个协议间双向转换(流式 + 非流式)
  • 📸 外挂识图:为不支持图片的模型自动接入识图模型,把图片转成文字描述再转发;自带持久化 LRU 缓存
  • 🖥️ macOS 桌面应用:原生菜单栏 App,内嵌代理服务,拖拽安装、零依赖
  • 📊 管理界面:Alpine.js 单页应用,包含仪表盘、Provider 管理、适配器配置、识图设置、抓包调试
  • 🎯 虚拟适配器:自定义端点 + 模型重映射(/{adapter-name}/v1/...
  • 📡 SSE 流式:4 个双向流转换器,每行带时间戳
  • 🔍 协议抓包:环形缓冲记录原始请求/响应,支持左右对比 + 差异分析
  • 🔥 热加载:配置原子替换,进行中请求不受影响
  • 📈 Token 统计:按 Provider 统计 token 使用量

截图

安装

macOS(推荐):Releases 下载 LLMProxy.dmg,拖入 /Applications。如果 macOS 阻止运行,执行:

xattr -cr /Applications/LLMProxy.app

再次打开即可。内含完整代理服务和管理界面。

macOS(Homebrew):

brew tap maplezzk/tap && brew install --cask llm-proxy

仅 CLI:

npm install -g @maplezzk/llm-proxy

快速开始

# 启动
llm-proxy start

# 打开管理界面 → http://127.0.0.1:9000/admin/

首次启动会自动创建配置目录。打开管理界面在浏览器里完成所有配置,无需手写 YAML。

管理界面支持:

  • Provider 管理:增删改 AI 服务商、拉取远程模型列表、声明输入模态(文本/图片)
  • 适配器配置:创建带模型重映射和协议转换的虚拟端点
  • 识图设置:为不支持图片的模型启用外挂识图、查看缓存命中率
  • 代理密钥:设置 API 认证密钥
  • 连通性测试:直接发送测试请求验证配置
  • 协议抓包:实时查看请求/响应原文

配置

~/.llm-proxy/config.yaml:

log_level: debug          # debug | info | warn | error
port: 9000                # 可选:默认 9000
max_body_size: 10485760   # 可选:请求体大小上限(字节,默认 10MB)
proxy_key: sk-xxx         # 可选:设置后 /v1/* 需认证

providers:
  - name: deepseek
    type: openai          # anthropic | openai | openai-responses
    api_key: ${DEEPSEEK_API_KEY}
    api_base: https://api.deepseek.com
    models:
      - id: deepseek-chat

  - name: anthropic
    type: anthropic
    api_key: ${ANTHROPIC_API_KEY}
    models:
      # 多模态模型 — 显式声明支持图片
      - id: claude-sonnet-4
        input: [text, image]
        thinking:
          budget_tokens: 10000

      # 非多模态模型 — 图片请求会自动走外挂识图
      - id: deepseek-reasoner
        # 不写 input → 默认 [text];图片请求触发外挂识图

      # MiniMax 思考模式透传(非标准 thinking.type)
      - id: MiniMax-M2
        thinking:
          type: enabled

adapters:
  - name: my-tool
    type: anthropic
    models:
      - sourceModelId: claude-sonnet-4
        provider: anthropic
        targetModelId: claude-sonnet-4-20250514

# 外挂识图 — 为不支持图片的模型自动识图
vision:
  provider: anthropic              # 必填:识图 Provider
  model: claude-sonnet-4           # 必填:多模态模型 ID
  prompt: |                        # 可选:自定义提示词(默认见下)
    请详细描述这张图片的内容,包括其中的文字、物体、场景、颜色等关键信息。

API Key 通过环境变量注入(${VAR}),配置文件不保存明文密钥。

外挂识图

当路由目标模型 未声明 input: image 时,llm-proxy 可以自动把图片内容转成文字描述,再交给模型处理:

  1. 入站请求包含图片块(Anthropic image、OpenAI Chat image_url、OpenAI Responses input_image
  2. llm-proxy 提取每张图片,通过代理自身路由调用配置的识图 Provider/Model(递归路由)
  3. 把图片块替换为 <image_description>...</image_description> 文本块
  4. 非多模态模型收到文本,就能"看懂"图片内容

识图缓存~/.llm-proxy/vision-cache.json):

  • 键:base64 图片用 md5:<hash>,URL 图片用 url:<原 URL>
  • LRU 淘汰上限 1000 条(可通过 vision_cache.max_entries 调整)
  • 内存变更后 5s 防抖刷盘;进程退出前同步刷盘
  • 统计信息:hits / misses / hit-rate,通过 /admin/vision-cache/stats 查看

缓存文件位置:~/.llm-proxy/vision-cache.json

CLI 命令

llm-proxy start     # 启动代理
llm-proxy stop      # 停止代理
llm-proxy restart   # 重启
llm-proxy reload    # 热加载配置(零中断)
llm-proxy status    # 查看状态

管理 API

| 端点 | 方法 | 说明 | |----------|--------|-------------| | /admin/config | GET | 查看配置(Key 脱敏) | | /admin/config/reload | POST | 热加载配置 | | /admin/health | GET | 健康检查 | | /admin/status/providers | GET | Provider 状态统计 | | /admin/logs | GET | 请求日志 | | /admin/logs/stats | GET | 日志统计 | | /admin/token-stats | GET | Token 统计 | | /admin/log-level | GET / PUT | 查看 / 修改日志级别 | | /admin/locale | GET / PUT | 查看 / 修改界面语言(zh / en) | | /admin/port | GET / PUT | 查看 / 修改监听端口(需重启生效) | | /admin/proxy-key | GET / PUT | 查看 / 修改代理认证密钥 | | /admin/vision | GET / PUT | 查看 / 修改外挂识图配置 | | /admin/vision-cache/stats | GET | 识图缓存命中率 / 容量 | | /admin/vision-cache/clear | POST | 清空识图缓存 | | /admin/adapters | GET / POST / PUT / DELETE | 适配器 CRUD | | /admin/providers | POST / PUT / DELETE | Provider CRUD | | /admin/providers/:name/pull-models | POST | 拉取远程模型列表 | | /admin/test-model | POST | 向 Provider/Model 发送测试请求 | | /admin/test-adapter | POST | 通过适配器发送测试请求 | | /admin/debug/captures/* | GET / POST | 协议抓包环形缓冲 + SSE 推送 |

协议转换矩阵

| 源 | 目标 | 非流式 | 流式 (SSE) | |--------|--------|:---:|:---:| | Anthropic | OpenAI | ✅ | ✅ | | OpenAI | Anthropic | ✅ | ✅ | | Anthropic | OpenAI Responses | ✅ | ✅ | | OpenAI Responses | Anthropic | ✅ | ✅ |

架构

Client → POST /v1/{messages|chat/completions|responses}
  → server.ts(正则路由匹配)
    → pipeline.ts(统一请求流水线)
      → parseAndAuth()(body、JSON、认证、提取 model)
      → vision.ts(图片 → 文字(外挂识图),含 LRU 缓存)
      → router.ts(modelName → Provider)
      → translation.ts(协议转换、thinking 注入)
      → provider.ts(fetch 上游)
      → stream-converter.ts(SSE 转换)
      → capture.ts(环形缓冲 + SSE 推送)
      → token-tracker(按 Provider 统计 token 用量)
  → 响应
  • 运行时:Node.js >= 20, TypeScript ESM
  • 前端:Alpine.js 单页应用
  • 构建tsc + esbuild
  • 测试:Node.js 原生测试运行器 + tsx(280 个测试)

开发

详见 DEVELOPMENT.md

npm run dev          # 开发模式启动代理
npm test             # 运行 280 个测试
npm run build:app    # 构建 macOS .app + .dmg

FAQ

Homebrew 安装显示旧版本? 强制刷新 tap:

brew upgrade --cask llm-proxy

如果失败,先卸载再重新安装:

brew uninstall --cask llm-proxy
brew untap maplezzk/tap && brew tap maplezzk/tap && brew install --cask llm-proxy

macOS 阻止应用运行? 清除隔离标记:

xattr -cr /Applications/LLMProxy.app

怎么清空识图缓存? 任选其一:

rm ~/.llm-proxy/vision-cache.json

或调用 POST /admin/vision-cache/clear(也可以在管理界面 → 识图设置 → 「清空缓存」按钮)。

识图缓存在哪里? ~/.llm-proxy/vision-cache.json,重启后保留,5s 防抖刷盘。

怎么给模型开启图片输入? 在管理界面 → Providers → 编辑模型 → 勾选 输入模态 → 图片,或在 config.yaml 中加 input: [text, image]。未声明 image 的模型在配置了 vision: 后会自动走外挂识图。