UniLLM 纯文本大模型 MCP
用一套统一接口调用市场主流的纯文本大模型,屏蔽各家协议差异。本 Skill 背后是一个 MCP Server。
支持 12 家厂商:OpenAI、Anthropic Claude、Google Gemini、DeepSeek、智谱 GLM、通义千问、Kimi(月之暗面)、豆包(火山方舟)、百川、MiniMax、零一万物,以及任意自定义 OpenAI 兼容端点(Ollama / vLLM / OneAPI / 中转网关)。
> <skill-directory> 指本 Skill 所在目录,而非用户项目目录。
> MCP Server 源码位于 <skill-directory>/server/。
⚠️ 核心声明:仅文本情况下可调用
本 MCP 只接受纯文本模型,且拒绝任何图片输入。
这是运行时强制的契约,不是文档约定 —— 校验发生在任何网络请求之前,被拒绝的调用不消耗任何 API 配额。
调用时(runtime)的判定规则
text_chat 收到一次调用
│
├─ 1. messages 中带 images? → ⛔ 拒绝(图片输入一律拒绝)
├─ 2. model 在「多模态白名单」中? → ⛔ 拒绝
├─ 3. model 在「纯文本清单」中? → ✅ 放行
└─ 4. model 不在任何内置清单(自定义名 / 接入点 ID)
├─ textOnly=true → ✅ 放行
└─ 未声明 → ⛔ 拒绝
关键差异:本契约没有「带图放行」这一途 —— 图片输入一律拒绝,无论模型是什么。这是刻意的单向约束。
满足契约的两种方式
| 方式 | 条件 | 适用场景 |
|---|---|---|
| A. 内置清单 | model 属于该厂商已知纯文本模型 |
常规使用,最省事 |
| B. 显式声明 | 传 textOnly: true |
自定义模型名、私有部署 |
工具一览
| 工具名 | 用途 | 契约 |
|---|---|---|
text_chat |
纯文本对话(单轮 / 多轮) | ⛔ 受限:仅文本情况下可调用 |
text_list_providers |
列出文本可用厂商与纯文本模型 | — |
text_list_models |
列出厂商的纯文本模型 | — |
text_provider_status |
检查密钥配置(返回掩码) | — |
> 工具在 Agent 中的实际名称形如 mcp__plugin_unillm-text_unillm-text__text_chat,调用时用短名即可。
各厂商纯文本可用性速查
| provider id | 厂商 | 可用的纯文本模型 | 被拒绝(多模态) | 国内直连 |
|---|---|---|---|---|
deepseek |
DeepSeek | deepseek-chat、deepseek-reasoner |
— | ✅ |
baichuan |
百川 | Baichuan4、Baichuan3-Turbo、Baichuan3-Turbo-128k |
— | ✅ |
zhipu |
智谱 GLM | glm-4-long、glm-z1-air |
glm-4-plus、glm-4-air、glm-4-flash |
✅ |
qwen |
通义千问 | qwen-long |
qwen-max、qwen-plus、qwen-turbo、qwen3-235b-a22b |
✅ |
moonshot |
Kimi | — | kimi-k2-0711-preview、moonshot-v1-* |
✅ |
doubao |
豆包 | — | doubao-seed-1-6-250615 等 |
✅ |
minimax |
MiniMax | — | MiniMax-Text-01 |
✅ |
yi |
零一万物 | — | yi-lightning、yi-large |
✅ |
openai |
OpenAI | — | gpt-4o、gpt-4o-mini 等 |
⚠️ 需代理 |
anthropic |
Claude | — | claude-sonnet-4-5-20250929 等 |
⚠️ 需代理 |
gemini |
Gemini | — | gemini-2.5-pro、gemini-2.5-flash 等 |
⚠️ 需代理 |
custom |
自定义端点 | 需 textOnly: true |
— | ✅ |
> 💡 只有 DeepSeek 与百川同时满足「国内直连 + 有纯文本模型」,是纯文本场景的首选。
> 用 text_list_models(provider=...) 可随时获取最新明细,返回会明确区分「纯文本」「多模态(不可用)」「向量」三类。
When to Use
- 用户要求调用大模型完成文本任务:文本生成、问答、摘要、翻译、改写、代码生成、文案撰写、角色扮演。
- 用户需要多轮文本对话(带 system prompt、温度控制)。
- 用户要做多模型对比 / 投票,需要一次调用多家厂商的文本模型。
- 用户问「支持哪些文本模型」「某厂商有哪些纯文本模型」「密钥配了没有」。
- 用户要把文本 LLM 能力接进自己的应用,需要一份可复用的统一 API 封装。
When NOT to Use
- 需要图像理解 / 图文问答 —— 本 MCP 会拒绝图片输入,请改用配套的
unillm-multimodal多模态 MCP。 - 需要文本向量化(embeddings) —— 请使用
unillm-multimodal的llm_embed工具。 - 需要图像生成(文生图)—— 当前版本不含该能力。
- 需要流式输出 —— 当前
text_chat为一次性返回完整结果。
参数说明
text_chat
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
provider |
enum | ✅ | 厂商 id |
model |
string | ✅ | 纯文本模型名 |
messages |
array | ✅ | {role, content}[],多轮需传全历史。传入 images 会被拒绝 |
textOnly |
boolean | 声明该模型仅支持文本。自定义模型名 / 私有部署时必填 | |
temperature |
number | 采样温度 0~2 | |
max_tokens |
number | 最大生成 token 数 | |
apiKey |
string | 临时密钥(优先于环境变量,通常无需填写) | |
baseUrl |
string | 覆盖默认基址(代理 / 自定义端点) |
密钥配置
密钥只从环境变量读取,不会写入任何文件,也不会回显完整值。
export DEEPSEEK_API_KEY="sk-xxxxxxxx" # 纯文本场景首选,国内直连
export BAICHUAN_API_KEY="xxxxxxxx"
export ZHIPU_API_KEY="xxxxxxxx"
export DASHSCOPE_API_KEY="sk-xxxxxxxx" # 通义千问
export MOONSHOT_API_KEY="sk-xxxxxxxx" # Kimi
export ARK_API_KEY="xxxxxxxx" # 豆包(火山方舟)
export OPENAI_API_KEY="sk-xxxxxxxx" # 需代理
export ANTHROPIC_API_KEY="sk-ant-xxxx" # 需代理
export GEMINI_API_KEY="xxxxxxxx" # 需代理
配置后可用 text_provider_status(provider="deepseek") 核对。
调用示例
1. 单轮文本对话
text_chat(
provider="deepseek",
model="deepseek-chat",
messages=[{"role": "user", "content": "用一句话解释什么是 MCP"}]
)
2. 多轮对话(需完整传入历史)
text_chat(
provider="zhipu",
model="glm-4-long",
messages=[
{"role": "system", "content": "你是一位严谨的技术顾问"},
{"role": "user", "content": "什么是 RAG?"},
{"role": "assistant", "content": "RAG 是检索增强生成…"},
{"role": "user", "content": "它和微调相比有什么优劣?"}
],
temperature=0.3
)
3. 长上下文文本处理
text_chat(
provider="qwen",
model="qwen-long",
messages=[{"role": "user", "content": "<超长文档内容>\n\n请提炼要点"}]
)
4. 强推理任务
text_chat(
provider="zhipu",
model="glm-z1-air",
messages=[{"role": "user", "content": "证明:素数的个数是无限的"}]
)
5. 自定义 / 私有部署模型(必须声明)
text_chat(
provider="custom",
baseUrl="http://localhost:11434/v1",
apiKey="ollama",
model="qwen2.5:7b",
textOnly=true, # ← 必填:声明这是纯文本模型
messages=[{"role": "user", "content": "你好"}]
)
6. 多模型对比(同一问题问多家)
deepseek/deepseek-chat vs zhipu/glm-4-long vs qwen/qwen-long
7. 走代理调用 OpenAI
text_chat(
provider="openai",
baseUrl="https://your-gateway.example.com/v1",
model="gpt-4-turbo",
messages=[{"role": "user", "content": "hello"}]
)
选型建议
| 场景 | 推荐 |
|---|---|
| 通用文本(首选) | deepseek/deepseek-chat —— 国内直连、质量好、成本低 |
| 长上下文 | qwen/qwen-long 或 moonshot/moonshot-v1-128k |
| 强推理 | zhipu/glm-z1-air 或 deepseek/deepseek-reasoner |
| 中文写作 | baichuan/Baichuan4 |
| 海外基线对照 | 配好代理后用 openai/* 或 anthropic/* |
错误处理
| 错误码 / 现象 | 含义 | 处理方式 |
|---|---|---|
| 🚫 文本契约校验未通过 | 用了多模态模型,或带了图片 | 换纯文本模型(如 deepseek-chat);移除 images |
MISSING_API_KEY |
未配置密钥 | 按提示设置对应环境变量 |
AUTH_FAILED (401) |
密钥无效/过期 | 检查密钥是否有多余空格 |
INSUFFICIENT_BALANCE (402) |
余额不足 | 充值或换厂商 |
FORBIDDEN (403) |
网络被限制或无权访问 | 用 baseUrl 指向中转网关 |
NOT_FOUND (404) |
模型名或 baseUrl 有误 | 用 text_list_models 核对 |
RATE_LIMITED (429) |
触发限流 | 已自动退避重试,仍失败则降并发 |
TIMEOUT |
请求超时 | 调大 UNILLM_TIMEOUT_MS |
NETWORK_ERROR |
网络不可达 | 检查网络;境外模型需代理 |
注意事项
- 契约校验先于网络请求:被拒绝的调用不消耗任何 API 配额。
- 不要打印密钥:任何情况下都不要
echo $XXX_API_KEY,也不要把它写进用户文件。 - 多轮要传全历史:本工具无服务端会话状态,多轮对话必须把历史消息完整放进
messages。 - Claude 的 max_tokens 必填:代码已默认补 4096,可按需覆盖。
- 模型名以厂商文档为准:内置清单是推荐值,厂商上新后可能变化;自定义模型请用
textOnly: true调用。
可配置项
| 环境变量 | 默认 | 说明 |
|---|---|---|
UNILLM_TIMEOUT_MS |
120000 |
单次请求超时(毫秒) |
UNILLM_MAX_RETRIES |
2 |
429/5xx/网络错误的重试次数 |
安装与自检
cd <skill-directory>/server
npm install && npm run build
node dist/index.js # stdio 启动;正常时 stderr 输出启动日志
若 MCP Server 未被加载,检查:
1. server/dist/index.js 是否已构建;
2. .mcp.json 中 ${CODEBUDDY_PLUGIN_ROOT} 是否被正确展开;
3. 插件是否在 settings.json 的 enabledPlugins 中启用。
> 需要图像理解能力,请同时安装配套技能 unillm-multimodal(多模态 MCP)。两者可独立安装,也可并存。