A shared Vector Engine setup usually begins with simple configuration: one Base URL, one API Key per tool, and a model name that Dify, Cursor, and Node.js can all use. The setup gets harder after a few changes. A workflow owner updates Dify, a developer changes Cursor, and a service deploy changes Node.js environment variables. When model_not_found appears, the team needs a compact way to see what changed.
This tutorial builds a request delta report for an OpenAI-compatible API gateway. It does not store prompts or secrets. It compares the provider fields that matter most in an LLM API provider layer.
The snapshot shape
Create a JSON snapshot for each caller. Keep it boring and predictable.
{
"tool": "dify-workflow-a",
"baseUrl": "configured-openai-compatible-base-url",
"apiKeyScope": "workflow-production",
"modelName": "configured-model-route",
"requestPath": "/v1/chat/completions",
"owner": "workflow-team",
"lastChangedBy": "release-note-2026-07-20"
}
For Dify, the snapshot comes from provider settings and workflow notes. For Cursor, it comes from the custom provider configuration. For Node.js, it can be exported during deployment.
A small Node.js delta script
Save snapshots as dify.json, cursor.json, and node-service.json, then compare them.
import fs from "node:fs";
const files = process.argv.slice(2);
if (files.length < 2) {
console.error("Usage: node delta-report.js dify.json cursor.json node-service.json");
process.exit(1);
}
const snapshots = files.map((file) => ({
file,
data: JSON.parse(fs.readFileSync(file, "utf8")),
}));
const fields = ["baseUrl", "apiKeyScope", "modelName", "requestPath"];
for (const field of fields) {
const values = new Map();
for (const item of snapshots) {
const value = item.data[field] || "missing";
if (!values.has(value)) values.set(value, []);
values.get(value).push(item.data.tool || item.file);
}
if (values.size > 1) {
console.log(`DELTA: ${field}`);
for (const [value, tools] of values.entries()) {
console.log(` ${value}: ${tools.join(", ")}`);
}
}
}
Run it:
node delta-report.js dify.json cursor.json node-service.json
The output is intentionally plain. If Dify and Cursor use one model name but Node.js uses another, the report shows it. If all tools use the same model name but one API Key scope is different, the report shows that too.
What to do with the report
Do not make the report a replacement for logs. Use it as the starting point for targeted checks.
| Delta | Why it matters | Next check |
|---|---|---|
| Base URL differs | One tool may be using another provider layer | Verify the OpenAI-compatible API gateway entry in the tool |
| API Key scope differs | Access, quota, or audit labels may differ | Confirm the key owner and intended environment |
| model name differs | The route may not exist for one tool | Replay a minimal Node.js request and check model_not_found |
| request path differs | A client may append /v1 twice or omit it |
Confirm the client library path behavior |
Add one live request after the diff
After the static comparison, send one tiny request through Vector Engine from Node.js. This proves the selected Base URL, API Key, and model name can produce a response.
const res = await fetch(`${process.env.BASE_URL}/v1/chat/completions`, {
method: "POST",
headers: {
authorization: `Bearer ${process.env.API_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
model: process.env.MODEL_NAME,
messages: [{ role: "user", content: "Say ok." }],
}),
});
const body = await res.json().catch(() => ({}));
console.log(res.status, body?.error?.code || body?.id);
If the code returns model_not_found, the next owner is the model route owner. If Node.js succeeds but Dify fails, the next owner is the Dify provider configuration. If Cursor fails alone, the next owner is the Cursor custom provider entry.
This gives the team a small operating pattern: compare the request contract, replay one request, then assign the fix to the field that changed.
Registration URL: https://api.vectorengine.cn/register?aff=Igym
在 model_not_found 影响用户之前,为向量引擎建立请求差异报告
一个共享的向量引擎配置通常从简单字段开始:一个 Base URL、每个工具一把 API Key,以及 Dify、Cursor 和 Node.js 都能使用的 model name。几次变更之后,情况会变复杂。workflow 负责人更新了 Dify,开发者调整了 Cursor,服务发布又修改了 Node.js 环境变量。等 model_not_found 出现时,团队需要一种紧凑方式看清到底改了什么。
这篇教程会建立一个请求差异报告,适合 OpenAI 兼容的向量引擎API中转站。它不保存 prompt,也不保存密钥,只对比 LLM API provider layer 中最关键的 provider 字段。
快照结构
为每个调用方创建一个 JSON 快照。字段要稳定,不要复杂。
{
"tool": "dify-workflow-a",
"baseUrl": "configured-openai-compatible-base-url",
"apiKeyScope": "workflow-production",
"modelName": "configured-model-route",
"requestPath": "/v1/chat/completions",
"owner": "workflow-team",
"lastChangedBy": "release-note-2026-07-20"
}
Dify 的快照来自 provider 设置和 workflow 备注。Cursor 的快照来自 custom provider 配置。Node.js 的快照可以在部署阶段导出。
一个小型 Node.js 差异脚本
把快照保存为 dify.json、cursor.json 和 node-service.json,然后进行对比。
import fs from "node:fs";
const files = process.argv.slice(2);
if (files.length < 2) {
console.error("Usage: node delta-report.js dify.json cursor.json node-service.json");
process.exit(1);
}
const snapshots = files.map((file) => ({
file,
data: JSON.parse(fs.readFileSync(file, "utf8")),
}));
const fields = ["baseUrl", "apiKeyScope", "modelName", "requestPath"];
for (const field of fields) {
const values = new Map();
for (const item of snapshots) {
const value = item.data[field] || "missing";
if (!values.has(value)) values.set(value, []);
values.get(value).push(item.data.tool || item.file);
}
if (values.size > 1) {
console.log(`DELTA: ${field}`);
for (const [value, tools] of values.entries()) {
console.log(` ${value}: ${tools.join(", ")}`);
}
}
}
运行方式:
node delta-report.js dify.json cursor.json node-service.json
输出会保持朴素。 如果 Dify 和 Cursor 使用一个 model name,而 Node.js 使用另一个,报告会显示出来。 如果所有工具使用同一个 model name,但其中一个 API Key 范围不同,报告也会显示出来。
如何使用报告
不要把差异报告当成日志替代品。它更适合作为定向排查的起点。
| 差异 | 为什么重要 | 下一步检查 |
|---|---|---|
| Base URL 不一致 | 某个工具可能接到了另一个 provider layer | 核对工具里的 OpenAI-compatible API gateway 配置 |
| API Key 范围不一致 | 访问权限、配额或审计标签可能不同 | 确认密钥负责人和目标环境 |
| model name 不一致 | 某个工具使用的路由可能不存在 | 用 Node.js 回放最小请求并检查 model_not_found |
| request path 不一致 | 客户端可能重复拼接 /v1 或遗漏路径 |
核对 client library 的路径行为 |
差异之后再加一次真实请求
完成静态对比后,再从 Node.js 通过向量引擎中转站发送一次小请求。这样可以证明选定的 Base URL、API Key 和 model name 确实可以得到响应。
const res = await fetch(`${process.env.BASE_URL}/v1/chat/completions`, {
method: "POST",
headers: {
authorization: `Bearer ${process.env.API_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
model: process.env.MODEL_NAME,
messages: [{ role: "user", content: "Say ok." }],
}),
});
const body = await res.json().catch(() => ({}));
console.log(res.status, body?.error?.code || body?.id);
如果代码返回 model_not_found,下一位负责人就是模型路由负责人。 如果 Node.js 成功但 Dify 失败,下一位负责人就是 Dify provider 配置。 如果只有 Cursor 失败,下一位负责人就是 Cursor custom provider 条目。
这会形成一个小型操作模式:先对比请求契约,再回放一次请求,然后把修复分配给发生变化的字段。
Top comments (0)