From a06e7c6e229eb51eaefd1f45aa81cfc0c094b75f Mon Sep 17 00:00:00 2001 From: yumoqing Date: Wed, 2 Sep 2026 15:07:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(agent=5Fplatform):=20=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E5=86=85=E9=83=A8=E5=8A=A9=E6=89=8B=E5=85=A5=E5=8F=A3=E9=A1=B5?= =?UTF-8?q?+=E5=86=85=E9=83=A8agent=E6=8A=80=E8=83=BD=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - agent_platform/index.ui: pipeline_id=platform_general会话入口 - skills: platform-architecture(平台架构地图) + model-auto-config(文档→配置工作流) --- .../common/model-auto-config/SKILL.md | 42 ++++++++++++ .../common/platform-architecture/SKILL.md | 50 ++++++++++++++ wwwroot/agent_platform/index.ui | 65 +++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 skills_library/pipelines/platform_general/common/model-auto-config/SKILL.md create mode 100644 skills_library/pipelines/platform_general/common/platform-architecture/SKILL.md create mode 100644 wwwroot/agent_platform/index.ui diff --git a/skills_library/pipelines/platform_general/common/model-auto-config/SKILL.md b/skills_library/pipelines/platform_general/common/model-auto-config/SKILL.md new file mode 100644 index 0000000..5599157 --- /dev/null +++ b/skills_library/pipelines/platform_general/common/model-auto-config/SKILL.md @@ -0,0 +1,42 @@ +--- +name: model-auto-config +description: 通读模型API文档自动生成模型治理配置(供应商/端点/适配模板/模型/定价)。内部agent收到文档URL配置模型时必读并严格执行。 +capability: model_auto_config +tools: [fetch_model_doc, extract_llm_api_spec, apply_llm_config, platform_llm_status] +--- + +# 模型自动配置(从 API 文档到落库) + +内部 agent 的核心能力:用户给一个供应商的模型 API 文档(或定价文档)URL, +自动完成模型治理全套配置。**定价只允许来自文档原文,禁止编造。** + +## 工作流(严格按序) + +1. **抓取**:`fetch_model_doc(url)` → 纯文本。失败/内容不足如实说明,不凭记忆编。 +2. **提取**:`extract_llm_api_spec(doc_text)` → 结构化规格。重点核对: + - `endpoints[].base_url / region`(domestic 国内 / international 国际) + - `protocol`:能走 `/chat/completions` 的一律 `openai_compat` + - `models[].price_*`:单位统一**元/千tokens**。文档给「元/百万」必须 ÷1000,保留6位小数 + - `models[].cost_*`:供应商成本,未知时与 price 相同 +3. **确认**:把端点、协议、每个模型的定价摘要给用户确认后再落库。 +4. **落库**:`apply_llm_config(spec)`(幂等:供应商按名复用、模型按 + (vendor, vendor_model_id) 复用——已存在只更新定价,不重复建)。 + +## 硬规则 + +- **定价真实性**:文档没写价格的模型 → 价格填 `null` 并在 description 注明,绝不编数字。 +- **单位换算**:元/百万tokens ÷ 1000 = 元/千tokens。 +- **缓存价**:支持 context caching 的,缓存价约 = 输入价 × 0.2(以文档为准)。 +- **thinking 模式**:开源模型思考/非思考输出价不同且平台计费时无法区分 → 取较高(思考)价兜底,并在 description 注明。 +- **协议限制**:非 `openai_compat` 的模型,模板会存档但运行时暂不可被产线调用, + `apply` 返回的 `runtime_note` 必须如实转告用户。 +- **端点去重**:同供应商已有端点不重复添加(apply 内部已合并,确认时留意新增数)。 + +## 定价示例(换算) + +文档:「输入 2 元/百万tokens,输出 6 元/百万tokens」 +→ price_input = 0.002,price_output = 0.006(元/千tokens)。 + +## 验证 + +配置完成后调 `platform_llm_status` 复核模型/定价/供应商,把结果摘要回给用户。 diff --git a/skills_library/pipelines/platform_general/common/platform-architecture/SKILL.md b/skills_library/pipelines/platform_general/common/platform-architecture/SKILL.md new file mode 100644 index 0000000..7f8b439 --- /dev/null +++ b/skills_library/pipelines/platform_general/common/platform-architecture/SKILL.md @@ -0,0 +1,50 @@ +--- +name: platform-architecture +description: 产线平台架构总览——模块地图、表前缀、运行时进程、部署目录。内部agent回答平台问题/排障前必读。 +capability: platform_knowledge +--- + +# 产线平台架构(内部 agent 必读) + +## 模块地图(代码仓库 → 职责) + +| 仓库 | 包名 | 职责 | +|---|---|---| +| pipeline-core | pipeline_core | 会话 agent 内核:能力包注册表/技能加载器/记忆/工具注册/上传 | +| pipeline-service | pipeline_service | 执行引擎:任务链/角色 agent/PM-QC poller/治理/内部 agent(platform_ability) | +| pipeline-llm | pipeline_llm | 模型治理:供应商/端点/账号/适配模板/模型目录/定价/双维度记账/限流冷却 | +| pipeline-bidding | pipeline_bidding | 投标产线(解析→QC→章节→合成→评分) | +| pipeline-opportunity | pipeline_opportunity | 商机产线 | +| pipeline-sdlc | pipeline_sdlc | 开发产线前端(项目/迭代/任务/交付件页面) | +| pipeline-ops / pipeline-dist / pipeline-task | — | 运维/分销/任务中心 | +| pipeline-app | — | 宿主应用:主菜单/菜单权限/构建脚本 | + +## 关键约定 + +- 表前缀:模型治理 `llm_*`;执行引擎 `sd_*`(projects/tasks/bugs/iterations)、`pipeline_tasks`、`pipeline_human_tasks` +- 技能库:`skills_library/all`(全局)+ `pipelines/{pipeline_id}/common|roles/{role}`;部署期 build.sh 拷到 `skills/` +- 能力包:`pipeline_core.ability.register_ability`,import 即注册;会话按 `pipeline_id` 动态挂载 +- agent 调用 LLM 走内部代理:短期 token(plk-)当 api_key,真 key 只在进程内 +- 数据库:sqlor 占位符用 `${param}$`(不是 %s);纯 SELECT 后必须显式 COMMIT(MDL 锁) + +## 运行时进程 + +单进程 aiohttp(ahserver),内部启动 6 个 poller: +role(角色执行)/ pm(审核复盘)/ qc(门禁)/ failed(失败处理)/ bug(缺陷流转)/ bid(投标对账)。 +暂停项目(status='paused')在所有 poller 中零消耗(含 failed/bug,2026-09-02 修复)。 + +## 模型治理五件套(记忆版) + +1. **供应商**(llm_vendor):协议 + 端点目录(base_url/region/timeout,全球端点配一次) +2. **账号**(llm_account):选端点 + 独立充值记账,api_key 单层 AES 加密 +3. **适配模板**(llm_api_profile):按协议×能力去重(request/response/param_schema) +4. **模型目录**(llm_model):vendor_model_id + 能力 + 模板引用 + 四价(price_in/out、cost_in/out,元/千tokens) +5. **客户配置**(llm_org_policy):主备模型 + 端点偏好(any/prefer/must × domestic/intl) + +限流窗口与记账按(账号,端点)对;多账号轮转 + 主备容错。 + +## 部署 + +- 测试:pipeline@pipeline.opencomputing.cn:/d/pipeline/pipeline-app,端口 9090 +- 生产:doit@doit.opencomputing.cn:/d/doit/pipeline-app,域名 doit.opencomputing.cn +- 部署 = git pull + pip install(pipeline-service 非 editable)+ 清 __pycache__ + restart-pipeline.sh diff --git a/wwwroot/agent_platform/index.ui b/wwwroot/agent_platform/index.ui new file mode 100644 index 0000000..fb837d5 --- /dev/null +++ b/wwwroot/agent_platform/index.ui @@ -0,0 +1,65 @@ +{ + "widgettype": "VBox", + "options": {"width": "100%", "height": "100%", "padding": "0"}, + "subwidgets": [ + { + "widgettype": "HBox", + "options": {"width": "100%", "alignItems": "center", "padding": "16px 24px 8px 24px", "cheight": 6, "gap": "12px"}, + "subwidgets": [ + {"widgettype": "Title2", "options": {"text": "平台内部助手"}}, + {"widgettype": "Text", "options": {"text": "平台运维/管理 agent · 模型自动配置 · 仅管理员可用", "cfontsize": 0.9, "color": "#94a3b8"}}, + {"widgettype": "Filler"}, + { + "widgettype": "Button", + "id": "new_session_btn", + "options": {"label": "+ 新建会话", "css": "small"}, + "binds": [{ + "wid": "self", + "event": "click", + "actiontype": "script", + "target": "self", + "script": "var tp=bricks.getWidgetById('platform_tabs',bricks.app);if(!tp)return;var sid='p'+Date.now()+'_'+Math.floor(Math.random()*100000);var n=tp.opts.items.length+1;tp.open_tab({name:'psession_'+sid,label:'会话 '+n,removable:true,content:{widgettype:'VBox',options:{css:'filler',width:'100%',height:'100%'},subwidgets:[{widgettype:'urlwidget',options:{url:'/pipeline_core/api/agent_menus.dspy?session_id='+sid+'&pipeline_id=platform_general',method:'GET'}},{widgettype:'AgentIO',options:{css:'filler',margin:'0 24px 24px 24px',url:'/pipeline_core/api/agent_chat.dspy?session_id='+sid+'&pipeline_id=platform_general',model_dataurl:'/pipeline_core/api/agent_model_options.dspy?session_id='+sid+'&pipeline_id=platform_general',model_cwidth:14,placeholder:'例如:通读这份文档并配置模型 <文档URL>...'}}]}});" + }] + } + ] + }, + { + "widgettype": "TabPanel", + "id": "platform_tabs", + "options": { + "css": "filler", + "width": "100%", + "height": "100%", + "tab_pos": "top", + "items": [ + { + "name": "platform_default", + "label": "会话 1", + "removable": false, + "content": { + "widgettype": "VBox", + "options": {"css": "filler", "width": "100%", "height": "100%"}, + "subwidgets": [ + { + "widgettype": "urlwidget", + "options": {"url": "{{entire_url('/pipeline_core/api/agent_menus.dspy')}}?session_id=default_platform_general&pipeline_id=platform_general", "method": "GET"} + }, + { + "widgettype": "AgentIO", + "options": { + "css": "filler", + "margin": "0 24px 24px 24px", + "url": "/pipeline_core/api/agent_chat.dspy?session_id=default_platform_general&pipeline_id=platform_general", + "model_dataurl": "/pipeline_core/api/agent_model_options.dspy?session_id=default_platform_general&pipeline_id=platform_general", + "model_cwidth": 14, + "placeholder": "例如:通读这份文档并配置模型 <文档URL>..." + } + } + ] + } + } + ] + } + } + ] +}