feat(platform): apply_llm_config自动产品映射(2026-09-08用户需求:添加模型时如有产品模块自动映射)
根治记账failed"模型未映射到产品"不靠人工事后补: - _sync_model_products:apply落库后调env.import_categories_and_products (resource_module=pipeline_llm)增量导入所有active模型为产品(幂等:已映射按 resource_ref_id+org_id跳过,顺带自愈其他漏映射模型) - 父类别复用已有pipeline_llm根类别"大模型消费"(防类别树分裂) - 产品模块未装→跳过不阻断(模型注册已成功,映射是下游增值步骤);失败如实记 product_mapping.note - check_model_accounting hint与工作流prompt同步:未映射→重跑apply触发自动映射
This commit is contained in:
parent
a9cac99c52
commit
e5902a4fd4
@ -735,6 +735,61 @@ async def _write_model_skill(sor, vmid, m, spec, profile_ids):
|
||||
logger.info("模型配套技能已写入: %s", path)
|
||||
|
||||
|
||||
# pipeline_llm 产品类别根名(首次自动建;已存在则复用,防类别树分裂)
|
||||
_LLM_PRODUCT_ROOT_NAME = "大模型消费"
|
||||
_LLM_ROOT_CAT_ID = "7S4za5hOEJqBGXb2f-NmK" # 现有根类别 id(实测),新建时兜底用它
|
||||
|
||||
|
||||
async def _sync_model_products(sor, org_id="0"):
|
||||
"""模型上线后自动产品映射(2026-09-08 用户需求:添加模型时如有产品模块自动映射)。
|
||||
|
||||
根治记账 failed「模型未映射到产品」:apply 落库模型后,调产品模块的
|
||||
import_categories_and_products(resource_module='pipeline_llm') 增量导入
|
||||
所有 active 模型为产品(幂等:已映射的按 resource_ref_id+org_id 跳过,
|
||||
顺带自愈其他漏映射模型)。
|
||||
|
||||
产品模块未装(env 无 import_categories_and_products)→ 返回跳过说明,
|
||||
不阻断 apply(模型注册本身已成功,产品映射是下游增值步骤)。
|
||||
返回 (ok, note)。
|
||||
"""
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
import_fn = getattr(env, "import_categories_and_products", None)
|
||||
if not callable(import_fn):
|
||||
return True, "产品模块(product_management)未加载,跳过自动产品映射(模型已注册成功,可后续在产品管理手动导入产线模型)"
|
||||
|
||||
# 定父类别:复用已有 pipeline_llm 根类别(防类别树分裂);没有则新建根
|
||||
parent_cat = _LLM_ROOT_CAT_ID
|
||||
try:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT id FROM product_category WHERE resource_module='pipeline_llm' "
|
||||
"AND parent_id IS NULL AND org_id=${o}$ LIMIT 1", {"o": org_id})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
if recs:
|
||||
parent_cat = getattr(recs[0], "id", "") or _LLM_ROOT_CAT_ID
|
||||
else:
|
||||
# 查名字兜底(parent_id 可能存 '0' 而非 NULL)
|
||||
recs2 = await sor.sqlExe(
|
||||
"SELECT id FROM product_category WHERE name=${n}$ AND org_id=${o}$ LIMIT 1",
|
||||
{"n": _LLM_PRODUCT_ROOT_NAME, "o": org_id})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
if recs2:
|
||||
parent_cat = getattr(recs2[0], "id", "") or _LLM_ROOT_CAT_ID
|
||||
except Exception as e:
|
||||
logger.warning("_sync_model_products 父类别解析失败(用默认根): %s", e)
|
||||
|
||||
try:
|
||||
result = await import_fn(
|
||||
resource_module="pipeline_llm", org_id=org_id,
|
||||
parent_category_id=parent_cat, user_id="system")
|
||||
except Exception as e:
|
||||
return False, "自动产品映射调用失败(模型已注册,请手动在产品管理导入产线模型):%s" % repr(e)[:150]
|
||||
if not result or not result.get("success"):
|
||||
err = (result or {}).get("error", "导入无返回") if isinstance(result, dict) else "导入无返回"
|
||||
return False, "自动产品映射未成功(模型已注册,请手动导入):%s" % str(err)[:150]
|
||||
return True, "自动产品映射完成:%s" % str((result or {}).get("message", ""))[:150]
|
||||
|
||||
|
||||
async def _h_apply_llm_config(sor, params, ctx):
|
||||
"""按提取的规格写库:供应商(复用/新建)+ 适配模板 + 模型。
|
||||
|
||||
@ -1123,6 +1178,10 @@ async def _h_apply_llm_config(sor, params, ctx):
|
||||
except Exception as e:
|
||||
skill_notes.append("%s: 配套技能生成失败(%s)——完备性判断将按能力语义降级"
|
||||
% (vmid, str(e)[:80]))
|
||||
# 6. 自动产品映射(2026-09-08 用户需求:添加模型时如有产品模块自动做产品映射)。
|
||||
# 根治记账 failed「模型未映射到产品」——不靠人工事后补。产品模块未装则
|
||||
# 跳过不阻断(模型注册已成功);映射幂等(已映射跳过+自愈其他漏映射模型)。
|
||||
prod_ok, prod_note = await _sync_model_products(sor, org_id="0")
|
||||
return json.dumps({
|
||||
"vendor": vendor_action, "profiles": profile_ids,
|
||||
"models_created": created, "models_updated": updated, "models_skipped": skipped,
|
||||
@ -1131,6 +1190,7 @@ async def _h_apply_llm_config(sor, params, ctx):
|
||||
"template_notes": tpl_notes,
|
||||
"account_notes": account_notes,
|
||||
"skill_notes": skill_notes,
|
||||
"product_mapping": {"ok": prod_ok, "note": prod_note},
|
||||
"runtime_note": rt_note,
|
||||
"media_audit": audit_note,
|
||||
}, ensure_ascii=False)
|
||||
@ -2385,7 +2445,9 @@ async def _h_check_model_accounting(sor, params, ctx):
|
||||
item["verdict"] = "记账失败"
|
||||
item["reason"] = (row.get("note") or "")[:200]
|
||||
item["hint"] = ("常见处置:模型未挂ppid→apply_model_pricing;"
|
||||
"模型未映射产品→产品管理导入产线模型;"
|
||||
"模型未映射产品→apply_llm_config 已自动映射(2026-09-08),"
|
||||
"仍报未映射说明自动映射失败(看 apply 返回 product_mapping.note,"
|
||||
"多为产品模块未加载),重跑一次 apply 或告知用户;"
|
||||
"定价无匹配档位→核对usages维度值与定价YAML是否一致")
|
||||
elif st == "created":
|
||||
# 2026-09-06 用户定夺:只有 status='SUCCEEDED' 的行才写 accounting_status,
|
||||
@ -2711,7 +2773,9 @@ PLATFORM_PROMPT = """
|
||||
- failed → 按 reason/hint 处置;需要核实库内数据(产品映射/定价挂接/流水明细)
|
||||
一律用 `db_query` 只读查询,**禁止用 run_command 手搓连库脚本**(沙箱 /tmp 不跨
|
||||
命令持久、平台目录只读、输出双截断——手搓必陷多轮试错)。
|
||||
未映射产品→告知用户在产品管理导入产线模型(人工步骤,如实转告即止,不要自行深挖)
|
||||
产品映射由 apply_llm_config 自动完成(2026-09-08 起)——若仍报「未映射到产品」,
|
||||
回看 apply 返回的 product_mapping.note(多为产品模块未加载),重跑一次
|
||||
apply_llm_config(幂等)触发自动映射,仍失败才如实告知用户。
|
||||
9. 汇报:配置/定价/测试/记账四段结果 + 出处 URL + 遗留事项(如模板需人工核对项)。
|
||||
用户发现问题后按其说明修改,再重新走对应环节(全链幂等,重跑安全)。
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user