直接用 net/http 调 openai 官方 api 即可,核心是发带 authorization、content-type、user-agent 头的 post 请求,传标准 json 结构体,国内需配代理,务必处理 429/401 等响应体错误。

直接用 net/http 调 OpenAI 官方 API 就行,别自己加载模型
ChatGPT 3.5/4 不是本地可部署的开源模型,所谓“下载权重”“c提问加载”全是过时或错误信息。OpenAI 只提供 HTTPS API,Golang 对接的核心就是发 POST 请求、带 Authorization 头、传 JSON、收 JSON —— 没有别的路。
- 别信“gpt-侯捷”“本地加载模型”这类项目:它们要么已失效,要么实际仍是调 OpenAI 或其他代理中转,不是真离线推理
- 别折腾
net底层 TCP 连接:OpenAI API 是标准 REST over HTTPS,net/http完全够用,强行换协议只会引入 TLS 握手失败、证书验证错误等新问题 - 官方 endpoint 是
https://api.openai.com/v1/chat/completions,不是/v1/completions(那是旧版 text-davinci 接口,已弃用)
必须设对的三个 header:Authorization、Content-Type、User-Agent
少一个就 401 或 400,尤其是 Authorization 必须是 Bearer sk-xxx 格式,空格不能少,大小写敏感;Content-Type 错成 text/plain 会返回空响应但状态码还是 200,极难排查。
-
Authorization: Bearer <your-api-key></your-api-key>—— key 必须从 OpenAI Platform 控制台生成,不能复用网页登录 token -
Content-Type: application/json—— 不加或写错,API 会静默忽略 body -
User-Agent: golang-http-client—— 非强制但建议加,部分企业网络策略会拦截无 UA 的请求
结构体字段名要和 OpenAI 文档严格一致,尤其 messages 是切片
JSON 字段名大小写、嵌套层级、数组/对象类型必须和 官方文档 一模一样,Go struct tag 写错一个字母就导致 json.Marshal 生成空字段或 null。
type ChatRequest struct {
Messages []Message `json:"messages"` // 注意是小写 messages,不是 Messages
Model string `json:"model"` // 如 "gpt-3.5-turbo"
Temperature float64 `json:"temperature,omitempty"`
}
type Message struct {
Role string `json:"role"` // "system", "user", "assistant"
Content string `json:"content"`
}
-
messages必须是 slice,不能是 map 或单个 object;空切片会报错,至少传一个{Role: "user", Content: "..."} -
model值必须拼写准确:"gpt-3.5-turbo"≠"gpt35-turbo"≠"gpt-3.5-turbo-0125"(后者虽存在,但非默认) - 省略字段用
omitempty,否则零值(如Temperature: 0)会被序列化为"temperature":0,可能触发非预期行为
代理不是可选项,而是国内环境下的必要配置
不配代理,http.DefaultClient.Do 会卡死在 DNS 解析或 TLS 握手阶段,超时时间再长也连不上 api.openai.com —— 这不是代码问题,是网络策略限制。
- 用
http.Transport显式配置代理,不要依赖系统环境变量(HTTP_PROXY在某些容器或 IDE 中不可靠) - 代理地址格式必须含协议:正确是
http://127.0.0.1:7890,错写成127.0.0.1:7890会导致 panic: “invalid URL port” - 务必设置
Timeout和IdleConnTimeout,否则失败请求会堆积,最终耗尽 goroutine
最常被忽略的其实是错误处理:OpenAI 返回的 429 Too Many Requests 和 401 Invalid API key 都藏在 response body 里,只看 resp.StatusCode 不够,必须读 body 并 json.Unmarshal 才能看到具体 message。没做这步,就永远不知道是 key 过期还是额度用完了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











