From f965e4b4d68b3279d48b2ea5aa25b71114e2c54b Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 4 Sep 2026 21:02:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(llm=5Fmodel):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=BB=B7=E6=A0=BC/=E6=88=90=E6=9C=AC=E5=9B=9B=E5=AD=97?= =?UTF-8?q?=E6=AE=B5(price/cost=20input/output)=E2=80=94=E2=80=94=E5=AE=9A?= =?UTF-8?q?=E4=BB=B7=E7=BB=9F=E4=B8=80=E8=B5=B0ppid=E5=AE=9A=E4=BB=B7?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0,=E8=AE=B0=E8=B4=A6=E6=94=B9=E8=B7=AF?= =?UTF-8?q?=E5=90=8E=E4=B8=BA=E6=AD=BB=E5=BA=93=E5=AD=98;=E7=BB=93?= =?UTF-8?q?=E7=AE=97cost=E6=81=920,=E5=B1=95=E7=A4=BA/=E5=88=97=E8=A1=A8/?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=90=8C=E6=AD=A5=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/llm_model.json | 32 ------------------------------- mysql.ddl.sql | 4 ---- pipeline_llm/gateway.py | 9 +++++---- pipeline_llm/inference.py | 6 ++---- pipeline_llm/product_interface.py | 13 ++++++------- scripts/migrate_legacy_llm.py | 2 -- wwwroot/api/v1/models.dspy | 2 -- 7 files changed, 13 insertions(+), 55 deletions(-) diff --git a/models/llm_model.json b/models/llm_model.json index d69ee4e..6b35217 100644 --- a/models/llm_model.json +++ b/models/llm_model.json @@ -76,38 +76,6 @@ "type": "str", "length": 32 }, - { - "name": "price_input", - "title": "输入单价(元/千token)", - "type": "float", - "length": 12, - "dec": 6, - "default": "0" - }, - { - "name": "price_output", - "title": "输出单价(元/千token)", - "type": "float", - "length": 12, - "dec": 6, - "default": "0" - }, - { - "name": "cost_input", - "title": "输入成本(元/千token)", - "type": "float", - "length": 12, - "dec": 6, - "default": "0" - }, - { - "name": "cost_output", - "title": "输出成本(元/千token)", - "type": "float", - "length": 12, - "dec": 6, - "default": "0" - }, { "name": "default_params", "title": "默认参数(JSON)", diff --git a/mysql.ddl.sql b/mysql.ddl.sql index 6823366..65780ea 100644 --- a/mysql.ddl.sql +++ b/mysql.ddl.sql @@ -43,10 +43,6 @@ CREATE TABLE IF NOT EXISTS llm_model ( `profile_id` varchar(32) comment '适配模板ID', `query_profile_ids` text comment '后续步骤模板链(JSON数组,异步模型提交后顺序执行:查询/下载)', `ppid` varchar(32) comment '定价项目ID(pricing_program)', - `price_input` decimal(12,6) NOT NULL DEFAULT 0 comment '输入单价(元/千token)', - `price_output` decimal(12,6) NOT NULL DEFAULT 0 comment '输出单价(元/千token)', - `cost_input` decimal(12,6) NOT NULL DEFAULT 0 comment '输入成本(元/千token)', - `cost_output` decimal(12,6) NOT NULL DEFAULT 0 comment '输出成本(元/千token)', `default_params` text comment '默认参数(JSON)', `status` varchar(20) NOT NULL DEFAULT 'active' comment '状态', `description` text comment '描述', diff --git a/pipeline_llm/gateway.py b/pipeline_llm/gateway.py index 4fd3815..5e13b80 100644 --- a/pipeline_llm/gateway.py +++ b/pipeline_llm/gateway.py @@ -199,7 +199,7 @@ async def _model_chain(sor, org_id: str, model_name: str, purpose: str = ''): for mid in chain_ids: recs = await sor.sqlExe( "SELECT id, name, vendor_id, vendor_model_id, capability, default_params, " - "price_input, price_output, cost_input, cost_output, ppid, org_id " + "ppid, org_id " "FROM llm_model WHERE id=${i}$ AND status='active' LIMIT 1", {"i": mid}) await sor.sqlExe("COMMIT", {}) if recs: @@ -496,9 +496,10 @@ async def govern_settle(ctx: dict, ok_call: bool, req_tokens: int = 0, resp_toke db, dbname = _get_db() try: model = ctx.get('model_row') or {} - cost_in = _fnum(model.get('cost_input')) - cost_out = _fnum(model.get('cost_output')) - cost = req_tokens / 1000.0 * cost_in + resp_tokens / 1000.0 * cost_out + # 2026-09-04:模型表不再存单价/成本四字段——成本与售价统一走 ppid 定价引擎, + # 出账由异步记账循环(accounting.py)经产品层计算;此处 cost 恒 0, + # 供应商账号余额不再按调用扣减(真实成本以定价引擎结算为准)。 + cost = 0.0 policy_org = ctx.get('policy_org_id') or '' caller_org = ctx.get('org_id') or '' # owner 模型 = 生效策略是平台('0') 且调用方不是平台自己 diff --git a/pipeline_llm/inference.py b/pipeline_llm/inference.py index 27598af..2c2fcab 100644 --- a/pipeline_llm/inference.py +++ b/pipeline_llm/inference.py @@ -371,7 +371,7 @@ async def list_models(org_id, catelogid='', limit=200): """按能力分类列模型(对齐 llmage v1/models 的分类方式)。 catelogid 空 = 全部能力。返回 [{'id','name','model_id','capability', - 'vendor','status','price_input','price_output'}]。 + 'vendor','status'}]。 机构未配策略(无可用模型)返回空列表,由调用方决定是否提示。 """ from .gateway import _active_policy_org, _get_db @@ -381,7 +381,7 @@ async def list_models(org_id, catelogid='', limit=200): if not await _active_policy_org(sor, org_id or ''): return rows sql = ("SELECT m.id, m.name, m.vendor_model_id, m.capability, m.status, " - "m.price_input, m.price_output, v.name AS vendor_name " + "v.name AS vendor_name " "FROM llm_model m LEFT JOIN llm_vendor v ON v.id=m.vendor_id " "WHERE m.status='active'") params = {} @@ -400,8 +400,6 @@ async def list_models(org_id, catelogid='', limit=200): 'capability': getattr(r, 'capability', '') or 't2t', 'vendor': getattr(r, 'vendor_name', '') or '', 'status': getattr(r, 'status', ''), - 'price_input': float(_fnum(getattr(r, 'price_input', 0))), - 'price_output': float(_fnum(getattr(r, 'price_output', 0))), }) return rows diff --git a/pipeline_llm/product_interface.py b/pipeline_llm/product_interface.py index b1ac7d5..8c8a49d 100644 --- a/pipeline_llm/product_interface.py +++ b/pipeline_llm/product_interface.py @@ -26,7 +26,7 @@ async def _resolve_model(resource_ref_id): async with get_sor_context(env, _MODULE_NAME) as sor: recs = await sor.sqlExe( "SELECT id, name, vendor_model_id, capability, status, ppid, org_id, " - "price_input, price_output, cost_input, cost_output, description " + "description " "FROM llm_model WHERE id=${i}$ LIMIT 1", {"i": resource_ref_id}) await sor.sqlExe("COMMIT", {}) if not recs: @@ -35,18 +35,17 @@ async def _resolve_model(resource_ref_id): async def get_product_display(resource_ref_id): - """展示定价信息。""" + """展示定价信息。2026-09-04 起模型表不存单价,定价统一走 ppid 定价引擎。""" m, err = await _resolve_model(resource_ref_id) if err: return {'success': False, 'message': err} - pi = float(m.get('price_input') or 0) - po = float(m.get('price_output') or 0) - pricing_text = '输入 %.4f 元/千token,输出 %.4f 元/千token' % (pi, po) if (pi or po) else '未定价' + ppid = m.get('ppid') or '' + pricing_text = '按定价方案计费(ppid=%s)' % ppid if ppid else '未挂定价方案' return { 'success': True, 'pricing_text': pricing_text, 'pricing_detail': { - 'price_input': pi, 'price_output': po, + 'ppid': ppid, 'capability': m.get('capability') or 't2t', 'model_id': m.get('vendor_model_id') or m.get('name', ''), }, @@ -156,7 +155,7 @@ async def load_product_category_product(parent_category_id): async with get_sor_context(env, _MODULE_NAME) as sor: models = await sor.sqlExe( "SELECT id, name, vendor_model_id, capability, status, org_id, description, " - "ppid, price_input, price_output FROM llm_model " + "ppid FROM llm_model " "WHERE status='active' ORDER BY capability, name", {}) await sor.sqlExe("COMMIT", {}) caps = await sor.sqlExe( diff --git a/scripts/migrate_legacy_llm.py b/scripts/migrate_legacy_llm.py index 5d1f72f..4be2603 100644 --- a/scripts/migrate_legacy_llm.py +++ b/scripts/migrate_legacy_llm.py @@ -160,8 +160,6 @@ async def main(dry=False): 'capability': cap, 'sync_mode': 'sync', 'profile_id': '', 'query_profile_ids': '', 'ppid': '', - 'price_input': 0, 'price_output': 0, - 'cost_input': 0, 'cost_output': 0, 'default_params': '', 'status': 'active', 'description': '由旧 llm 表迁移生成', 'org_id': '0', }) diff --git a/wwwroot/api/v1/models.dspy b/wwwroot/api/v1/models.dspy index 1e6a81b..d6183a0 100644 --- a/wwwroot/api/v1/models.dspy +++ b/wwwroot/api/v1/models.dspy @@ -39,7 +39,5 @@ for r in rows: "name": r.get('name', ''), "catelogid": r.get('capability', ''), "vendor": r.get('vendor', ''), - "price_input": r.get('price_input', 0), - "price_output": r.get('price_output', 0), }) return json.dumps(out, ensure_ascii=False)