文章

AI - 大模型代理(bifrost)

AI - 大模型代理(bifrost)

AI - 大模型代理(bifrost)

我们的目标

  1. 把多家的llm厂商进行收拢,减少业务层变动,增加token安全。
  2. AI Agent多“设备USB”的远程接入。

bifrost VS 其他

我更倾向于go开发的llm代理,只需要一个可执行文件就行(服务端的启动程序),无需过多依赖(有些依赖库的版本,例如node、python)安装。

  • bifrost

    资料:https://docs.getbifrost.ai 、 https://github.com/maximhq/bifrost/releases

    高性能通用LLM网关、 5000 RPS(厂商数据),基础版(免费版)和企业版(完整版)。

    选择原因:基础版够用

  • GoModel

    资料: https://github.com/ENTERPILOT/GoModel

    我在使用的时候,model的alias用了一段时间,升级到了virtual models;但是我进行deepseek的Anthropic当作web_search工具时,由于参数未透传到底层,才放弃使用的。

  • CLIProxyAPI

    资料: https://github.com/router-for-me/CLIProxyAPI

    我用它代替了GoModel后,用了一段时间。

  • liteLLM

    未使用

行动(部署MCP服务)

资料参考:

https://skillhub.cn/mcp/mysql-mcp-server

https://skillhub.cn/skills/user_b22a52ba/mail-sender

https://mcp.so/servers/mcp-email-server

bifrost运行,同时当作mysql、email的MCP服务器。

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
FROM maximhq/bifrost:v2.2.6

USER root

# ============================================================
# 第 1 层:更换 Alpine 镜像源(加速 apk 下载)
# ============================================================
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

# ============================================================
# 第 2 层:安装 Node.js + Python3 + pip + 编译工具
# 说明:uvx 需要系统 Python 解释器,build-base 用于编译 Python 原生扩展
# ============================================================
RUN --mount=type=cache,target=/var/cache/apk \
    apk add --no-cache \
    nodejs npm \
    tzdata coreutils \
    python3 python3-dev py3-pip \
    build-base libffi-dev openssl-dev \
    && node --version \
    && python3 --version \
    && pip3 --version

# ============================================================
# 第 3 层:安装 uv / uvx(两种方式任选其一)
# ============================================================

# --- 方式 A(推荐):直接从官方镜像 COPY 二进制,最快最干净 ---
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/

# --- 方式 B(备选):如果 COPY 方式不可用,用 Alpine 包管理器 ---
# RUN apk add --no-cache uv

# 验证 uvx 可用
RUN uvx --version

# ============================================================
# 第 4 层:设置 npm 淘宝镜像源 + 安装全局 Node MCP 服务器
# ============================================================
RUN npm config set registry https://registry.npmmirror.com

RUN --mount=type=cache,target=/root/.npm \
    npm install -g @benborla29/mcp-server-mysql

# ============================================================
# 第 5 层:验证 Python MCP 服务器可通过 uvx 拉起(可选预装)
# uvx 是懒加载的,第一次调用会自动下载,这里不做预装
# ============================================================


USER 1000:0
WORKDIR /app

ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["/app/main"]
1
2
3
4
# 构建
docker build -t bifrost-mcp-server:2.2.6 .
# 如果dockerfile文件名为 bifrost-mcp-server.docker
# docker build -t bifrost-mcp-server:2.2.6 -f bifrost-mcp-server.docker . 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 启动,最好持久化到本地,方便重建container时数据不丢失
# 不用config.json文件控制,全部都存储到sqlite数据库中。
docker run -d \
  --name bifrost-mcp \
  -p 8081:8080 \
  -v /Users/wangfuyu/Project/docker_data/bifrost_mcp_data/data:/app/data \
  --add-host=host.docker.internal:host-gateway \
  -e ALLOW_INSERT_OPERATION=false \
  -e ALLOW_UPDATE_OPERATION=false \
  -e ALLOW_DELETE_OPERATION=false \
  -e BIFROST_SETUP_TOKEN=8a7be94c-b845-470b-b18c-dbb14c94f9e6.100 \
  -e TIME_ZONE=Asia/Shanghai \
  bifrost-mcp-server:2.2.6
  
# uvx --from mysql-mcp-server mysql_mcp_server
# uvx mcp-email-server@latest stdio

以上安装启动完成,进行配置一个宿主机的mysql和一个邮箱功能。

1
2
3
4
5
6
7
8
9
10
11
# 到 MCP Gateway -> New MCP Server 配置新服务
# mysql, 在容器中执行 uvx --from mysql-mcp-server mysql_mcp_server
connection Type : STDIO
command : uvx
arguments : --from,mysql-mcp-server,mysql_mcp_server
env : 
   MYSQL_HOST : host.docker.internal
   MYSQL_PORT :
   MYSQL_USER :
   MYSQL_PASSWORD :
   MYSQL_DATABASE :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# qq email
