返回 Skill 列表
extension
分类: 开发与工程无需 API Key

华为 ModelEngine Nexent 智能体平台集成技能

覆盖华为开源 ModelEngine Nexent 智能体平台「北向调用 / 流式输出 / 远程操控 / MCP 接入 / 加载原理 / 环境探查」六大方向的端到端集成技能,附一键管理 CLI。

person作者: dmkx01hubModelScope

Nexent 智能体集成(六大方向)

配套平台版本:2.5.0(接口/字段/端口均以该版本为准;跨版本使用请先以各服务 /openapi.json 实测校准)。

配套技能:智能体 UI 设计与真机测试 → agent-ui-design-and-testing;技能质量检查 → skill-qc

整合华为开源 ModelEngine Nexent 智能体平台的全部对接经验,分为六大方向:

| 方向 | 内容 | 参考文档 | |---|---|---| | 方向一:北向接口调用 | 从外部 Web 系统调用智能体:agent 发现、POST /nb/v1/chat/run、SSE 流式、Bearer 鉴权、conversation_id 追问、附件/文件上传(/nb/v1/chat/attachments/upload + 知识库文件上传) | references/01-northbound-api.md | | 方向二:流式输出经验 | SSE 事件协议本质(thinking 增量/final_answer 一次性)、conversation_id 响应头、协议层踩坑(空请求体 422/conversation_id 误渲染)、提示词契约;前端呈现(三层架构/滚动三态/图表 init/弹窗解耦/真实浏览器验证)详见 agent-ui-design-and-testing 技能 streaming-ui.md | references/02-streaming-guide.md + agent-ui-design-and-testing/streaming-ui.md | | 方向三:远程操控提示词与发布 | 管理 API(登录 session 鉴权、agent_id 查询、search_info/update、技能管理 API/api/skills 创建/上传/更新/scan_skill/nl2skill + 脚本型技能 run_skill_script 执行机制)、版本 publish 递增与命名规则) | references/03-admin-api.md + scripts/nexent_agent.py | | 方向四:MCP 工具接入与联调 | API 转 MCP(/tool/openapi_service)、工具扫描/绑定、MCP 仓库注册(/api/mcp/add)、接入已有远程 MCP 服务器(healthcheck/tools/refresh-tools)、config_json 补配置、SSE 协议探测、OpenAPI 对接与裁剪、端口速查 | references/04-mcp.md | | 方向五:加载与调用原理 | 提示词草稿/发布两态、技能渐进式加载(read_skill_md 命中后读全文)、工具绑定与 thinking 可见调用、技能命中验证方法论、技能使用规则 prompt 模板 | references/05-prompt-skill-tool-loading.md | | 方向六:环境探查 | 新建智能体前的全量环境摸底(网络/鉴权/模型/知识库/智能体现状/技能/MCP/工具),更新智能体时的按需探查(仅查相关维度) | references/06-environment-probe.md |

目录

🔎 接口探查方法论(铁律:文档优先 → 源码兜底)

遇到接口问题,先查官方 API 文档,调试不通再解析源码——不要一上来就翻 GitHub。

