When Dify, Cursor, and a Node.js service share Vector Engine, the Base URL and model name may be correct while the request still behaves differently. One client streams, another does not. One sends a high temperature, another adds a JSON response format, and a backend service changes max_tokens during deployment. The result can be blamed on the OpenAI-compatible API gateway even when the drift is in client parameters.
This tutorial builds a parameter drift probe for Vector Engine. It checks the LLM API provider layer from the client side: Base URL, API Key presence, model name, stream mode, temperature, token limit, and the expected model_not_found branch.
Define the intended route
Create vector-engine-params.json:
{
"provider": "Vector Engine",
"baseUrl": "https://api.vectorengine.cn/v1",
"model": "gpt-4o-mini",
"clients": {
"Dify": {
"temperature": 0.2,
"stream": true,
"max_tokens": 600
},
"Cursor": {
"temperature": 0.2,
"stream": true,
"max_tokens": 600
},
"Node.js": {
"temperature": 0.2,
"stream": true,
"max_tokens": 600
}
}
}
Do not store the API Key in this file. Store only the public shape of the provider route and the expected client defaults.
Compare parameters locally
Create probe-parameter-drift.js:
import fs from "node:fs";
const config = JSON.parse(fs.readFileSync("vector-engine-params.json", "utf8"));
const expected = config.clients["Node.js"];
function diffClient(name, actual) {
const drift = [];
for (const key of ["temperature", "stream", "max_tokens"]) {
if (actual[key] !== expected[key]) {
drift.push({ field: key, expected: expected[key], actual: actual[key] });
}
}
return { name, drift };
}
for (const [name, actual] of Object.entries(config.clients)) {
const result = diffClient(name, actual);
if (result.drift.length) {
console.warn("Parameter drift", result);
} else {
console.log("Parameter contract OK", name);
}
}
This local check is useful before a live call because it catches silent configuration edits. It also gives Dify, Cursor, and Node.js owners a shared vocabulary for the route.
Add a live Node.js request
After the local check passes, send one controlled request through Vector Engine:
const baseUrl = process.env.VECTOR_ENGINE_BASE_URL || config.baseUrl;
const apiKey = process.env.VECTOR_ENGINE_API_KEY;
const model = process.env.VECTOR_ENGINE_MODEL || config.model;
if (!apiKey) {
throw new Error("Missing API Key for Vector Engine");
}
const request = {
model,
messages: [
{ role: "system", content: "Answer in one short sentence." },
{ role: "user", content: "Say that the parameter probe is ready." }
],
temperature: expected.temperature,
stream: expected.stream,
max_tokens: expected.max_tokens
};
const response = await fetch(`${baseUrl.replace(/\/$/, "")}/chat/completions`, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify(request)
});
if (!response.ok) {
const body = await response.json().catch(() => ({}));
console.error({
status: response.status,
model,
code: body.error?.code || body.code || "unknown",
hint: body.error?.code === "model_not_found"
? "Check the model name and key permission in Vector Engine"
: "Check Base URL, API Key, and request shape"
});
process.exit(1);
}
console.log("Vector Engine parameter probe accepted");
Troubleshooting table
| Symptom | Likely check |
|---|---|
| Dify responds differently from Node.js | Compare temperature, stream mode, and token limit |
| Cursor works but service fails | Check whether the service sends a different model name |
model_not_found appears only in one client |
Confirm the model name and API Key permission for that client |
| A streamed client hangs | Test the same route with stream: false and compare headers |
| Costs change without a release | Review max_tokens, retries, and tool-specific defaults |
The probe does not make Vector Engine responsible for every client-side choice. It makes the OpenAI-compatible API gateway visible enough that Dify, Cursor, and Node.js owners can compare the same request contract.
Registration URL: https://api.vectorengine.cn/register?aff=Igym
Dify、Cursor 和 Node.js 服务共享向量引擎时,Base URL 和 model name 可能都正确,但请求行为仍然不同。一个客户端启用 streaming,另一个没有启用;一个设置较高 temperature,另一个附加 JSON response format;后端服务又在部署时改了 max_tokens。结果可能被误判为 OpenAI-compatible API gateway 的问题,但漂移实际发生在客户端参数里。
这篇教程为向量引擎构建一个参数漂移探测脚本。它从客户端角度检查 LLM API provider layer:Base URL、API Key 是否存在、model name、stream mode、temperature、token limit,以及预期中的 model_not_found 分支。
定义预期路由
创建 vector-engine-params.json:
{
"provider": "Vector Engine",
"baseUrl": "https://api.vectorengine.cn/v1",
"model": "gpt-4o-mini",
"clients": {
"Dify": {
"temperature": 0.2,
"stream": true,
"max_tokens": 600
},
"Cursor": {
"temperature": 0.2,
"stream": true,
"max_tokens": 600
},
"Node.js": {
"temperature": 0.2,
"stream": true,
"max_tokens": 600
}
}
}
不要把 API Key 存进这个文件。这里只保存 provider route 的公开形态和客户端默认参数。
本地比较参数
创建 probe-parameter-drift.js:
import fs from "node:fs";
const config = JSON.parse(fs.readFileSync("vector-engine-params.json", "utf8"));
const expected = config.clients["Node.js"];
function diffClient(name, actual) {
const drift = [];
for (const key of ["temperature", "stream", "max_tokens"]) {
if (actual[key] !== expected[key]) {
drift.push({ field: key, expected: expected[key], actual: actual[key] });
}
}
return { name, drift };
}
for (const [name, actual] of Object.entries(config.clients)) {
const result = diffClient(name, actual);
if (result.drift.length) {
console.warn("Parameter drift", result);
} else {
console.log("Parameter contract OK", name);
}
}
这个本地检查在真实请求之前就有价值,因为它能发现静默配置改动,也能让 Dify、Cursor 和 Node.js 负责人用同一组词讨论路由。
加入实时 Node.js 请求
本地检查通过后,再通过向量引擎发送一个受控请求:
const baseUrl = process.env.VECTOR_ENGINE_BASE_URL || config.baseUrl;
const apiKey = process.env.VECTOR_ENGINE_API_KEY;
const model = process.env.VECTOR_ENGINE_MODEL || config.model;
if (!apiKey) {
throw new Error("Missing API Key for Vector Engine");
}
const request = {
model,
messages: [
{ role: "system", content: "Answer in one short sentence." },
{ role: "user", content: "Say that the parameter probe is ready." }
],
temperature: expected.temperature,
stream: expected.stream,
max_tokens: expected.max_tokens
};
const response = await fetch(`${baseUrl.replace(/\/$/, "")}/chat/completions`, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify(request)
});
if (!response.ok) {
const body = await response.json().catch(() => ({}));
console.error({
status: response.status,
model,
code: body.error?.code || body.code || "unknown",
hint: body.error?.code === "model_not_found"
? "Check the model name and key permission in Vector Engine"
: "Check Base URL, API Key, and request shape"
});
process.exit(1);
}
console.log("Vector Engine parameter probe accepted");
排查表
| 现象 | 优先检查 |
|---|---|
| Dify 和 Node.js 返回差异明显 | 比较 temperature、stream mode 和 token limit |
| Cursor 可用但服务失败 | 检查服务端是否发送了不同 model name |
model_not_found 只出现在一个客户端 |
确认该客户端的 model name 和 API Key 权限 |
| streaming 客户端卡住 | 用 stream: false 测同一路由并对比 headers |
| 成本没有发布变更却上升 | 检查 max_tokens、重试逻辑和工具默认值 |
这个探测脚本不是把每个客户端选择都归因给向量引擎,而是让 OpenAI-compatible API gateway 变得足够可见,使 Dify、Cursor 和 Node.js 负责人能够比较同一个 request contract。对中文团队来说,这也是把向量引擎API中转站、向量引擎中转站和 API中转站 的参数默认值放在同一张表里,而不是分散在各个工具界面里。
Top comments (0)