# 发邮件依赖 tzdata 必须安装
# 运行先安装 uvx mcp-email-server@latest stdio
connection Type : STDIO
command : uvx
arguments : mcp-email-server@latest,stdio
env : 
   MCP_EMAIL_SERVER_EMAIL_ADDRESS : my@qq.com
   MCP_EMAIL_SERVER_PASSWORD : Authorization Code
   MCP_EMAIL_SERVER_IMAP_HOST : imap.qq.com
   MCP_EMAIL_SERVER_IMAP_PORT : 993
   MCP_EMAIL_SERVER_SMTP_HOST : smtp.qq.com
   MCP_EMAIL_SERVER_SMTP_PORT : 465
   MCP_EMAIL_SERVER_ALLOWED_RECIPIENTS : *
   TIME_ZONE : Asia/Shanghai

假设是配置文件配置,那么是json方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "name": "email-qq",
  "connection_type": "stdio",
  "stdio_config": {
    "command": "uvx",
    "args": ["mcp-email-server@latest", "stdio"],
    "envs": [
      "MCP_EMAIL_SERVER_EMAIL_ADDRESS",
      "MCP_EMAIL_SERVER_PASSWORD",
      "MCP_EMAIL_SERVER_IMAP_HOST",
      "MCP_EMAIL_SERVER_IMAP_PORT",
      "MCP_EMAIL_SERVER_SMTP_HOST",
      "MCP_EMAIL_SERVER_SMTP_PORT"
    ]
  },
  "tools_to_execute": ["*"]
}

客户端

这里使用AnythingLLM客户端配置好llm和mcp server来进行对话就能实现操作。

mcp.json

1
2
3
4
5
6
7
8
9
10
{
  "mcpServers": {
    "bifrost-gateway": {
      "url": "http://127.0.0.1:8081/mcp",
      "headers": {
        "X-API-KEY": "sk-bf-ca393c4f-b53c-454a-b963-6c564ce3dbcb"
      }
    }
  }
}

png

png

curl客户端

如果在后台开启了Auto-execute,则可以内部直接完成MCP Tool的调用,直接返回答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
POST http://127.0.0.1:8081/anthropic/v1/messages
Content-Type: application/json
Authorization: Bearer sk-bf-ca393c4f-b53c-454a-b963-6c564ce3dbcb
x-api-key: Bearer sk-bf-ca393c4f-b53c-454a-b963-6c564ce3dbcb

{
  "model": "say",
  "max_tokens": 2048,
  "messages": [{"role":"user","content":"帮我看下数据表user_claw有多少条记录"}],
  "stream": false
}
#### response
{
  "id": "chatcmpl-ce3ede24-8aec-90ae-8e62-fdbcde9b27b0",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "thinking",
      "thinking": "The table user_claw has 1 record.\n\nLet me verify maybe there's also checking. Just report.",
      "signature": ""
    },
    {
      "type": "text",
      "text": "`user_claw` 表当前共有 **1 条记录**。\n\n补充一下表结构信息:\n\n| 字段 | 类型 | 说明 |\n|---|---|---|\n| id | bigint | 自增主键 |\n| user_id | bigint | 用户ID |\n| name | varchar | 名称 |\n| image_id | int | 使用镜像id |\n| state | tinyint | 状态,1开机,2关机,0默认 |\n| create_time | bigint | 录入时间 |\n| update_time | bigint | 最后一次修改时间 |\n| extra_time | varchar | 其他时间戳记录 |\n| agent_info | varchar | agent快照 |\n| worker_id | int | 工作服务所属集群的ID |\n\n如果想看这条记录的具体内容,或者确认是否包含被逻辑删除的数据,可以告诉我,我再帮你细查。"
    }
  ],
  "model": "deepseek-ai/DeepSeek-V4.1-Flash",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 3741,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "cache_creation": {
      "ephemeral_5m_input_tokens": 0,
      "ephemeral_1h_input_tokens": 0
    },
    "output_tokens": 414
  }
}

单独使用工具查询,json的request 是现在模型代理直接返回的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
####
POST http://127.0.0.1:8081/v1/mcp/tool/execute
Content-Type: application/json
Authorization: Bearer sk-bf-ca393c4f-b53c-454a-b963-6c564ce3dbcb
x-api-key: Bearer sk-bf-ca393c4f-b53c-454a-b963-6c564ce3dbcb

{
  "index": 0,
  "type": "function",
  "id": "call_611b946781ea496cadf8714b",
  "function": {
    "name": "nexus-execute_sql",
    "arguments": "{\"query\": \"SELECT COUNT(*) AS cnt FROM nexus.user_claw\"}"
  }
}
#### response
{
  "role": "tool",
  "content": "cnt\n1",
  "tool_call_id": "call_611b946781ea496cadf8714b"
}

结论

  1. 对多个大模型进行统一管理,方便切换。
  2. 对待使用tool,也可以一步到位,比如search、代发邮件、统一文件资源中心等功能,直接使用mcp让模型集成回答问题。
  3. 对于单独接入MCP的,使用别的LLM,那么可能返回的tool不是想要的,需要用程序写好返回tool的参数。
  4. bifrost 部署需要联网,可以自己对出网控制,允许请求他们官方的数据。
本文由作者按照 CC BY 4.0 进行授权