位置速查:源码仓库 https://github.com/ModelEngine-Group/nexent(main);运行环境 API 文档 = 各服务端口 /openapi.json(示例部署 3000/5010/5013,端口由部署决定,勿假设默认);前端端点常量 frontend/services/api.ts(API_ENDPOINTS)+ frontend/const/*.ts;后端路由 backend/apps/*.py、模型 backend/consts/model.py、实现 backend/services/*.py

  1. 文档优先:① 平台官方文档/帮助 → ② 环境内 /openapi.json(最权威的本环境接口清单)→ ③ 前端 frontend/services/api.tsAPI_ENDPOINTS(前端真实调用 URL)→ ④ 仓库 docs/
  2. 源码兜底(文档缺失/过时/与实际不符时):backend/apps/*.py 路由(确认真实路径与 prefix)→ backend/consts/model.py(请求/响应模型字段)→ backend/services/*.py(行为实现,如 update 注释 "agent_id is None → create")→ frontend/services/*.ts(前端怎么调)
  3. GitHub 拉取用 api.github.com trees/contents API(秒级),不下载整包 zip

本技能中标注「源码确认」的结论均为此流程的实战产出,可直接复用。详见 references/03-admin-api.md「接口探查方法论」。

⚠️ 两套鉴权(最易混淆,务必区分)

| 场景 | 鉴权方式 | 用途 | |---|---|---| | 北向接口(方向一) | Authorization: Bearer <北向 API Key> | 调用智能体对话(chat/run、agents 列表) | | 管理接口(方向三) | Authorization: Bearer <登录 session JWT>北向 API Key 无效!) | 查询/更新提示词、发布版本 |

管理接口的 JWT 获取:POST {BASE}/api/user/signin body {"email","password"},从响应 Set-Cookie: nexent_access_token=<JWT> 提取。

🔐 连接凭证追问铁律(未提供必须显式追问,禁止猜测)

调用任何 Nexent 接口前,以下四项连接凭证必须齐备;只要用户未主动提供,就必须用 AskUserQuestion 显式追问——绝不允许自己猜、不允许用默认值兜底、不允许拿记忆/历史会话里的旧凭据复用

| 凭证 | 用途 | 追问要点 | |---|---|---| | ① Nexent 地址(base URL) | 管理门户与北向地址(端口由部署决定,无固定默认) | 管理 API 完整地址(实测 3000);北向 API 完整地址(实测 5013)。两者可能不同,分别确认 | | ② 登录用户名(邮箱或账号) | 管理 POST /api/user/signin 换 JWT | 部署方提供的登录用户名/邮箱,勿假设是固定账号 | | ③ 登录密码 | 同上 | 走交互输入或环境变量 NEXENT_PASSWORD禁止硬编码/写入代码文档 | | ④ 北向 API Key | 北向 Authorization: Bearer nexent-<key> | 形如 nexent-xxxx,由部署方提供;与管理 JWT 不同体系,不能互用 |

红线

  • ❌ 禁止猜地址(如"实测是 3000 那就用 3000")——端口由部署决定,必须问。
  • ❌ 禁止猜用户名/密码/Key,禁止套用记忆里别的环境的凭据。
  • ❌ 禁止"先用默认值跑通再说"——拿不到凭证先追问,不要擅自发起调用。
  • ✅ 四项齐了再动手;任一项缺失 → 先 AskUserQuestion 追问,拿到后再继续。
  • 详细 Required Values 与获取方式见 references/03-admin-api.md

方向一:北向接口调用(Quick Start)

# 1. 发现智能体(可选)
# ⚠️ 北向 API 与管理门户端口不同:实测环境 管理门户=:3000、北向=:5013(均为示例值,具体端口由你的部署决定)
#    {NEXENT_BASE_URL} 此处应填北向 base(如 http://<host>:5013), 不是管理门户 3000(3000 的 /nb/v1/* 是前端门户会 404/307)
curl -s "{NEXENT_NORTHBOUND_BASE_URL}/nb/v1/agents" -H "Authorization: Bearer <API_KEY>"

# 2. 发起对话(SSE 流式响应)
curl -s -N -X POST "{NEXENT_BASE_URL}/nb/v1/chat/run" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{"agent_name":"<agentName>","query":"<用户问题>"}'

# 3. 追问: 从响应头取 conversation_id, 传回即可延续会话
curl -s -N -X POST "{NEXENT_BASE_URL}/nb/v1/chat/run" \
  -H "Authorization: Bearer <API_KEY>" -H "Content-Type: application/json" \
  -d '{"agent_name":"<agentName>","conversation_id":"<上轮id>","query":"追问内容"}'

完整协议、端点、错误处理见 references/01-northbound-api.md

💡 chat/run 报 "Agent execution failed" 先自查配置(慎判平台层):model_ids 非空 / 工具数 ≤ 上下文预算 / 工具 usage 在 mcp/list 存在 / 未误触内联代码解释器 / 已 publish——多数正常仅自己报错 = 自己配置问题(详见 01「排障」)。 🚨 模型写代码被拦两类错误Code execution failed ≈ 单步失败可自愈(智能体重试后仍产 final_answer,前端勿一收 error 就中断);Forbidden function evaluation(模型把 tool 当 Python 函数调用)≈ 硬拒收不可恢复。改 prompt:勿加"工具调用由平台自动接管"正向指引(轻量模型误读→step1 就 stop),回退到端到端通过的 prompt 最稳(详见 01「两类错误」)。

方向二:流式输出经验(要点速记)

  • thinking 事件:逐字增量 → 前端须累积拼接(不逐帧取末段,否则 1-2 字闪现);对增量做匹配/归类同样必须累积整段再判(逐词帧不含完整关键词,单帧匹配必失败)
  • final_answer 事件:一次性完整(非增量)→ 到达后整体处理
  • ⚠️ SSE 只有 data: 行、无 event: 行——按 data.type 分流(不是 event: 事件名;默认名 "message" 会把 tool/execution_logs 当答案渲染);仅 thinking 两类 + final_answer 累积/渲染,工具类/元信息事件不渲染(详见 02 §1)
  • conversation_id:在响应头(非 SSE 事件体),只读不渲染进答案
  • 协议层踩坑:空请求体 → 422 → [object Object](对象展开丢键);conversation_id 误渲染进答案(重复分支)
  • 前端呈现(三层架构/滚动三态/图表 init 时机/关闭弹窗不中断/真实浏览器验证)详见 agent-ui-design-and-testing 技能 streaming-ui.md——本技能只负责协议对不对,渲染对不对由 UI 设计与测试技能覆盖
  • ⚠️ 铁律:前端交付必须真实浏览器渲染验证(JSON 正确 ≠ 渲染正确)
  • 追问/延续轮输出契约conversation_id 续接 ≠ 自动"只答当前问题"——结构化模板型智能体须在 constraint_prompt 加"首轮 vs 延续轮"分支(延续轮仅聚焦新问题、不重复 N 小节模板,仅明确要求重出时完整输出);追问勿重复携带 attachments(否则重新触发多模态工具调用,慢+重复分析);few_shots 放一条追问示例。详见 references/02-streaming-guide.md §5.3
  • thinking 原文 ≠ 面向用户文本thinking 事件增量是模型原文,live 模式可能混有工具调用独白(工具名+参数原文,如 analyze_image(/image_urls_list=/S3 URL)——面向最终用户(C 端)必须净化:把思考 token 映射为预设干净步骤,原文只留开发者视图。协议层结论见 02-streaming-guide.md §5.4,渲染层实现见 agent-ui-design-and-testing streaming-ui.md §1.1
  • error 事件可能是"过程性失败"≠ 运行必然失败:模型偶发写代码被平台拦(Code execution failed)等单步失败后智能体自动重试继续,最终仍产出 final_answer。前端不能一收 error 就中断——只记录、继续收流,以"是否到达 final_answer"为成功标准;流结束无结果且有 error 才报错/自动重试(Code execution failed / Agent execution failed 类)。协议层见 02-streaming-guide.md §4,渲染层实现见 agent-ui-design-and-testing streaming-ui.md §5.2
  • 🚨 模型偶发退化 final_answer:轻量模型(DeepSeek-V4-Flash 等)约 1/4 概率只调 1 工具就提前 stop,把 final_answer 输出成思考片段而非约定的结构化 JSON,且不报错。前端在"流正常结束但既无 final_answer 也无 error"分支自动重试一次retryLeft 递减,0 即停,绝不递归/无限重试),仍退化则显示"未获得有效回答";根治须切更强模型或优化 prompt。协议层 02 §4,渲染层 agent-ui 场景 G / §5.2
  • 🚨 final_answer 长 JSON 被平台截断(3600~4800 字符、Expecting ',' delimiter):前端按括号实际深度配平恢复(跳过字符串内括号),不靠 prompt 约束长度;兜底见 agent-ui bug-patterns.md §18.1
  • 提示词引导工具 = 映射查表,不写枚举清单(§5.5):枚举必然漏新增工具(实测漏 generate_parallel_chart);参数枚举唯一来源 = 工具描述(MCP docstring)——改 docstring 重连即生效,prompt 不重复维护(实测 group_by docstring 已 7 项、prompt 旧 5 项 = 漂移实证);模型选错工具第一顺位查 tools[].description 措辞(详见 01 排障 + 02 §5.5)
  • 完整协议/契约层踩坑与跨技能索引见 references/02-streaming-guide.md

方向三:远程操控提示词与发布(要点速记)

使用前先向用户追问基础信息(与方向一相同原则,不假设):① 管理 API base URL(部署方提供的完整地址,端口由部署决定、无固定默认值,实测环境为 http://<host>:3000 但不要假设 3000;同理北向端口实测环境为 5013);② 登录用户名(邮箱或账号)/密码(从部署方获取,交互输入或环境变量注入,禁止硬编码);③ 北向 API Key(形如 nexent-xxx,调用北向接口时用);④ 当前环境能否直连该管理 API。详见 references/03-admin-api.md 的 Required Values。

⚠️ 铁律(层级绑定):创建前必须先探查;更新涉及新能力必须先按需探查;纯改提示词免探查

  • 🚨 新建智能体:必须先执行方向六全量摸底(Step 1–7),输出探查报告给用户,再问决策再创建。禁止跳过探查直接 create。
  • 更新智能体(涉及新增 MCP/技能/知识库等能力变更):必须先执行方向六按需探查(仅查相关维度),展示候选给用户,再操作。禁止不探查直接 add/bind/publish。
  • 更新智能体(仅改提示词/展示字段):不需要探查,直接 search_info 编辑。
  • 方向三中所有涉及"列候选给用户选"(模型/知识库/MCP/技能列表)的数据来源,均应优先复用方向六探查环节已获取的信息(避免重复拉取)。若探查信息已过期(如会话断开后重连),需重新探查。

⚠️ 铁律:模型/知识库只在【创建】智能体时由用户显式选择;【更新】智能体自动沿用现有配置,不再询问

  • 创建闸门(强制交互):任何 agent create 调用之前,必须 GET /api/model/list 拉列表 → 用 AskUserQuestion 展示给用户 → 拿到显式选择的 model_id 才能继续。禁止硬编码 model_id、禁止取默认值、禁止"先建完再问"。
  • ⚠️ 创建/更新 body 必须用 model_ids: [<id>] 数组——只传 model_id 单数字段会被静默忽略(接口 200 但 search_info 显示 model_ids: [] → agent 运行报 "Agent execution failed");创建后必查 search_info.model_ids 确认非空(实测确认)。
  • 更新自动沿用(不询问)agent update 不询问模型,直接沿用 search_info 返回的 model_ids(如 [<某模型id>])→ update["model_id"] = model_ids[0]update["model_ids"] = model_ids。创建时的选择是"一次性决策",后续迭代不重复打扰用户。
  • 写自动化部署脚本也必须遵守:不要把 create 压成无交互单脚本并硬编码 model_ids——Phase 1 先交互收集(模型/知识库/提示词),Phase 2 才执行。本技能自带 nexent_agent.py create 已内置 input("请选择模型 ID...") 闸门,优先用它而非自写硬编码脚本。
  • 反模式:为图快把部署写成 deploy.py 单脚本、硬编码 deepseek-v4-pro未让用户选模型,事后补救换模型重 publish。根因=软指令被"交付惯性"覆盖、且绕过技能自带交互 CLI。
  • 模型列表:GET /api/model/list(⚠️ 响应含明文 api_key,只取 model_id/display_name/model_type 展示)
  • 知识库列表:GET /api/indices{"indices": ["<index_name哈希>", ...]}(⚠️ 仅返回索引哈希串,本版本管理 API 无任何端点返回知识库可读名称——名称只存在于平台「知识库管理」UI;RAGFlow/AIDP/iData 为外部代理需单独 api_base+api_key。向用户列候选时必须标注"这是索引哈希、名称请到 UI 核对",禁止只甩哈希
  • 挂知识库 = 配置 knowledge_base_search 工具实例的 params 数组中 index_names 元素的 default(⚠️ params 是 param 描述数组非字典;update 后 publish)
  • MCP 接入硬闸门:任何 POST /api/mcp/add(远程 MCP)/ API 转 MCP / 绑定资源(tool/update之前,必须先列候选 MCP(名称/用途/传输/是否需隧道)让用户选,或用 AskUserQuestion 确认 server_url 与目标资源——禁止默认挑一个、禁止硬编码 server_url 直接 add。MCP 接入涉及外部网络可达性决策,本质是用户选择点。
  • 破坏性操作确认闸门:任何 DELETE(删智能体 DELETE /api/agent、删技能 DELETE /api/skills/{name}、删会话 DELETE /api/conversation/{id}、删版本 DELETE /api/agent/{id}/versions/{no}不可逆,执行前必须用 AskUserQuestion 让用户显式确认"删哪个 + 是否确认"——禁止静默/默认删除(即便会话清理有"先建后删+快照对比"规则,删除那步仍需确认)。
# 内置 CLI(自动登录/字段回填/版本递增; 邮箱/密码未提供时交互输入)
# <base_url> 为部署方提供的完整管理 API 地址(端口由部署决定, 示例 3000, 勿假设默认)
python scripts/nexent_agent.py list   <base_url>              # 列全部智能体(name+id)
python scripts/nexent_agent.py show   <base_url> <agent_id>   # 看配置(含提示词)
python scripts/nexent_agent.py create <base_url>              # 新建智能体(★ 先读模型列表让用户选→交互收集提示词→创建→提示publish)
python scripts/nexent_agent.py update <base_url> <agent_id> duty_prompt   # 更新字段(回填其余)
python scripts/nexent_agent.py publish <base_url> <agent_id> [version_name] [release_note] [desc] [--duty=描述智能体如何工作] [--opening=开场白]  # 发布新版本(自动递增); 末尾可同步「展示/描述字段组」
python scripts/nexent_agent.py bind-kb <base_url> <agent_id>  # 挂载知识库(★ 先列 indices 让用户选→更新 knowledge_base_search 实例 index_names→提示publish)

字段职责划分(提示词放对位置!)

| 字段 | 职责 | |---|---| | duty_prompt | 角色定位、核心任务(不要放输出格式要求) | | constraint_prompt | 工具使用规范 + 输出格式要求 | | few_shots_prompt | 示例(few-shot 示例对话,用户可见"示例"字段) |

update 必须回填全部字段(search_info 拉取 → 排除 tools/sub_agent_id_list/skills/model_names/model_ids → 规范化 model_id=enabled_tool_ids=related_agent_ids → 仅改目标字段),否则清空未传字段。

publish 版本规则(创建时确认,更新自动递增)

  • 创建时:初始版本命名规则(如 X.Y 格式、起始版本)由用户确认。
  • 更新时(不询问用户):先读版本列表(version_name + version_no + create_time 一起看)推测规律——update 会自动落一条版本、publish 再落一条(列表末尾可能是"伪最新"),且存在同名重复 → 识别命名规律([前缀]主.次)后延续(同前缀+同主版本,次版本+1)POST /api/agent/{id}/publish body {version_name, release_note, publish_as_a2a:false}(version_no 服务端自动递增);发布后复查去重。禁止只看列表最后一条 / 取全局最大值+1 / 凭记忆硬编码 1. 前缀

⚠️ 发布前必须同步「展示/描述字段组」:面向用户的展示类字段(description/display_name/business_description/duty_prompt/constraint_prompt/greeting_message/example_questions/few_shots_prompt不会随 duty_prompt/技能/MCP 的更新自动变化——每次能力/功能变更须主动刷新,否则平台展示旧描述。字段语义映射与反模式(opening_remarks/greeting/prologue 不存在)见 references/91-field-mapping.md;一键发布命令见下方 CLI(--desc/--business/--opening/--examples/--shots 逐项传)。

完整协议见 references/03-admin-api.md

技能管理 API(远程创建/上传/更新,/api/skills,属管理 API 范畴)

  • POST /api/skills JSON 创建(body: name/description/content/tool_ids/tags…;tool_names 不支持)
  • POST /api/skills/upload multipart 上传创建file=SKILL.md 或 ZIP(frontmatter 需 name/description;ZIP 含 SKILL.md 根或子目录)
  • ⚠️ 脚本型技能(含 scripts/ 的)必须整包 ZIP 上传——只传 SKILL.md 单文件时 scripts/ 不物化,run_skill_script 报 FileNotFound(详见 03)
  • PUT /api/skills/{name}/upload 文件覆盖更新;GET /api/skills/{name}/files 验证物化;GET /api/skills/scan_skill 扫描本地目录刷新 DB(Skill not found 时修复)
  • AI 辅助创建:POST /api/skills/creator/create(nl2skill 异步任务)

方向四:MCP 工具接入与联调(要点速记)

把自有 REST API 变成 Nexent 智能体的 MCP 工具——Nexent 有一键「API 转 MCP」能力(FastMCP.from_openapi())。

端口速查(实测部署示例值,端口由部署决定、无固定默认,勿假设)3000 管理门户(登录拿 JWT)/ 5010 Config API(转换/工具管理主入口)/ 5011 MCP 服务器(SSE,工具运行于此)/ 5013 北向 API(chat/run)/ 5015 MCP 管理 API(内部)。

两个注册渠道,用途不同(最易混淆)

| 渠道 | 接口 | 效果 | |---|---|---| | 原生 MCP 代理(首选,Channel ②) | POST {3000}/api/mcp/add body {name, server_url, enabled, authorization_token?, custom_headers?} | 进 MCP 仓库(mcp_record_t);配合 5010 scan_tool 把远程 MCP 工具扫入 tool_t(source=mcp, usage=服务器名)→ 可绑定智能体;运行时 直连 MCP 服务器ToolCollection.from_mcp,自动带鉴权头) | | OpenAPI 转换(Channel ①) | POST {5010}/tool/openapi_service body {service_name, server_url, openapi_json, headers_template?, force_update?} | 生成 src:mcp 工具,可绑定智能体;不进 MCP 仓库;工具运行在 Nexent 自己的 5011 MCP 服务器(FastMCP.from_openapi 包装) |

选型已有原生 MCP 服务器(SSE/streamable-http)时,一律优先 Channel ②——工具由 MCP 服务器自己提供、运行时直连、鉴权头自动注入(mcp_record 的 authorization_tokenheaders["Authorization"]custom_headers 合并进 mcp_config["headers"]),这才是"原生 MCP 接入"的正路。Channel ① 只在只有 REST API、没有 MCP 服务器时用(API 转 MCP 中转方案)。 ⚠️ 历史教训:曾漏 5010 /tool/scan_tool 一步,误判"原生 MCP 无法绑定"退回 Channel ①——正路是 Channel ② 补上 scan_tool。 ⚠️⚠️ 🚨 自有 REST API 接入:API 转 MCP 必须配合「仓库注册自己的条目」——/tool/openapi_service 转换后,须 POST /api/mcp/add 注册自己条目(server_url=平台 :5011/sse)→ scan_tool → PUT /api/mcp/updateconfig_json漏注册 = 工具 usage 挂到环境已有 MCP 名下(动了环境资源,用户禁止)。完整六步见 04「API-MCP 添加完整教程」。

原生 MCP(Channel ②)绑定完整链路

1. POST {3000}/api/mcp/add   {name, server_url, enabled:true, authorization_token?:"Bearer xxx", custom_headers?}
2. GET  {3000}/api/mcp/list            按 name 取 mcp_id(add 响应无 mcp_id)
3. GET  {3000}/api/mcp/healthcheck?mcp_id=     → status=true(scan_tool 依赖 enabled && status;若记录 `enabled=false` 先 `POST /api/mcp/enable {mcp_id}` 启用,并比对 authorization_token 与服务器侧一致)
4. POST {3000}/api/mcp/refresh-tools?mcp_id=   → 持久化工具名
5. GET  {3000}/api/mcp/tools?mcp_id=           → 实时验证工具可见(可选)
6. GET  {5010}/tool/scan_tool           ★ 关键步骤:把远程 MCP 工具扫入 tool_t(source=mcp, usage=mcp服务器名),生成 tool_id
7. GET  {3000}/api/tool/list            按 origin_name 找 tool_id(source=mcp, usage=服务器名)
8. POST {5010}/tool/update              {tool_id, agent_id, params:{}, enabled:true} → tool_instance 绑定
9. POST {3000}/api/agent/{id}/publish   ★ 必须发布版本才生效

⚠️ 补充坑:改 mcp 记录(PUT /api/mcp/update)必须回填 authorization_token+custom_headers(不带会清空→401/503);MCP 调用挂起用官方 mcp SDK 直连二分定位;自建 SSE 服务器鉴权中间件须纯 ASGI、sse_app() 挂根路径。 ⚠️ 「not found in MCP server」两类根因:① 工具绑定漂移(usage 指向已不存在服务器 → 重绑 enabled_tool_ids+publish);② 5011 平台 MCP 未实例化 OpenAPI 工具 → POST {5010}/tool/openapi_service force_update=true 重新注册触发重建,无需改绑定;/api/mcp/refresh-tools 只刷缓存无效。 ⚠️ 链路小坑:scan_tool 可能 >20s(客户端 60~90s 超时);/api/tool/list 可能直接返回裸数组(解析兼容 list/dict)。

配置六步(Channel ①,API 转 MCP;无原生 MCP 服务器时才用)

1. POST {5010}/tool/openapi_service     注册 OpenAPI 服务(openapi_json 可直接用应用 /openapi.json 或裁剪版)
2. GET  {5010}/tool/scan_tool            扫描 → 工具生成(src:mcp,记录 tool_id)
3. GET  {3000}/api/tool/list             确认工具(tool_id, origin_name)
4. POST {5010}/tool/update               绑定到智能体(每个工具一次)body {tool_id, agent_id, params:{}, enabled:true}
5. POST {3000}/api/agent/{id}/publish    ★ 必须发布版本,绑定才生效!
6. PUT  {3000}/api/mcp/update            补 config_json(OpenAPI JSON,含 "openapi" key)→ 界面 API-MCP 配置可见

MCP SSE 协议探测(验证工具真实可用):

GET  {host}:5011/sse → event: endpoint / data: /messages/?session_id=xxx
POST {host}:5011/messages/?session_id=xxx → JSON-RPC: initialize → notifications/initialized → tools/list → tools/call
tools/call body: {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"<tool_name>","arguments":{...}}}
  • Python 读 SSE 必须 readline 逐行(逐字节读在 Windows/urllib 下有缓冲问题导致 endpoint 丢失)
  • 工具绑定后必须 publish 智能体版本,否则运行时看不到工具
  • 常见坑:/tool/validate 只查远程 MCP 代理表,不适用于验证 OpenAPI 转换类工具

OpenAPI 对接:FastAPI 天然生成 /openapi.json(OpenAPI 3),可直接作 openapi_json;建议裁剪只留对外端点(内部 /api/* 不泄漏给智能体)。

完整流程、踩坑清单、GitHub 源码获取方式见 references/04-mcp.md

方向五:提示词/技能/工具的加载与调用原理(要点速记)

核心结论一句话:技能是文件化的(SKILL.md,tenant 隔离),加载靠 read_skill_md("<技能名>") 渐进式读取(动作可见于 thinking);没有触发 read_skill_md = 技能一定没加载

提示词:三层(duty_prompt 角色任务 / constraint_prompt 约束+输出格式 / few_shots_prompt 示例);update 只改草稿、必须 publish 才生效;update 必带 agent_id(漏传=误建新 agent)。

技能

  • 文件化:skills/{tenant_id}/{skill_name}/SKILL.md;校验 GET /api/skills/{name}/files,缺失可 GET /api/skills/scan_skill 刷新
  • 加载 = read_skill_md("<技能名>")(命中后读全文,thinking 可见);tool_ids=[] 只是"不可作为函数工具调用",不代表不能被 read_skill_md 加载
  • "Skill not found" = 技能文件未就绪/参数错误(排查 files/scan_skill),不是绕开加载的理由
  • 提示词是否要求"每次分析都 read_skill_md 加载"是项目决策,不是平台通用规则:若项目分析依赖技能全文,可要求每次加载(提示词写"每次分析都 read_skill_md 加载" + 兜底"失败忽略但禁止编造技能依据");若技能只是可选增强,则不必强制加载,可写"可用时加载"

工具:内置(如 knowledge_base_search)+ API 转 MCP;绑定后必须 publish;模型在 thinking 中以 code block 发起调用,平台执行回填。

会话管理:chat/run 不带 conversation_id = 新建会话;北向无删除接口(405),删除只能走管理 API DELETE /api/conversation/{id}(JWT);会话列表 GET /api/conversation/list 必须带 today_start_ms/week_start_ms 参数(缺失 422),列表在 data.items,名称字段是 conversation_title(UI 未命名会话默认 "New Conversation";"只保留最近一次"= 应用存管理凭据,新会话成功后再删上一次(先建后删);只删应用创建且未被续用的会话(update_time 快照对比,被续用保留;应用自身追问也要刷新快照)

验证方法论:端到端 SSE 抓 thinking → 技能看 read_skill_md 动作、工具看 code block 调用。

完整原理、实测案例、11 条踩坑清单、修正后 prompt 模板见 references/05-prompt-skill-tool-loading.md

方向六:环境探查(新建全量摸底,更新按需探查)

新建智能体前必须全量探查环境——网络→鉴权→模型→知识库→智能体现状→技能→MCP→工具,每次连接新环境都必须做(或缓存过期后重新做)。更新智能体时只按业务诉求探查相关维度(如"加 MCP"只探 MCP+工具),不冗余全量。

为什么必须探查

  • 环境是黑盒——不知道有什么模型、知识库、技能、MCP,盲目发请求是撞运气
  • 探查产出的结构化报告是「用户知情决策」的前提(选模型、选知识库、是否复用已有智能体)
  • 不探查的后果:创建了同名/同领域智能体、选了不合适的模型、遗漏了可复用的技能/MCP

两种场景

| 场景 | 探查范围 | 输出 | |---|---|---| | ① 新建智能体(全量摸底) | Step 1–7 全流程 | 完整探查报告(含各维度结构化表格)→ 问用户决策 → 创建 | | ② 更新/添加功能(按需探查) | 仅查业务诉求涉及维度(见下表) | 候选列表 → 问用户确认 → 执行 |

按需探查速查

| 用户诉求 | 仅查这些步骤 | |---|---| | "加 MCP 工具" | Step 7(MCP 列表 + 工具列表 + 市场) | | "加技能" | Step 6(技能列表 + 目标技能详情) | | "改提示词" | 不需要探查(直接 search_info 拉当前提示词编辑) | | "换模型" | Step 3(模型列表,更新时沿用不选) | | "挂知识库" | Step 4(索引列表) | | "看当前配置" | Step 5 进阶(show 该智能体) | | "新建智能体(已有摸底)" | 仅 Step 3+4(模型+知识库,供用户选择) | | "什么功能都不确定" | 全量 Step 1–7 |

7 步探查流程(全量摸底):

Step 1: 网络连通性验证 ✓
  → 管理门户 base URL(端口由部署决定,示例 :3000)
  → 北向 API base URL(端口由部署决定,示例 :5013)
  → Config API base URL(端口由部署决定,示例 :5010)

Step 2: 鉴权验证 ✓
  → 管理登录换 JWT (POST /api/user/signin)
  → 北向 API Key 验证 (GET /nb/v1/agents)

Step 3: 模型探查 ✓
  → GET /api/model/list → 取 model_id/display_name/model_type(⚠️ 响应含明文 api_key,禁止转存)
  → 展示表格供用户选模型

Step 4: 知识库探查 ✓
  → GET /api/indices → 索引哈希串(⚠️ 无可读名称,标注让用户到 UI 核对)

Step 5: 智能体现状 ✓
  → GET /api/agent/list → 整理 agent_id/name/display_name/model_name 表格
  → 可选:nexent_agent.py show <id> 看详情

Step 6: 技能探查 ✓
  → GET /api/skills → 名称/描述/tool_ids
  → 可选:GET /api/skills/{name} 看详情

Step 7: MCP + 工具探查 ✓
  → GET /api/mcp/list(远程 MCP 服务器)
  → GET /api/tool/list(已注册工具,兼容 list/dict 结构)
  → 可选:GET /api/mcp-tools/registry/list(市场)

探查产出 — 结构化报告直接展示给用户(不要替用户做决策):

## 📋 Nexent 环境探查报告

### 网络与鉴权
| 服务 | 端口 | 状态 |
|---|---|---|
| 管理门户 | :3000 | ✅ 200 |

### 模型(共 N 个)
| model_id | display_name | type |
|---|---|---|
| ... | ... | ... |

### 知识库(共 N 个)
- `<哈希>`(名称请到 UI 核对)

### 现有智能体(共 N 个)
| agent_id | name | display_name | model |
|---|---|---|---|
| ... | ... | ... | ... |

### 技能(共 N 个)
- `<技能名>` - 描述

### MCP 服务器(共 N 个)
- `<MCP名>` - URL - 状态

### 注册工具(共 N 个)
- `<工具名>` - source - 绑定 agent

注意事项

  • 探查信息仅当前会话有效,下次连接同环境可复用但需注意数据过期(MCP/skill 可能变化)
  • 探查过程中任何一步不通 → 停止并向用户报告原因,不盲目继续
  • MCP 接入/创建智能体等后续操作仍需通过 AskUserQuestion 问用户决策,探查不替代决策权
  • 完整流程、反面教材、正确行为示例见 references/06-environment-probe.md

提示词设计建议(配合前端渲染)

  1. 固定小节结构(如 ## 核心结论 / ## 处理建议 / ## 分歧分析 / ## 风险提示,业务方可根据场景自定义小节名)便于前端分区卡片渲染
  2. 禁止 ### #### 三级标题,段首引导用 **粗体**
  3. 表格必须完整(表头 + 分隔行 + 数据行),防止解析失败
  4. 每条建议标注依据来源(如 规则/技能/知识库)
  5. 关键数值用 Markdown 表格;结论前置,简洁专业

Resources

  • references/01-northbound-api.md — 方向一:北向接口完整 API 文档(agents / chat/run / SSE / 错误处理 / 模型写代码被拦两类错误排障(Code execution failed 可自愈 vs Forbidden function evaluation 硬拒收 + 改 prompt 教训) / 模型选错工具排障(第一顺位查 tools[].description 措辞,通用兜底工具宽泛描述诱使模型绕过专用工具)
  • references/02-streaming-guide.md — 方向二:流式输出对接方法论(接口/协议层:SSE 事件本质 / conversation_id 响应头 / 协议层踩坑(空请求体 422、conversation_id 误渲染、final_answer 长 JSON 被平台截断 → 前端按括号实际深度配平兜底)/ 提示词契约 / 追问-延续轮输出契约(§5.3:首轮vs延续轮分支、追问不重复带附件) / thinking 原文≠面向用户文本(§5.4:工具调用独白净化、映射预设步骤) / §5.5 提示词引导工具 = 映射查表不写枚举清单(枚举必然漏、参数枚举唯一来源 = 工具描述 docstring,单点维护防漂移) / 验证清单;前端呈现(三层架构/滚动三态/图表 init/弹窗解耦/真实浏览器验证)详见 agent-ui-design-and-testing 技能 streaming-ui.md,本文件仅留概述 + 跨技能索引)
  • references/03-admin-api.md — 方向三:管理 API 完整文档(Required Values 追问 / 登录鉴权 / agent CRUD 与创建(update 不带 agent_id)/ 模型与知识库列表(创建时供用户选择,更新自动沿用)/ 技能管理 API(创建/上传/更新/scan_skill/nl2skill + 脚本型技能 run_skill_script 执行机制 + ★ZIP 上传(只传 SKILL.md 脚本不物化)) / search_info / update / publish / 版本命名规则(创建时确认、更新自动递增,多读版本号找规律)/ 接口探查方法论(文档优先→源码兜底)/ 技能"不存在但已加载"排查(已修订指向 05))
  • references/04-mcp.md — 方向四:MCP 工具接入(原生 MCP 接入(Channel②:/api/mcp/add→healthcheck→refresh-tools→5010 scan_tool→tool/update→publish) / API 转 MCP(Channel①)/🚨 API 转 MCP 必须配合仓库注册自己的条目——POST /api/mcp/add(server_url=平台5011/sse) + PUT /api/mcp/update 补 config_json,漏注册=usage 挂到已有 MCP 名下(用户纠正) / 双渠道机制与选型 / 运行时 mcp_host 直连与鉴权头注入 / MCP 调用挂起排障路径(官方 mcp SDK 直连二分定位) / 「not found in MCP server」两类排障——①工具绑定漂移(tool.usage 指向已不存在服务器→重绑 enabled_tool_ids+publish)②5111 OpenAPI 工具未实例化(5010 记录在但 tools/list 仅 3 内置→5010 POST /tool/openapi_service force_update 重新注册触发重建,3000 refresh-tools 只刷缓存无效) / SSE 服务器自建三坑(纯 ASGI 中间件、sse_app 挂根路径、sse_client 2 元组) / SSE 探测:JSON-RPC 响应走流不走 POST body(后台读流+按 id 等待) / mcp/update 不带 authorization_token 会清空 / MCP SSE 协议探测 / 端口速查)
  • references/05-prompt-skill-tool-loading.md — 方向五:提示词/技能/工具加载与调用原理(三层提示词草稿/发布 / 技能文件化与 read_skill_md 渐进式加载(无触发=技能一定没加载)/ 工具绑定与 thinking 可见调用 / 会话生命周期与管理(北向无删除、管理 API DELETE、只删应用创建且未被续用的会话;列表接口需 today_start_ms/week_start_ms 参数、data.items 结构、conversation_title 字段) / 11 条踩坑清单 / 修正后技能使用规则 prompt 模板)
  • references/91-field-mapping.md字段映射速查表(实测校准):用户可见「展示/描述字段组」(description/display_name/business_description=描述智能体应该如何工作(非duty_prompt)/duty_prompt/constraint_prompt/greeting_message/example_questions/few_shots_prompt=示例) + 技术配置字段 + 反模式(opening_remarks/greeting/prologue 不存在) + 版本字段;快速判断 UI↔底层字段映射的方法
  • references/06-environment-probe.md方向六:环境探查(全量摸底与按需探查):新建智能体前的全量环境摸底流程(网络/鉴权/模型/知识库/智能体现状/技能/MCP/工具,7 步探查)+ 更新智能体时的按需探查策略(根据业务诉求只查相关维度)+ 探查报告模板 + 反面教材
  • references/90-qc-ground-truth.md【质控专用,非使用教程】:领域事实清单/复查清单(43 条核心结论 + 已废弃结论 + 已发现问题记录),本技能逻辑复查的领域锚点;质控方法论详见独立技能 skill-qc(L0~L4 五层),质控时加载 skill-qc 执行;正常使用本技能无需阅读,仅在排查/修订/复查时对照使用
  • scripts/nexent_agent.py — 管理 CLI(list / show / update / publish,自动登录 + 字段回填 + 版本递增)