用 OpenAI 兼容接口构建微型 CLI
1. 先确定最小目标
一个实用的微型 CLI 不需要马上支持会话管理、插件系统和复杂配置,先完成三件事即可:读取用户问题、调用 OpenAI 兼容接口、把模型回复输出到终端。
本文使用 Python 标准库实现请求逻辑,因此不依赖特定 SDK。只要服务端提供兼容的 `/v1/chat/completions` 路径,就可以复用这套结构。
CodeRelay Hub 提供统一入口 `https://api.coderelayhub.com`,可以把 Claude、GPT、Gemini、DeepSeek、Kimi、GLM、Qwen 和其他模型放在同一套调用方式下。
2. 准备密钥和默认模型
先把密钥放进环境变量,避免把凭据写进源代码或提交到代码仓库。
命令:`export OPENAI_API_KEY="你的密钥"`
再设置两个可选变量,让同一个 CLI 能够切换接口地址和模型。
命令:`export OPENAI_BASE_URL="https://api.coderelayhub.com/v1"`
命令:`export OPENAI_MODEL="GPT-6.1 Sol"`
默认模型可以选择 `GPT-6.1 Sol`,需要更强的复杂推理能力时,也可以改成 `Claude Opus 5.5` 或 `Gemini 4 Argon`。
3. 编写最小请求函数
请求体使用常见的聊天格式,其中 `messages` 至少包含一条 `user` 消息。下面的函数会读取环境变量,设置授权头,并返回服务端的文本结果。
代码:`import json, os, sys, urllib.request`
代码:`def ask(prompt):`
代码:` base = os.getenv("OPENAI_BASE_URL", "https://api.coderelayhub.com/v1")`
代码:` model = os.getenv("OPENAI_MODEL", "GPT-6.1 Sol")`
代码:` body = {"model": model, "messages": [{"role": "user", "content": prompt}]}`
代码:` request = urllib.request.Request(base + "/chat/completions", data=json.dumps(body).encode(), headers={"Authorization": "Bearer " + os.environ["OPENAI_API_KEY"], "Content-Type": "application/json"})`
代码:` with urllib.request.urlopen(request, timeout=60) as response:`
代码:` data = json.load(response)`
代码:` return data["choices"][0]["message"]["content"]`
4. 添加命令行入口
入口逻辑可以从位置参数读取问题,也可以在没有参数时读取标准输入,这样既支持单次查询,也支持管道组合。
代码:`prompt = " ".join(sys.argv[1:]) or sys.stdin.read().strip()`
代码:`if not prompt:`
代码:` raise SystemExit("请输入问题")`
代码:`try:`
代码:` print(ask(prompt))`
代码:`except urllib.error.HTTPError as error:`
代码:` raise SystemExit(f"请求失败:{error.code} {error.read().decode()}")`
把这些内容保存为 `ask.py` 后,可以使用 `python ask.py "解释这个错误"` 发起第一次调用。错误处理至少要区分网络失败、授权失败和服务端返回的无效数据。
5. 加入模型切换和流式输出
模型切换不应该要求修改代码,使用 `--model` 参数覆盖默认值即可。实际实现时,可以用 `argparse` 解析参数,再把选中的模型写入请求体。
较长回答适合启用流式输出,把请求体中的 `stream` 设置为 `true`,然后逐行读取服务端事件并立即打印。这样用户能更早看到结果,也能减少等待完整响应时的空白感。
流式解析需要处理空行、结束标记和不完整事件,因此建议先让非流式版本稳定,再单独添加解析器,并为结束标记和异常响应补充测试。
6. 保持接口边界清晰
把环境变量读取、请求构造、响应解析和终端展示分成独立函数,后续切换到 OpenAI SDK 时就只需要替换请求层。
不要在日志中打印授权头,也不要把完整提示词和敏感响应无条件写入文件。生产使用时还应加入重试上限、请求超时、退出码和输入长度限制。
当 CLI 稳定后,可以把它接入编辑器、脚本或 CI 任务。CodeRelay Hub 的统一入口让这些调用继续使用同一套 OpenAI SDK 习惯,同时可以按需选择现有模型。
现在就打开一个免费工作区,开始运行你的第一个 CLI。