mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 06:41:58 +00:00
3a1e4aa816
用户拿到的是这么一段:
OpenAIAuthenticationError: Error code: 401 - {'error': {'code':
'invalid_model', 'message': 'The model does not exist or you do not have
access to it.'}}
流式失败,回退非流式:(同一段,再来一遍)
401 + Authentication 看着像 key 过期,实际上 key 好好的——是 model id 在这个
端点上不存在。照着原文去换 key 是白费功夫。而且整条轨迹里**没有任何地方**
记着试的是哪个模型:llm.start 只带了 message_count。
三处:
1. llm.start 带上 model。调用失败时至少知道试的是什么。
2. explain_model_error():invalid_model 译成"模型「x」在这个供应商上不存在…
去设置→供应商改模型列表";额度耗尽单独认;不认识的错误照抄原文(猜错了
比不猜更糟)。流式回退再失败时不再把同一段原文吐两遍,而是抛一条
NodeError。结构化输出那条路径也走同一个翻译——模型不存在不叫"结构化
输出失败"。
3. Copilot 提示里补上"model 字段不要填"。它原先只被告知 llm 节点有个 model
字段,却从不知道有哪些 model id,于是按供应商名字猜(看到 DeepSeek 就写
deepseek-chat)——猜出来的那个正好不存在。这是这次报错的真正来源,不修
的话每次生成都会再踩一遍。
顺带把那个供应商的模型列表改对了:列着的 deepseek-chat / deepseek-reasoner
两个都返回 invalid_model,而真正能用的 deepseek-v4-pro 反倒不在列表里(它是
default_model,所以"跟随默认"的节点一直是好的,手动选模型的节点必挂)。
逐个实测后换成 deepseek-v4-pro / deepseek-v3.2 / ernie-4.5-turbo-128k。
已确认没有已保存的工作流节点写死了那两个失效 id。
59 lines
2.0 KiB
Python
59 lines
2.0 KiB
Python
"""模型调用失败时说的话。
|
|
|
|
真实случай:供应商的模型列表里列了两个它根本不提供的 id,用户在节点上选了
|
|
其中一个,界面上抛出来的是
|
|
|
|
OpenAIAuthenticationError: Error code: 401 - {'error': {'code':
|
|
'invalid_model', 'message': 'The model does not exist or you do not have
|
|
access to it.', ...}}
|
|
|
|
401 + Authentication 看着像 key 过期,实际上 key 好好的。照着原文去换 key 是
|
|
白费功夫。而且整条轨迹里没有任何地方记着试的是哪个模型——因为 llm.start 只带
|
|
message_count。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from app.engine.nodes.llm import explain_model_error
|
|
|
|
|
|
class _FakeAuthError(Exception):
|
|
pass
|
|
|
|
|
|
def test_invalid_model_says_model_not_key() -> None:
|
|
exc = _FakeAuthError(
|
|
"Error code: 401 - {'error': {'code': 'invalid_model', 'message': "
|
|
"'The model does not exist or you do not have access to it.', "
|
|
"'type': 'invalid_request_error'}}"
|
|
)
|
|
msg = explain_model_error(exc, "deepseek-chat")
|
|
|
|
assert "deepseek-chat" in msg, "必须说清是哪个模型,否则没法排查"
|
|
assert "不存在" in msg
|
|
assert "设置" in msg and "供应商" in msg, "要给出下一步去哪儿改"
|
|
# 别把用户往换 key 的方向带
|
|
assert "401" not in msg
|
|
assert "Authentication" not in msg
|
|
|
|
|
|
def test_quota_is_not_confused_with_missing_model() -> None:
|
|
exc = _FakeAuthError("Error code: 429 - insufficient_quota: balance is 0")
|
|
msg = explain_model_error(exc, "gpt-4o")
|
|
assert "额度" in msg and "gpt-4o" in msg
|
|
assert "不存在" not in msg
|
|
|
|
|
|
def test_unknown_error_keeps_the_original_text() -> None:
|
|
"""不认识的错误照抄原文——猜错了比不猜更糟。"""
|
|
exc = _FakeAuthError("connection reset by peer")
|
|
msg = explain_model_error(exc, "some-model")
|
|
assert "some-model" in msg
|
|
assert "connection reset by peer" in msg
|
|
|
|
|
|
def test_long_errors_are_trimmed() -> None:
|
|
exc = _FakeAuthError("x" * 5000)
|
|
msg = explain_model_error(exc, "m")
|
|
assert len(msg) < 400
|