fix(llm): _pick_candidate协议感知选端点(404根因)——按模型profile.protocol过滤端点标签,不匹配报真实可行动错误;无标签端点视为通用(向后兼容)
This commit is contained in:
parent
7b6b74646d
commit
51d1e4ccdd
@ -260,8 +260,19 @@ def _filter_by_pref(candidates_with_ep, pref: str):
|
||||
return matched + rest
|
||||
|
||||
|
||||
async def _model_protocol(sor, model: dict) -> str:
|
||||
"""模型适配模板的协议(2026-09-05 端点协议感知选择用)。查不到返回空串。"""
|
||||
pid = (model.get('profile_id') or '').strip()
|
||||
if not pid:
|
||||
return ''
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT protocol FROM llm_api_profile WHERE id=${i}$ LIMIT 1", {"i": pid})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
return (getattr(recs[0], 'protocol', '') or '').strip() if recs else ''
|
||||
|
||||
|
||||
async def _pick_candidate(sor, model: dict, pref: str):
|
||||
"""构建候选并选一个:区域偏好过滤 → 冷却避让 → 余额加权。
|
||||
"""构建候选并选一个:协议过滤 → 区域偏好过滤 → 冷却避让 → 余额加权。
|
||||
|
||||
返回 (ok, result):ok 时 result=(account_dict, endpoint_dict);否则 result=错误信息。
|
||||
"""
|
||||
@ -274,6 +285,27 @@ async def _pick_candidate(sor, model: dict, pref: str):
|
||||
accounts = await _account_candidates(sor, model)
|
||||
if not accounts:
|
||||
return False, '模型「%s」的供应商下无启用账号(或账号余额状态异常)' % model.get('name', '')
|
||||
# 协议感知(2026-09-05 404 教训):模型模板协议与端点标签匹配才可用。
|
||||
# 端点无标签(历史数据)视为通用——同供应商混布 compatible-mode/api/v1
|
||||
# 两类端点时,无标签过滤会把原生异步模型拼到 openai_compat 前缀下 404。
|
||||
mproto = await _model_protocol(sor, model)
|
||||
if mproto:
|
||||
tagged = [(i, e) for i, e in enumerate(endpoints) if (e.get('protocol') or '').strip()]
|
||||
if tagged:
|
||||
matched = {i for i, e in tagged if (e.get('protocol') or '').strip() == mproto}
|
||||
untagged = {i for i, e in enumerate(endpoints)
|
||||
if not (e.get('protocol') or '').strip()}
|
||||
usable = matched | untagged
|
||||
if not matched:
|
||||
return False, ('供应商端点均为其他协议(模型模板协议 %s,端点协议 %s)——'
|
||||
'原生异步(openai_compat 之外)与兼容模式端点 base_url 不同,'
|
||||
'混用必 404。请在供应商端点目录添加协议 %s 的端点'
|
||||
% (mproto, sorted({(e.get('protocol') or '') for _, e in tagged}),
|
||||
mproto))
|
||||
else:
|
||||
usable = set(range(len(endpoints)))
|
||||
else:
|
||||
usable = set(range(len(endpoints)))
|
||||
# 展开 (账号, 端点) 对:账号选用的端点下标
|
||||
pairs = []
|
||||
for acc in accounts:
|
||||
@ -285,10 +317,11 @@ async def _pick_candidate(sor, model: dict, pref: str):
|
||||
i = int(i)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
if 0 <= i < len(endpoints):
|
||||
if i in usable:
|
||||
pairs.append((acc, endpoints[i], i))
|
||||
if not pairs:
|
||||
return False, '所有账号都未选用端点(模型治理→供应商账号→选用端点),请配置'
|
||||
return False, ('所有账号都未选用可用端点(模型治理→供应商账号→选用端点)。'
|
||||
'模型模板协议 %s——请把该协议端点加入账号的选用端点' % (mproto or '未知'))
|
||||
pairs = _filter_by_pref(pairs, pref)
|
||||
if not pairs:
|
||||
return False, ('端点偏好为「仅 %s」,但没有可用的该区域端点。按合规要求不跨端点降级——'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user