跳到主要内容

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 公开 APIhttps://<호스트>/api/v1/…RESTX-API-Key → 下方
LiteLLM(模型)http://<server>:4000OpenAI 兼容主密钥
统一 MCP(平台)<platform>/api/v5/mcpMCP (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 会把这个值 以各服务对应的名称传入。

    服务容器读取的名称
    RAGRAG_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,而是 /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_typeFEEDS · DEPENDS_ON · PRODUCES省略则为全部
directionUP · DOWN · BOTH默认 DOWN(下游影响)
depth1 ~ 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)
modehybrid(默认)· 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(默认相同设备)
langsummary 行使用的语言 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变化的标题栏字段
dimensionsadded · removed · changed(值 · 单位 · 数量 · 公差 · 文字 · 位置中哪项变化了)· unchanged
bom · notes变化的 BOM 行 · 备注
regions变化区域——后版本的 bbox 与前版本的 bbox_old。对位失败时为 status: unavailable 及原因,不会凭空编造区域
summary人类可读的摘要行——数字按图纸原文照录
confidence · limitshigh · medium · low,以及无法对比的项(扫描页·无标题栏·仅一方有 BOM 等)
warningsdifferent_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。要延续对话,请在下次请求中传入该值。 由于是同步调用,需要多次调用工具的问题可能耗时数十秒。

2026.09 版本中不带 session_id 的调用会返回 500

文档中虽说「留空则开启新对话」,但服务器会返回 500,以 X-API-Key 调用也以 500 结束。 2026.10 两者均已修复。

答案为空时返回 502

自 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: <발급받은 키>"
参数含义
sincelabeled_at 下限(RFC 3339 或 epoch ms)。留空则从最早开始
asset_id按设备 id 过滤
target_kindANOMALY(单个事件)· FINDING(AI 发现)· PROPOSAL(由发现生成的建议卡片)· MISSED(漏报上报)· DAILY_TASK
limit最大行数 1~1000,默认 500

响应包含 count · items · next_since。按时间从旧到新返回,因此下一页需用 next_since 重新 调用——相同时刻的行可能重复出现,请用 feedback_id 过滤。若对同一对象人工再次点击, 该行的 value · labeled_at 会更新(以最后一次标注为准)。

label_keyvalue
verdicthit · false_alarm · unsure(判定保留——不计入准确度计算)
reason误报原因 setup · idle · maintenance · sensor · other / 建议拒绝原因 already_done · not_needed · wrong · other
cause实际原因 breakdown · degradation · sensor · setup · maintenance · normal · other
proposal_decisionaccepted · rejected
outcomeeffective · not_effective · unknown(在 comment 中备注)
missedmissed(在 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

该密钥授予的权限为 /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_domains50500
get_tag_history500500
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"
}