API 对接指南
外部系统直接调用 PlantPulse AI 的 MCP 及 API 的方法。
旧的独立服务 MCP Server(:50000) · Ontology(:8888) 已归档,曾经直接开放 LightRAG 的
:7114 也已不存在。 工具汇集在 MCP 网关这一个地址 → MCP 工具地图
MCP 客户端统一接入网关这一个地址
外部 MCP 客户端(其他智能体 · 桌面应用等)只需接入 https://<호스트>/mcp/gateway/ 这一个地址(Streamable HTTP)。
平台统一 MCP · 时序洞察 · RAG · 文档理解 · 视觉 · 工程计算 · 数字线程 · 运维人员接入的外部服务器的工具都汇集在这个地址。
| 要做的事 | 位置 |
|---|---|
| 获取密钥 | 在 AI 管理控制台 › MCP 网关 › 客户端 API 密钥 中点 签发密钥 —— 密钥(ppgw_…)只在签发后显示一次。为密钥赋予范围(设备 · 站点 · 项目 · 客户 PO · 供应商)和等级 —— 没有范围的密钥只能调用外部服务器工具 |
| 决定可见的工具 | 同一菜单的权限 —— 新密钥创建时未授权任何内容。按服务器授权«所有工具»或部分工具 |
| 调用 | X-API-Key: ppgw_… 或 Authorization: Bearer ppgw_… |
| 查看调用 | 监控 › 调用记录 · 指标 —— 每个密钥的调用都会留下记录 |
- 没有密钥或密钥错误时返回 401;1 分钟内错误超过 20 次的客户端在该分钟内返回 429。
- 此路径只转发网关的 MCP(
/mcp/)。网关管理 REST(/api/v1)不对外开放。 - 不带末尾斜杠的
/mcp/gateway会转到/mcp/gateway/(308)。 - 界面 · 权限 · 密钥作废见 → AI 管理控制台 — MCP 网关
其他端点
| 服务 | URL | 协议 | 认证 |
|---|---|---|---|
| MCP 网关 | https://<호스트>/mcp/gateway/ | MCP (Streamable HTTP) | 网关密钥 ppgw_… — 上方 |
| Copilot 公开 API | https://<호스트>/api/v1/… | REST | X-API-Key → 下方 |
| LiteLLM(模型) | http://<server>:4000 | OpenAI 兼容 | 主密钥 |
| 统一 MCP(平台) | <platform>/api/v5/mcp | MCP (JSON-RPC 2.0) | api_key — Authorization: Bearer 或 X-API-Key |
服务直连 — 供运维人员 · 系统对接使用
内部 MCP 服务器也可以不经网关直接访问。但认证只有一把安装共用的入站密钥(PI_INBOUND_API_KEY),
持有该密钥的一方即拥有全部权限,既没有按调用方区分的工具权限,也没有调用记录。
请只用于运维脚本 · 平台 CEP 这类系统对接,给客户的 MCP 客户端请提供网关。
| 服务 | 直连地址 | 认证 |
|---|---|---|
| 时序洞察 | http://<server>:8970/mcp/ · https://<호스트>/mcp/timeseries/ | 入站密钥 |
| RAG 网关 | http://<server>:7115/mcp/ · https://<호스트>/mcp/rag/ | 入站密钥 |
| 文档理解 | https://<호스트>/mcp/parser/(主机端口 7120 未发布) | 入站密钥 |
| 视觉 | https://<호스트>/mcp/vision/(主机端口 7130 未发布) | 入站密钥 |
以一个地址获取数字线程 · 工程计算 · 平台统一 MCP 的途径只有网关。
也可通过默认主机的路径打开
无需单独开放子域名或端口,代理会将以下内容通过 默认主机(与聊天相同地址)的路径转发:
| 路径 | 转发到 |
|---|---|
https://<호스트>/mcp/gateway/ | MCP 网关的 MCP —— 外部 MCP 客户端用这个 |
https://<호스트>/llm/ | LiteLLM — OpenAI SDK 的 base_url 即 https://<호스트>/llm/v1 |
https://<호스트>/mcp/rag/ | RAG 网关的 MCP |
https://<호스트>/mcp/timeseries/ | 时序洞察的 MCP |
https://<호스트>/mcp/parser/ | 文档理解的 MCP |
https://<호스트>/mcp/vision/ | 视觉的 MCP |
认证由后端来做——/mcp/gateway/ 为网关密钥 ppgw_…,直连 MCP 网为 X-API-Key: <PI_INBOUND_API_KEY>,/llm/ 若没有 LiteLLM
主密钥则为 401。由于默认主机通常是绑定了外部 DNS 的地址,安装后
请务必用 CHANGE_ME_… 检查是否有遗留的密钥 → 凭证管理
LiteLLM 管理界面(/llm/ui)不会通过此路径打开——请用 :4000 打开。
后端的入站密钥
时序洞察 · RAG · 文档理解 · 视觉 · 数字线程使用相同的入站密钥(安装 env 中的 PI_INBOUND_API_KEY)→
凭证管理。通过 X-API-Key: <key> 或 Authorization: Bearer <key> 发送。
-
无需密钥即可访问的只有
/ping·/health两个。/metrics也需要密钥。 -
密钥缺失或错误时返回 401(RAG 为
missing or invalid API key)。 -
🔴 密钥为空时服务不会启动(fail-closed)。安装巡检(
bin/lint-env.sh)会先 在[fail] PI_INBOUND_API_KEY is empty and PI_INBOUND_AUTH_DISABLED is not true处停止,服务日志中会留下FATAL: … is empty — refusing to start …。不会出现因密钥为空而«悄悄开放的后端»。 -
若想特意关闭认证(如隔离测试环境),需在安装 env 中写入
PI_INBOUND_AUTH_DISABLED=true(默认false)。compose 会把这个值 以各服务对应的名称传入。服务 容器读取的名称 RAG RAG_INBOUND_AUTH_DISABLED时序洞察 TS_INBOUND_AUTH_DISABLED数字线程 DT_INBOUND_AUTH_DISABLED文档理解 · 视觉 INBOUND_AUTH_DISABLED若填写了密钥,密钥优先(lint-env 会以
[note] … is ignored — PI_INBOUND_API_KEY is set and the key wins提示)。true·false之外的值视为[fail]。以关闭状态启动的服务会在/health中如实记录(数字线程auth.inbound=disabled,时序洞察inbound_auth: "disabled")——在管理控制台的 API 密钥界面执行巡检即可检测为开放 → AI 管理控制台 — API 密钥
文档理解·视觉不发布主机端口(7120 · 7130)——外部只能通过上述
/mcp/parser/ · /mcp/vision/ 路径访问。数字线程(7140)也不开放主机端口。
不是 /mcp,而是 /mcp/。省略斜杠会导致重定向或 404。
MCP 协议调用
全部五台服务器都遵循 **MCP(Model Context Protocol)**标准。工厂数据·本体
工具属于平台统一 MCP(/api/v5/mcp),波形分析属于时序洞察,文档·图片属于
其余三个。
直接调用服务器时使用不带前缀的名称(analyze_asset)。insight_ 之类的
前缀是聊天的工具注册器加上的,因此聊天界面看到的名称与这里使用的名称
不同。
MCP 基本结构
MCP 是基于 JSON-RPC 2.0 的 HTTP POST 通信。统一 MCP 需要 api_key 认证(Authorization: Bearer <token>)。
POST /api/v5/mcp HTTP/1.1
Content-Type: application/json
Authorization: Bearer <platform.api.token>
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "<tool-name>",
"arguments": {
"<param1>": "<value1>",
"<param2>": "<value2>"
}
}
}
查询工具列表
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'
工具调用示例
search_domains 开头人用名称说话,工具接收 ID。标准顺序是先由 search_domains 对14 个领域进行
部分匹配搜索以确定「领域 + ID」,再将该 ID 传给详情工具。
① 按名称查找获取 ID
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_domains",
"arguments": {
"query": "압축기",
"domain": "asset",
"limit": 20
}
}
}'
若已知 domain 可指定以进行精确搜索,不知道则省略,会按领域分类返回。
② 展开资产层级
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_asset_tree",
"arguments": { "asset_id": "<①에서 얻은 ID>" }
}
}'
tags 键不代表「没有标签」默认情况下标签只返回数量(tag_count)。只有在确实需要名称·tag_id 时才
传入 include_tags: true——响应体积会增大数倍。标签有无的权威来源是
tag_count,只有 tag_count: 0 才是真正的无标签。
③ 一次性读取标签当前值
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_tag_values",
"arguments": { "tag_ids": ["<tag_id>", "<tag_id>"] }
}
}'
tag_ids 是数组,一次最多传入 100 个。响应中的 found: false 表示未注册
标签,error 表示查询失败(值得重试)。区间历史数据为
get_tag_history。
统一 MCP 认证
统一 MCP 必须进行 api_key 认证。聊天使用的值是 Copilot 的
platform.api.url · platform.api.token(环境变量 CO_PLATFORM_API_URL ·
CO_PLATFORM_API_TOKEN — compose 会将主机 env 中的 PP_API_URL · PP_API_TOKEN 传入)。
2026.09 之前的前缀 CH_ 在 2026.10 改为 CO_,没有回退机制。
⚠ 旧名称 mcp.api.url · mcp.api.token 已不存在。 启动时旧配置行会
迁移为新名称,但若用旧名称传入环境变量则不会生效。
认证头
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{ ... }'
本体(知识图谱)调用
本体工具已并入统一 MCP。🔴 不存在名为 ontology_* 的工具——
这是旧独立服务(:8888)时代的名称。现在共有三个。
| 工具 | 回答什么 |
|---|---|
get_ontology | 单个站点的组成概览——区域/产线/设备结构 + 各设备的标签数量 |
query_ontology | 有向关系探索——「X 影响什么」,上游·下游 |
query_sparql | 多条件交叉查询(仅限 SELECT / ASK) |
名称相似但返回的维度不同。 纯层级结构用 get_asset_tree,
站点组成概览用 get_ontology,关系传播用 query_ontology。
站点组成概览
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_ontology",
"arguments": { "site_id": "<site_id>" }
}
}'
site_id 为必填——请先通过 search_domains 用 domain: "site" 解析。
total_tag_count 一项为准请勿把各节点的 tag_count 相加——未展开的分支会被遗漏。
total_tag_count_unknown: true 表示「无法计数」,不要凭感觉估算。
关系探索 — 「这会影响什么」
curl -X POST <platform>/api/v5/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <platform.api.token>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query_ontology",
"arguments": {
"entity_id": "<설비 ID>",
"direction": "DOWN",
"depth": 2
}
}
}'
| 参数 | 值 | 含义 |
|---|---|---|
entity_id | (必填) | 开始探索的实体 |
relation_type | FEEDS · DEPENDS_ON · PRODUCES | 省略则为全部 |
direction | UP · DOWN · BOTH | 默认 DOWN(下游影响) |
depth | 1 ~ 5 | 默认 2 |
响应为 root + nodes[] + edges[] + truncated。若为 truncated: true,
表示在深度或广度上被截断,需缩小范围后重新查询。
时序洞察 MCP 调用
设备异常检测
curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "detect_asset_anomaly",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1",
"lookback_minutes": 1440,
"top_k": 5
}
}
}'
省略 threshold 时默认为 5.0。传感器异常分数并非 0~1,而是校准分数
(相对于基准区间的稳健 z 值),若传入 0,即使只比基准中位数略高也会全部计为异常 →
AI 模型
设备传感器预测
curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "forecast_asset",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1",
"prediction_length": 96,
"enable_bounds": true
}
}
}'
设备健康评分
curl -X POST http://127.0.0.1:8970/mcp/ \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_asset_health",
"arguments": {
"asset_id": "ASSET_DJ_M_01_1"
}
}
}'
RAG(LightRAG)调用
RAG 引擎是 LightRAG 1.5.7(自 2026.10 起使用我们封装的镜像 pi/plantpulse-lightrag),但 🔴 不可直接调用。 LightRAG 只存在于容器
内部,外部可访问的入口只有 rag-api(7115) 网关一个。
文档上传·列表·删除在管理控制台中进行(旧的 LightRAG WebUI 已并入控制台)。
搜索通过网关的 REST 调用,并用 X-API-Key 认证。
Copilot 聊天的文档检索经由 MCP 网关调用此网关的 MCP 工具 rag_search(Copilot
没有内置的文档检索)。REST /api/v1/query 与 MCP rag_search 给出相同的信封 —— 不会
直接连接 LightRAG。下方响应格式并非 LightRAG 本身的格式,而是网关规定的信封。
文本搜索
curl -X POST http://127.0.0.1:7115/api/v1/query \
-H "Content-Type: application/json" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-d '{
"query": "펌프 정비 절차",
"mode": "hybrid"
}'
| 参数 | 值 |
|---|---|
query | 搜索词 — 须 3 个字符以上(过短则 400) |
mode | hybrid(默认)· naive · local · global — 其他值一律 422 |
| 响应 | 含义 |
|---|---|
{"retrieved": true, "answer": …, "sources": [{"file_name": …, "reference_id": …}]} | 找到了。reference_id 是答案正文中出处标记 [n] 的 n(引擎未编号的出处则没有此字段) |
{"retrieved": false, "code": …, "reason": …, "sources": []} | 未找到。 answer 键本身不存在 |
| HTTP 502 | 引擎侧失败 |
retrieved: false 并非错误而是「不存在」HTTP 状态为 200。若 code 为 NO_CONTEXT,表示已索引文档中无相关内容,
若为 EMPTY_ANSWER,表示引擎空手而归。再次调用结果相同——
请勿把没有 answer 的响应当作结果展示。
图纸对比 — 两个版本间的差异
可在开启图纸采集(DRAWING_INGEST_ENABLED=true)的安装中使用 → 环境变量设置。
入口有两个,对比工作由文档理解完成。 rag-api 取出已索引的两个版本的原件传给文档理解,并原样
返回其结果。两者都需要入站密钥。
| 入口 | 适用场景 |
|---|---|
rag-api GET /api/v1/drawings/{asset_id}/{doc_name}/diff | 已索引的图纸——自动查找前一版本进行对比 |
文档理解 POST /api/v1/drawings/diff | 直接对比手头的两个文件(与索引无关) |
与已索引图纸的前一版本对比(rag-api)
curl -G "http://127.0.0.1:7115/api/v1/drawings/<asset_id>/<doc_name>/diff" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
--data-urlencode "lang=ko"
| 参数 | 含义 |
|---|---|
against | 用于对比的前一版本文档名称。留空时会在相同图纸编号中选取版本标记紧邻前面的一个(A < B < … < Z < AA,1 < 2 < 10) |
against_asset | 若前一版本挂在其他设备上,填写该设备 ID(默认相同设备) |
lang | summary 行使用的语言 ko · en。留空则用安装语言(PP_LANG)。数字部分无论语言如何都按图纸原文照录 |
| 状态 | 含义 |
|---|---|
404 | 其中一方未索引、原件未保存,或没有可选的前一版本 |
422 | 比较器无法读取文件 |
502 | 无法连接比较器或对象存储 |
同一路由下还有页面预览(…/page/{n} — PDF 为 PNG,DXF 为 SVG)与版本状态(…/revision-status — current ·
outdated · change_open · unknown)。
直接对比两个文件(文档理解)
文档理解不发布主机端口,因此外部需通过 parser.* 主机调用。
curl -X POST "https://parser.<domain>/api/v1/drawings/diff" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" \
-F "old=@A-100_rev-A.dxf" -F "new=@A-100_rev-B.dxf" -F "lang=ko"
- 文件须为
.dxf或带文本层的矢量.pdf,单个文件最大 50 MB。不接受 DWG。 lang的默认值为en(与 rag-api 入口不同)。- 拒绝时会连同
error_kind: input一起返回:扩展名415· 大小413· 无法读取400。
结果的结构
| 键 | 内容 |
|---|---|
title | 变化的标题栏字段 |
dimensions | added · removed · changed(值 · 单位 · 数量 · 公差 · 文字 · 位置中哪项变化了)· unchanged |
bom · notes | 变化的 BOM 行 · 备注 |
regions | 变化区域——后版本的 bbox 与前版本的 bbox_old。对位失败时为 status: unavailable 及原因,不会凭空编造区域 |
summary | 人类可读的摘要行——数字按图纸原文照录 |
confidence · limits | high · medium · low,以及无法对比的项(扫描页·无标题栏·仅一方有 BOM 等) |
warnings | different_drawing_numbers(图纸编号不同)· revision_label_unchanged(版本标记相同)等 |
视频 · 音频 — rag-api 的 /api/v1/media
仅在开启视频 · 音频采集的安装(安装 env PI_MEDIA_ENABLED=true)中才会出现此路径。未开启的安装中此路径根本不存在,返回 404,
视频·音频上传会被 400 拒绝。是否开启可通过 GET /api/v1/config 的 media_ingest_enabled 查看 →
环境变量设置 · AI 管理控制台 — 视频
| 方法 · 路径 | 作用 |
|---|---|
GET /api/v1/media/jobs | 各文件的处理状态 · 时长 · 分段数 · 场景截图数(thumb_count)与处理时间段(window — open · next_start · spec) |
GET /api/v1/media/jobs/{asset_id}/{doc_name} | 单个文件的详情 |
GET /api/v1/media/integrity | 已索引但不在搜索索引中的分段 |
POST /api/v1/media/jobs/{asset_id}/{doc_name}/retry | 重新加入队列(失败·跳过)。若为 ?force=true 则从头重新转录 |
GET /api/v1/media/{asset_id}/{doc_name}/transcript | 保存的转录文本 |
GET /api/v1/media/{asset_id}/{doc_name}/thumb?t=<ms> | 该时刻之前最近的场景截图 |
GET /api/v1/media/{asset_id}/{doc_name}/stream | 播放——对 Range 请求以 206 响应 |
- 上传与文档相同的
POST /api/v1/docs/upload,删除也用相同的DELETE /api/v1/docs/{asset_id}/{doc_name}(来自平台台账的为409)。 - **场景截图(
…/thumb)**附带ETag和Cache-Control: private, max-age=86400。若以相同ETag发送If-None-Match, 不会重新读取图片而以 304 响应。状态数据库暂时繁忙时会返回 503(而非 500)及state database busy, retry shortly与Retry-After: 1—— 请在该时间之后重新调用。 - Copilot 界面使用的中继(Copilot 的
/media/thumb·/media/stream,用登录会话认证)也会原样转发ETag· 304,后端的 503 会 连同Retry-After一并以 503 转发(此前以 502 包装)。
请求 id 与指标 — X-Request-ID · /metrics
自 2026.10 重新发布起,五个 Python 后端(RAG · 时序洞察 API · 文档理解 · 视觉 · 数字线程)采用相同规则。
- 请求 id — 若请求携带
X-Request-ID(1~128 字符,字母·数字·._-),则沿用该值;若缺失或格式不符, 则生成新值,并通过响应头X-Request-ID返回。该请求处理期间产生的日志行会附带相同值request_id。RAG 还会在错误响应体中加入request_id。 - 指标 —
GET /metrics输出 Prometheus 文本格式。需要入站密钥(与健康检查路径不同,不豁免)。端口未变化 → 日志与监控
curl -s -D - -o /dev/null -H "X-Request-ID: my-trace-001" \
-H "X-API-Key: <PI_INBOUND_API_KEY>" http://127.0.0.1:7115/api/v1/config | grep -i x-request-id
调用 LLM API(OpenAI 兼容)
LiteLLM 代理提供 OpenAI 兼容 API。可直接沿用现有的 OpenAI SDK。
局域网中为 http://<server>:4000/v1,经由默认主机则为 https://<호스트>/llm/v1。
聊天补全
curl http://127.0.0.1:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 설치-시-변경" \
-d '{
"model": "aura-lite",
"messages": [
{"role": "user", "content": "주입기 베어링 교체 주기를 알려줘."}
],
"temperature": 0.7
}'
生成嵌入
curl http://127.0.0.1:4000/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 설치-시-변경" \
-d '{
"model": "aura-embedding-4b",
"input": "주입기 베어링 교체 절차"
}'
查看模型列表
curl http://127.0.0.1:4000/v1/models \
-H "Authorization: Bearer 설치-시-변경"
可用模型
| 模型名称 | 用途 | 实际模型 |
|---|---|---|
aura-lite | 对话·分析(同时支持图像输入) | Aura — 默认 Aura-Lite-NVFP4 |
aura-vision | 与上面相同引擎的视觉专用别名 | 同上模型 |
aura-embedding-4b | 嵌入 | Aura-Embedding-4B |
aura-reranker-0.6b | 重排序 | Aura-Reranker-0.6B |
gpt-4o · text-embedding-3-large 现已报错旧版本接受 OpenAI 兼容别名(gpt-4o · gpt-4o-mini · text-embedding-3-large ·
rerank-multilingual-v3.0)。现在不再接受——如果对接代码中残留旧名称,
调用将被拒绝。请改用上表中的名称。可用 /v1/models 查看当前可用的名称列表。
无论使用哪个名称,最终都指向内部运行的 Aura 模型——隔离网络安装也是如此。
Python SDK 示例
用 OpenAI SDK 调用 LLM
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:4000/v1",
api_key="설치-시-변경"
)
response = client.chat.completions.create(
model="aura-lite",
messages=[
{"role": "user", "content": "주입기 상태를 분석해줘."}
]
)
print(response.choices[0].message.content)
调用 MCP 工具
import requests
def call_mcp_tool(url, tool_name, arguments=None, headers=None):
response = requests.post(
url,
headers=headers or {},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": tool_name,
"arguments": arguments or {}
}
}
)
return response.json()
# 이름으로 설비를 찾는다 (통합 MCP — api_key 필요)
result = call_mcp_tool(
"<platform>/api/v5/mcp",
"search_domains",
{"query": "압축기", "domain": "asset"},
headers={"Authorization": "Bearer <platform.api.token>"}
)
print(result)
# 설비 이상 탐지 (TimeSeries-Insight — 인바운드 키 필요)
result = call_mcp_tool(
"http://127.0.0.1:8970/mcp/",
"detect_asset_anomaly",
{"asset_id": "ASSET_DJ_M_01_1", "lookback_minutes": 1440},
headers={"X-API-Key": "<PI_INBOUND_API_KEY>"}
)
print(result)
Copilot 公开 API(/api/v1)
外部系统可借此直接复用聊天和晨间卡片的入口。地址与聊天相同(默认主机)。
| 方法 · 路径 | 作用 |
|---|---|
POST /api/v1/chat | 提问并接收答案。所需工具由服务器自行选择 |
GET /api/v1/tasks/daily | 读取当日的每日卡片(每天 05:00 生成)。?date=YYYY-MM-DD — 以工厂时区为准,留空则为今天 |
GET /api/v1/tools | 代理当前可用的工具列表(名称·说明·是否只读) |
GET /api/v1/ai-feedback | 读取人工对 AI 结果标注的内容(误报·建议采纳/拒绝/效果)及服务器按规则标注的内容(正确·误报·漏报)——2026.10(见下方) |
curl -X POST https://<호스트>/api/v1/chat \
-H "Content-Type: application/json" \
-H "X-API-Key: <발급받은 키>" \
-d '{ "input_value": "지금 끊어진 엣지 장비가 몇 대야?" }'
响应包含 answer(Markdown)· session_id · duration_ms · tools(生成此答案所调用的工具)。
若省略或留空 session_id 则会开启新对话(与界面上的「新对话」相同——默认应用,归属调用者本人),
并在响应的 session_id 中返回该 id。要延续对话,请在下次请求中传入该值。
由于是同步调用,需要多次调用工具的问题可能耗时数十秒。
session_id 的调用会返回 500文档中虽说「留空则开启新对话」,但服务器会返回 500,以 X-API-Key 调用也以 500 结束。
2026.10 两者均已修复。
自 2026.10 重新发布 3 起,若模型重试后仍无法生成答案,将返回 HTTP 502。响应体结构相同,只是 answer 为空。
这是为了避免把空答案以 200 返回而让人误以为是「无结果」的正常结果——重新发送相同问题即可。
人工对 AI 结果的标注 — GET /api/v1/ai-feedback
Copilot 的建议中,仅读取人工对 AI 结果的标注(忽略原因·采纳/拒绝·效果)的入口(写入途径仅限界面)
→ AI 发现与准确度 — 人工留下的判断。认证方式
与其他 /api/v1 相同(仅限 X-API-Key — 自 2026.10 重新发布 6 起,登录会话返回 403)。
curl "https://<호스트>/api/v1/ai-feedback?since=2026-10-01T00:00:00Z&limit=500" \
-H "X-API-Key: <발급받은 키>"
| 参数 | 含义 |
|---|---|
since | labeled_at 下限(RFC 3339 或 epoch ms)。留空则从最早开始 |
asset_id | 按设备 id 过滤 |
target_kind | ANOMALY(单个事件)· FINDING(AI 发现)· PROPOSAL(由发现生成的建议卡片)· MISSED(漏报上报)· DAILY_TASK |
limit | 最大行数 1~1000,默认 500 |
响应包含 count · items · next_since。按时间从旧到新返回,因此下一页需用 next_since 重新
调用——相同时刻的行可能重复出现,请用 feedback_id 过滤。若对同一对象人工再次点击,
该行的 value · labeled_at 会更新(以最后一次标注为准)。
label_key | value |
|---|---|
verdict | hit · false_alarm · unsure(判定保留——不计入准确度计算) |
reason | 误报原因 setup · idle · maintenance · sensor · other / 建议拒绝原因 already_done · not_needed · wrong · other |
cause | 实际原因 breakdown · degradation · sensor · setup · maintenance · normal · other |
proposal_decision | accepted · rejected |
outcome | effective · not_effective · unknown(在 comment 中备注) |
missed | missed(在 comment 中说明,occurred_at 中为漏报事件时刻) |
新界面(三个菜单)中人工留下的值是 verdict 的 false_alarm(对待确认异常的忽略)及其 reason、proposal_decision、outcome。
hit · missed 由服务器对照停机·故障规则标注,unsure · cause 存在于旧界面留下的记录中。
每一行还会附带 occurred_at(标注所指的事件时刻)· labeled_by · labeled_at · config_ver(产生该结果的
判定版本),时刻旁的 …Stamp 是以工厂时区(PP_TZ)书写的值。
密钥——两种方式
| 方式 | 位置 | 特性 |
|---|---|---|
| 发放密钥(推荐) | Copilot 管理控制台 → API 密钥 → 发放 | 可命名并发放多个,可逐一吊销。会记录最后使用时间 |
| 环境变量密钥 | /etc/kopens/plantpulse-ai.env 中的 CO_API_V1_KEY(2026.09 以前为 CH_API_V1_KEY — 旧名称会被静默忽略) | 仅有一行。留空则仅此密钥的认证被关闭 |
由于只以哈希形式保存,列表中只显示前几位。若遗失请重新发放并 吊销旧密钥。
该密钥授予的权限为 /api/v1 与 Copilot MCP(/mcp)。自 2026.10 重新发布 6 起,这两条路径仅限密钥访问,
以登录浏览器会话调用将返回 403。以密钥调用的权限·文档等级遵循「外部 API」角色组(默认对外保密),
范围始终为全体 → 权限。管理员路径及 API 文档
界面(/swagger-ui.html)需要管理员登录。不存在「直接调用」工具的途径——
因为会改变状态的工具都附带人工审批流程。
界面使用的 API 中发生变化的内容(2026.10 重新发布 3)
以下不是公开 API,而是 Copilot 界面以登录会话调用的路径。若有模拟界面调用的集成,请加以确认。
| 方法 · 路径 | 变化内容 |
|---|---|
PUT /api/employees/{아이디}/work-role | 🔴 变为仅限管理员(此前本人也可操作)。请求体 {"workRole": "maintenance"}。每次修改都会以 employee.work_role:<아이디> 的形式记录在审计日志中 → 用户权限与工作角色 |
PUT /api/employees/{아이디}/home-role | 新路径——本人的首页偏好。请求体 {"homeRole": "manager"}(与工作角色相同的五个值)。可由本人或管理员调用。不会改变审批权限。三菜单(提问·建议·自动化)的新界面首屏对所有人都是提问,因此不使用此值——路径仍保留 |
GET /api/sop?query=…&assetId=… | 新增 assetId 参数——传入后会排除其他设备的出处。响应为 {answer, sources[], citations, truncated},答案会在 600 字符内的句子边界处截断(truncated)。搜索词过短返回 400,文档搜索服务无响应时返回 503 + Retry-After |
响应格式
MCP 成功响应
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{ ... 도구 실행 결과 JSON ... }"
}
]
}
}
MCP 错误响应
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid request",
"data": "상세 오류 메시지"
}
}
数据量较大时 — limit 与 has_more
🔴 不存在 page · size。 统一 MCP 工具通过 limit 设定上限,响应中的
has_more 表示「还有更多」。
{
"name": "search_domains",
"arguments": {
"query": "압축기",
"domain": "asset",
"limit": 50
}
}
| 工具 | limit 默认值 | 最大值 |
|---|---|---|
search_domains | 50 | 500 |
get_tag_history | 500 | 500 |
get_tag_values | (数组 tag_ids — 一次性) | 100 个 |
has_more: true 时由于没有页码,标准做法是缩小条件范围——指定 domain、缩短期间,
或具体化搜索词。这不是靠反复发送相同查询来获取下一页的形式。
时间格式
统一 MCP 的时间参数为服务器本地时间。参数名为 from · to,
格式为 YYYY-MM-DDTHH:MM:SS。
{
"name": "get_tag_history",
"arguments": {
"tag_id": "<tag_id>",
"from": "2026-03-29T00:00:00",
"to": "2026-03-29T23:59:59"
}
}
Z 将被拒绝不接受带 2026-03-29T00:00:00+09:00 或 ...Z 的值。仅接受不带偏移量的本地时间——
服务器当前识别的时间可通过 get_current_time 确认。
也没有名为 start_time · end_time 的参数。应为 from · to。
响应中带 _iso 后缀的字段为便于人类阅读的 KST 格式:
{
"timestamp": 1711641600000,
"timestamp_iso": "2026-03-29 09:00:00"
}