本文记录 Aider 连接自建 FreeLLMAPI 时遇到的两个典型问题,并给出完整解决方案。
最终实现:
Aider → LiteLLM → FreeLLMAPI → Cloudflare → NVIDIA Nemotron
适用于使用自建 OpenAI Compatible API 的 Aider 用户。
一、环境介绍
本次使用的环境如下:
1
2
3
4
5
6
操作系统:Windows 10
Aider:0.86.2
Python:3.11.9
LiteLLM:1.81.10
FreeLLMAPI:自建服务
模型:NVIDIA Nemotron 3 120B
Aider 通过 OpenAI Compatible API 调用 FreeLLMAPI。
整体架构:
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
┌─────────────────────┐
│ Aider │
│ v0.86.2 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ LiteLLM │
└──────────┬──────────┘
│ HTTPS
▼
┌─────────────────────┐
│ FreeLLMAPI │
│ OpenAI Compatible │
│ API │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Cloudflare │
│ Workers AI │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ NVIDIA Nemotron │
│ 3 120B A12B │
└─────────────────────┘
二、Aider 配置 FreeLLMAPI
FreeLLMAPI 提供 OpenAI Compatible API,因此 Aider 可以直接按照 OpenAI 模型进行配置。
Aider 配置文件:
1
2
3
openai-api-base: "https://freellmapi.example.com:5443/v1"
openai-api-key: "你的 FreeLLMAPI API Key"
model: "openai/nemotron-3-120b"
其中 openai-api-base 填写 FreeLLMAPI 的 OpenAI Compatible API 地址,例如 https://freellmapi.example.com:5443/v1。
模型名称 openai/nemotron-3-120b 是 Aider/LiteLLM 使用的模型标识,FreeLLMAPI 内部再将它映射到实际的后端模型。
三、问题一:Aider 提示 Connection error
配置完成以后运行:
1
aider
出现:
1
2
litellm.InternalServerError:
InternalServerError - OpenAIException - Connection error
此时不要直接判断 FreeLLMAPI 服务异常,首先需要确认 API 本身是否正常。
四、确认 FreeLLMAPI API 正常
使用 curl 直接测试:
1
curl.exe https://freellmapi.example.com:5443/v1/chat/completions
或者使用 Python HTTPX 测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import httpx
response = httpx.post(
"https://freellmapi.example.com:5443/v1/chat/completions",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"model": "nemotron-3-120b",
"messages": [
{
"role": "user",
"content": "你好"
}
],
"stream": False
},
timeout=30
)
print(response.status_code)
print(response.text)
如果直接调用能够正常返回模型结果,那么说明 FreeLLMAPI、API Key、模型、网络均正常,问题需要继续向 Aider → LiteLLM → HTTPX → HTTPS 这一层定位。
五、定位到 HTTPS 证书链问题
使用 OpenSSL 检查服务器证书:
1
2
3
4
openssl s_client `
-connect freellmapi.example.com:5443 `
-servername freellmapi.example.com `
-showcerts
最开始服务器只发送了服务器证书:
1
2
3
4
Certificate chain
0 s:CN=*.example.com
i:C=CN, O=Xin Net Technology Corp., CN=XinNet RSA DV
同时出现:
1
2
Verify return code: 21
unable to verify the first certificate
Python HTTPX 也出现:
1
2
CERTIFICATE_VERIFY_FAILED
unable to get local issuer certificate
这说明问题不是 API 本身,而是服务器没有正确提供完整的 HTTPS 证书链。
六、为什么浏览器正常,Aider 却无法连接?
这是 HTTPS 问题中非常常见的现象。浏览器能够正常访问 https://freellmapi.example.com:5443,并不代表 Python 一定能够正常验证证书。
因为不同软件使用的 CA 信任库可能不同:
1
2
3
4
5
6
7
浏览器
↓
自己的证书信任体系
Python / HTTPX
↓
Python/OpenSSL/certifi
如果服务器没有正确发送中间 CA,浏览器可能可以找到对应证书,但 Python 无法构建完整证书链,于是就会出现 CERTIFICATE_VERIFY_FAILED。
七、正确解决方法:配置 Nginx Full Chain
FreeLLMAPI 使用 Nginx 提供 HTTPS 服务。Nginx 不应该只配置服务器证书,而应该提供服务器证书加中间 CA 证书,也就是通常所说的 fullchain.pem。
例如:
1
2
3
4
5
6
7
-----BEGIN CERTIFICATE-----
服务器证书
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
中间 CA 证书
-----END CERTIFICATE-----
Nginx 配置:
1
2
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/server.key;
修改完成以后检查:
1
nginx -t
确认配置无误后重新加载:
1
nginx -s reload
如果使用 Docker、宝塔或者其他管理方式,则按照对应方式重新加载 Nginx。
八、再次检查 HTTPS 证书链
重新执行:
1
2
3
4
openssl s_client `
-connect freellmapi.example.com:5443 `
-servername freellmapi.example.com `
-showcerts
此时应该能够看到:
1
2
3
4
5
6
7
8
9
Certificate chain
0 s:CN=*.example.com
i:C=CN, O=Xin Net Technology Corp., CN=XinNet RSA DV
1 s:C=CN, O=Xin Net Technology Corp., CN=XinNet RSA DV
i:C=US, ST=New Jersey, L=Jersey City,
O=The USERTRUST Network,
CN=USERTrust RSA Certification Authority
这说明服务器已经发送了完整的服务器证书链(服务器证书 + 中间 CA)。
需要注意:通常不需要在服务器上额外发送 Root CA 根证书。服务器主要提供 Leaf Certificate 和 Intermediate Certificate,客户端再通过自己的信任库找到 Root CA。
九、使用 Python 验证 TLS 是否已经修复
这是整个排障过程中非常重要的一步。使用 Aider 自己的 Python 环境:
1
& "C:\Users\user\AppData\Local\pipx\pipx\venvs\aider-chat\Scripts\python.exe" -c "import httpx; r=httpx.get('https://freellmapi.example.com:5443/v1/models',verify=True,trust_env=False,timeout=20); print('STATUS:',r.status_code); print(r.text)"
如果得到 STATUS: 401,例如:
1
2
3
4
5
6
{
"error": {
"message": "Invalid API key",
"type": "authentication_error"
}
}
不要把它误认为 TLS 又失败了。 实际上这个结果说明 TLS 握手、HTTPS 连接、HTTP 请求、FreeLLMAPI 均已正常,只是测试请求没有携带正确 API Key,所以服务器返回 401 Unauthorized。这反而证明 Python → FreeLLMAPI 的 HTTPS 证书验证已经成功。
十、问题二:Aider 与 LiteLLM 版本兼容
解决 HTTPS 问题后,还需要确保 Aider 与 LiteLLM 版本匹配。本次环境为 Aider 0.86.2、LiteLLM 1.81.10。
如果 LiteLLM 版本与 Aider 0.86.2 不兼容,Aider 可能在调用模型之前直接出现:
1
2
3
ValueError:
PermissionDeniedError is in litellm
but not in aider's exceptions list
这个错误非常具有特征性。它不是 FreeLLMAPI API 错误,也不是 HTTPS 错误,而是 Aider 内部的 LiteLLM 异常映射与当前 LiteLLM 版本不一致。Aider 在初始化 LiteLLM 异常处理机制时,发现 LiteLLM 中存在 PermissionDeniedError,但 Aider 0.86.2 的异常列表中没有对应定义,于是直接抛出 ValueError。
十一、正确解决方法:使用兼容的 LiteLLM 版本
对于 Aider 0.86.2,本次验证可正常工作的版本为 LiteLLM 1.81.10。
如果使用 pipx 安装 Aider,可以直接对 Aider 自己的虚拟环境操作:
1
pipx runpip aider-chat install "litellm==1.81.10"
然后检查:
1
pipx runpip aider-chat show litellm
应该看到:
1
2
Name: litellm
Version: 1.81.10
再检查依赖:
1
pipx runpip aider-chat check
确保没有依赖冲突。
十二、重新运行 Aider
现在重新执行:
1
aider
正常启动:
1
2
3
4
Aider v0.86.2
Model: openai/nemotron-3-120b with whole edit format
Git repo: .git with 0 files
Repo-map: using 1024 tokens, auto refresh
输入:
1
你是什么大模型?
最终得到:
1
我是Nemotron 3 Super,由NVIDIA创建的大型语言模型。
并显示:
1
Tokens: 626 sent, 327 received.
这说明已经真正完成了一次 API 调用。
十三、最终配置
最终 Aider 配置保持:
1
2
3
openai-api-base: "https://freellmapi.example.com:5443/v1"
openai-api-key: "你的 FreeLLMAPI API Key"
model: "openai/nemotron-3-120b"
不需要关闭 SSL 验证。也就是说,不建议长期使用:
1
no-verify-ssl: true
正确的方式应该是服务器正确配置 Full Chain,客户端正常验证 HTTPS,Aider/LiteLLM 正常调用 API,而不是通过关闭 SSL 验证来绕过证书问题。
十四、最终运行链路
最终系统如下:
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
┌───────────────────────────────┐
│ Windows 10 │
│ │
│ Aider 0.86.2 │
│ │ │
│ ▼ │
│ LiteLLM 1.81.10 │
└──────────────┬────────────────┘
│
│ HTTPS
│ Full Chain
▼
┌───────────────────────────────┐
│ FreeLLMAPI │
│ │
│ OpenAI Compatible API │
└──────────────┬────────────────┘
│
▼
┌───────────────────────────────┐
│ Cloudflare AI │
└──────────────┬────────────────┘
│
▼
┌───────────────────────────────┐
│ NVIDIA Nemotron 3 120B │
└───────────────────────────────┘
最终实现 Aider → LiteLLM → HTTPS → FreeLLMAPI → Nemotron 完整打通。
十五、故障排查总结
本次问题实际上可以归纳为两个独立问题。
问题一:HTTPS 证书链
错误:
1
2
CERTIFICATE_VERIFY_FAILED
unable to get local issuer certificate
解决:在 Nginx 中配置 fullchain.pem(服务器证书 + 中间 CA),然后重新加载 Nginx。
验证方式为 openssl s_client ... 以及 httpx.get(..., verify=True)。
问题二:Aider/LiteLLM 兼容
错误:
1
2
PermissionDeniedError is in litellm
but not in aider's exceptions list
解决:通过 pipx runpip aider-chat install "litellm==1.81.10" 固定与 Aider 0.86.2 兼容的 LiteLLM 版本。
十六、推荐的排障思路
以后如果 Aider 调用自建 OpenAI Compatible API 出现 Connection error,不要直接修改 Aider 配置,建议按照下面的顺序逐层测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
① curl
↓
确认 API 服务是否可访问
② Python HTTPX
↓
确认 HTTPS / TLS 是否正常
③ OpenAI Python SDK
↓
确认 OpenAI Compatible API 是否正常
④ LiteLLM
↓
确认 LiteLLM 是否能够调用
⑤ Aider
↓
确认最终集成
也就是按照网络 → TLS → HTTP API → LiteLLM → Aider 逐层排查。这样可以快速判断问题究竟属于网络问题、证书问题、API 问题、LiteLLM 问题还是 Aider 问题,而不会把不同层次的问题混在一起。
十七、结语
自建 OpenAI Compatible API 最大的优势,是可以让大量 AI 工具(如 Aider、Claude Code、OpenCode、Continue 以及各种 OpenAI Compatible Client)复用同一套 API,通过 OpenAI Compatible API 接入自己的模型网关。
但在实际部署过程中,需要特别注意两个问题:
第一,HTTPS 证书链必须完整。 如果 Nginx 只发送服务器证书,而没有发送中间 CA,浏览器可能正常访问,但 Python、HTTPX、LiteLLM 等客户端可能无法完成证书验证。
第二,Aider 与 LiteLLM 存在版本依赖关系。 Aider 并不是简单地调用一个完全独立的 HTTP API,而是通过 LiteLLM 完成模型调用,因此需要使用与 Aider 版本兼容的 LiteLLM。
本次最终验证成功的组合为:
1
2
3
4
5
Aider 0.86.2
LiteLLM 1.81.10
Python 3.11.9
FreeLLMAPI OpenAI Compatible API
模型 NVIDIA Nemotron 3 120B
最终实现了 Aider → LiteLLM → FreeLLMAPI → Cloudflare → NVIDIA Nemotron 的完整链路,并成功完成实际模型调用。