Probe Unicode and Markdown Serialization Before Dify, Cursor, and Node.js Share Vector Engine
A provider route can be healthy while the caller still sends text in a shape that the rest of the system cannot reproduce. This happens often when Dify templates, Cursor prompts, and a Node.js backend all prepare messages differently. Newlines, Chinese text, code fences, Markdown tables, and escaped JSON can change during handoff.
Before treating Vector Engine as the shared OpenAI-compatible API gateway and LLM API provider layer, add a serialization probe. It should send the same controlled message set from Node.js that your team expects from Dify and Cursor. The probe is not a benchmark. It is a reproducibility check for Base URL, API Key, model name, request body shape, and model_not_found handling.
Use this configuration:
VECTOR_ENGINE_BASE_URL=https://api.vectorengine.cn/v1
VECTOR_ENGINE_API_KEY=replace_with_your_key
VECTOR_ENGINE_MODEL=gpt-4o-mini
Then run a small Node.js script:
const baseUrl = process.env.VECTOR_ENGINE_BASE_URL;
const apiKey = process.env.VECTOR_ENGINE_API_KEY;
const model = process.env.VECTOR_ENGINE_MODEL;
const cases = [
{
name: "multilingual",
content: "Summarize this mixed text: English line\\n中文行\\n日本語の行"
},
{
name: "markdown-table",
content: "Return a two-row table for: | tool | owner |\\n| Dify | workflow |\\n| Cursor | engineer |"
},
{
name: "code-fence",
content: "Explain this snippet:\\n```
js\\nconsole.log(JSON.stringify({ route: 'Vector Engine' }))\\n
```"
}
];
async function runCase(testCase) {
const response = await fetch(`${baseUrl}/chat/completions`, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model,
messages: [
{ role: "system", content: "Reply in one concise paragraph and preserve the user's intent." },
{ role: "user", content: testCase.content }
],
temperature: 0.2
})
});
const text = await response.text();
let payload;
try {
payload = JSON.parse(text);
} catch {
return { name: testCase.name, ok: false, reason: "non_json", detail: text.slice(0, 120) };
}
if (!response.ok) {
return {
name: testCase.name,
ok: false,
reason: payload?.error?.code || payload?.code || response.status,
detail: payload
};
}
return {
name: testCase.name,
ok: Boolean(payload.choices?.[0]?.message?.content),
sample: payload.choices?.[0]?.message?.content?.slice(0, 160)
};
}
const results = [];
for (const testCase of cases) {
results.push(await runCase(testCase));
}
console.table(results);
const failed = results.find((item) => !item.ok);
if (failed) {
if (failed.reason === "model_not_found") {
console.error("model_not_found points to model routing or a copied model name, not Unicode itself.");
}
process.exit(1);
}
After the script passes, compare the same message shapes in Dify and Cursor:
| Surface | What to verify |
|---|---|
| Dify | Template variables should not remove line breaks or code fences before the request reaches Vector Engine. |
| Cursor | Custom provider settings should use the same Base URL and model name as Node.js. |
| Node.js |
JSON.stringify should produce the body shape you expect, with no accidental double escaping. |
| Logs | Store case names and status codes, not raw prompt content. |
This probe catches boring but expensive mistakes. If the multilingual case fails, inspect request encoding and template rendering. If only the code-fence case fails, check whether a tool layer rewrites Markdown. If every case returns model_not_found, confirm the model name and provider route before changing prompt logic.
Registration URL: https://api.vectorengine.cn/register?aff=Igym
供应商路由可以是健康的,但调用方发送的文本结构仍然可能无法被其他系统复现。这个问题常见于 Dify 模板、Cursor 提示词和 Node.js 后端各自用不同方式组织消息时。换行、中文文本、代码块、Markdown 表格、转义后的 JSON,都可能在交接时发生变化。
在把向量引擎作为共享的 OpenAI 兼容 API 网关和 LLM API provider layer 之前,可以先增加一个序列化探针。它应该从 Node.js 发送一组受控消息,模拟团队预期会从 Dify 和 Cursor 发出的内容。这个探针不是性能测试,而是对 Base URL、API Key、模型名、请求体结构和 model_not_found 处理方式的可复现性检查。
使用这份配置:
VECTOR_ENGINE_BASE_URL=https://api.vectorengine.cn/v1
VECTOR_ENGINE_API_KEY=replace_with_your_key
VECTOR_ENGINE_MODEL=gpt-4o-mini
然后运行一个小的 Node.js 脚本:
const baseUrl = process.env.VECTOR_ENGINE_BASE_URL;
const apiKey = process.env.VECTOR_ENGINE_API_KEY;
const model = process.env.VECTOR_ENGINE_MODEL;
const cases = [
{
name: "multilingual",
content: "Summarize this mixed text: English line\\n中文行\\n日本語の行"
},
{
name: "markdown-table",
content: "Return a two-row table for: | tool | owner |\\n| Dify | workflow |\\n| Cursor | engineer |"
},
{
name: "code-fence",
content: "Explain this snippet:\\n```
js\\nconsole.log(JSON.stringify({ route: 'Vector Engine' }))\\n
```"
}
];
async function runCase(testCase) {
const response = await fetch(`${baseUrl}/chat/completions`, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model,
messages: [
{ role: "system", content: "Reply in one concise paragraph and preserve the user's intent." },
{ role: "user", content: testCase.content }
],
temperature: 0.2
})
});
const text = await response.text();
let payload;
try {
payload = JSON.parse(text);
} catch {
return { name: testCase.name, ok: false, reason: "non_json", detail: text.slice(0, 120) };
}
if (!response.ok) {
return {
name: testCase.name,
ok: false,
reason: payload?.error?.code || payload?.code || response.status,
detail: payload
};
}
return {
name: testCase.name,
ok: Boolean(payload.choices?.[0]?.message?.content),
sample: payload.choices?.[0]?.message?.content?.slice(0, 160)
};
}
const results = [];
for (const testCase of cases) {
results.push(await runCase(testCase));
}
console.table(results);
const failed = results.find((item) => !item.ok);
if (failed) {
if (failed.reason === "model_not_found") {
console.error("model_not_found points to model routing or a copied model name, not Unicode itself.");
}
process.exit(1);
}
脚本通过后,再在 Dify 和 Cursor 中对比同样的消息结构:
| 表面 | 需要验证的内容 |
|---|---|
| Dify | 模板变量在请求到达向量引擎之前,不应删除换行或代码块。 |
| Cursor | 自定义供应商配置应与 Node.js 使用同一个 Base URL 和模型名。 |
| Node.js |
JSON.stringify 生成的请求体应符合预期,不能出现意外的二次转义。 |
| 日志 | 记录 case 名称和状态码,不记录原始提示词内容。 |
这个探针能发现无聊但昂贵的错误。如果多语言 case 失败,先检查请求编码和模板渲染。如果只有代码块 case 失败,检查是否有工具层改写了 Markdown。如果所有 case 都返回 model_not_found,先确认模型名和供应商路由,再调整提示词逻辑。
对于把 Dify、Cursor、Node.js 接入向量引擎API中转站的团队来说,这类检查能让向量引擎中转站不只是一个地址配置,而是一个可复查的 API中转站 交接点。
Top comments (0)