先把一条真实业务链跑通
- 先用 query 跑通第一条真实请求,验证 Token、softwareId、tenantId 和页面上下文都能带进来。
- 优先消费结构化返回,不只看 answer,也要让宿主继续使用 steps、warnings 和 suggestedActions。
- 把菜单、权限、用户画像通过 sync 或适配器映射接进来,避免只靠自然语言猜上下文。
- 最后再接媒体上传、ASR、OCR 和反馈闭环,不要一开始就把所有能力混在一起。
这页不讲空泛概念,只讲怎么把第一条请求、宿主适配、结构化返回和多模态入口真正接起来。 先把最小链路跑通,再逐步加同步、反馈和媒体网关。
Entry Points
First Request
curl -X POST https://ziin.shenliu.cc/api/ziin/query \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer editor|softwareId:erp-suite|tenantId:tenant-east-cn|userId:u-1001' \
-d '{
"question": "为什么入库单提交失败?",
"mode": "embedded-agent",
"module": "inventory",
"context": {
"route": "/inventory/inbound/create",
"pageTitle": "入库管理",
"selectedMenu": "仓储中心 / 入库管理",
"platform": "web"
},
"inputs": [
{
"type": "error-dialog",
"content": "报错弹窗:无权限提交入库单"
}
]
}'{
"traceId": "q_20260415_0001",
"intent": "troubleshoot",
"answer": "当前用户没有直接提交入库单的审批权限。",
"permissions": [
"inventory.inbound.create",
"inventory.inbound.read"
],
"steps": [
"进入入库管理页面",
"先完成必填字段并保存单据",
"联系具备审批权限的角色继续提交"
],
"warnings": [
"当前结果受宿主权限上下文限制"
],
"sources": [
{
"assetCode": "ka_001",
"title": "入库管理操作手册",
"type": "manual"
}
],
"suggestedActions": [
"如无提交按钮,请联系管理员开通提交权限"
]
}保留用户原始口语,不要先过度改写。系统怎么问,智引就先吃什么。
最好由宿主直接传模块和当前路由,避免只靠自然语言去猜当前业务位置。
权限边界最好来自宿主可信上下文,而不是由模型自由推断。
截图、语音、文档、报错弹窗都统一挂在 inputs 里,再进入识别和问答链路。
公开体验调用。如果后续切到收费门禁模式,调用时补 `X-Ziin-Key` 即可。
控制接口已收口。知识导入、同步、运营、供应商配置和审计接口不建议长期公开。
公开下载中。公开资料可用于评估和联调,但不等于生产商用授权。
Host Types
这是最常见的第一步。适合已有 Web 业务系统、BFF 或 Node 服务的项目。
import { ZiinClient } from "@ziin/sdk-js";
const client = new ZiinClient({
baseUrl: "https://ziin.shenliu.cc",
token: "editor|softwareId:erp-suite|tenantId:tenant-east-cn|userId:u-1001",
});
const result = await client.query({
question: "怎么做入库单?",
mode: "api-engine",
module: "inventory",
context: {
route: "/inventory/inbound/create",
platform: "web",
},
});
console.log(result.answer);const response = await fetch("/api/ziin/query", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer editor|softwareId:erp-suite|tenantId:tenant-east-cn|userId:u-1001",
},
body: JSON.stringify({
question: "这个模块是干嘛的?",
mode: "ui-assistant",
module: "inventory",
context: {
route: "/inventory/inbound/create",
pageTitle: "入库管理",
selectedMenu: "仓储中心 / 入库管理",
platform: "web",
},
}),
});
const result = await response.json();
assistantPanel.render(result.answer, result.suggestedActions);端的 UI 不同,但协议不应该分裂。小程序、App 和 H5 都应共用同一套 Query 结构。
wx.request({
url: "https://ziin.shenliu.cc/api/ziin/query",
method: "POST",
header: {
"Content-Type": "application/json",
Authorization: "Bearer editor|softwareId:erp-suite|tenantId:tenant-east-cn|userId:u-1001",
},
data: {
question: "报错是什么意思?",
mode: "mini-program",
module: "inventory",
context: {
route: "/pages/inventory/inbound/create",
pageTitle: "入库管理",
selectedMenu: "仓储中心 / 入库管理",
platform: "mini-program",
},
},
});推荐 Token 组织成 role|softwareId:...|tenantId:...|userId:...,当前项目已支持从这个格式中解析 `softwareId`、`tenantId` 和 `userId`。
宿主 AI 保留自己的语气、品牌和会话层,Ziin 只负责提供软件知识、权限判断和结构化答案。
const ziin = await fetch("https://ziin.shenliu.cc/api/ziin/query", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer editor|softwareId:erp-suite|tenantId:tenant-east-cn|userId:u-1001",
},
body: JSON.stringify({
question: userMessage,
mode: "embedded-agent",
module: currentModule,
context: currentPageContext,
inputs: multimodalInputs,
}),
}).then((r) => r.json());
return llm.rewriteForUser({
answer: ziin.answer,
warnings: ziin.warnings,
actions: ziin.suggestedActions,
});RuoYi-Cloud 只是一个宿主,不是产品中心。以后接任何系统,都应只做 adapter,不要重写 core。
curl -X POST https://ziin.shenliu.cc/api/ziin/sync \
-H 'Content-Type: application/json' \
-d '{
"softwareId": "erp-suite",
"tenant": {
"id": "tenant-east-cn",
"softwareId": "erp-suite",
"name": "华东制造集团"
},
"menuNodes": [
{
"id": "mn-sync-001",
"module": "inventory",
"name": "入库管理",
"route": "/inventory/inbound/create",
"permissionKey": "inventory.write"
}
],
"permissionPoints": [
{
"roleCode": "warehouse_clerk",
"permissionKey": "inventory.write"
}
]
}'adapter:
softwareId: erp-demo
tenantMode: single
defaultPlatform: web
mapping:
roles:
"采购员": purchaser
"仓库管理员": warehouse_admin
permissions:
"inventory:inbound:create": "inventory.inbound.create"
"inventory:inbound:read": "inventory.inbound.read"Multimodal
真正商用不是“接个 OCR/ASR 接口”就结束,而是要建设媒体解析网关和统一任务链路。
import { ZiinClient } from "@ziin/sdk-js";
const client = new ZiinClient({
baseUrl: "https://ziin.shenliu.cc",
});
const created = await client.uploadAndCreateAsrTask({
tenantId: "tenant-east-cn",
userId: "u-1001",
source: "app",
scene: "voice-ticket",
language: "zh",
file: {
fileName: file.name,
mimeType: file.type,
bytes: file,
},
});const detail = await client.waitForTask(created.task.taskId, {
intervalMs: 2000,
maxAttempts: 45,
});
if (detail.status !== "success") {
console.error(detail.error);
}
console.log(detail.result);[
{ "type": "text", "content": "为什么提交失败?" },
{ "type": "error-dialog", "content": "提交失败:无权限提交入库单" },
{ "type": "ocr-text", "content": "OCR 结果:单据状态不允许过账" },
{ "type": "image", "content": "https://cdn.example.com/error.png", "mimeType": "image/png" },
{ "type": "document", "content": "https://cdn.example.com/manual.pdf", "mimeType": "application/pdf" }
]Delivery Standard