Skip to content

Commit 93cecc3

Browse files
committed
feat: model recommend use english output
1 parent c54f6a6 commit 93cecc3

3 files changed

Lines changed: 31 additions & 21 deletions

File tree

packages/cli/tests/e2e/advisor-recommend.e2e.test.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@ import { describe, expect, test } from "vite-plus/test";
22
import { isDashScopeE2EReady, parseStdoutJson, runCli } from "./helpers.ts";
33

44
describe("e2e: advisor recommend", () => {
5-
test("advisor 分组展示子命令帮助且成功退出", async () => {
5+
test("advisor shows subcommand groups and exits successfully", async () => {
66
const { stdout, stderr, exitCode } = await runCli(["advisor"]);
77
expect(exitCode, stderr).toBe(0);
88
expect(`${stdout}\n${stderr}`).toMatch(/advisor|recommend/i);
99
});
1010

11-
test("advisor recommend --help 正常退出", async () => {
11+
test("advisor recommend --help exits successfully", async () => {
1212
const { stderr, exitCode } = await runCli(["advisor", "recommend", "--help"]);
1313
expect(exitCode, stderr).toBe(0);
1414
expect(stderr).toMatch(/recommend|--message|dry-run/i);
1515
});
1616
});
1717

18-
describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommendDashScope", () => {
19-
test("advisor recommend 缺少 --message 时打印帮助并退出 (0)", async () => {
18+
describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", () => {
19+
test("advisor recommend without --message prints help and exits", async () => {
2020
const { stdout, stderr, exitCode } = await runCli([
2121
"advisor",
2222
"recommend",
@@ -26,13 +26,13 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
2626
expect(`${stdout}\n${stderr}`).toMatch(/--message|Usage:/i);
2727
});
2828

29-
test("advisor recommend --dry-run 输出意图分析和候选列表", async () => {
29+
test("advisor recommend --dry-run outputs intent analysis and candidates", async () => {
3030
const { stdout, stderr, exitCode } = await runCli([
3131
"advisor",
3232
"recommend",
3333
"--dry-run",
3434
"--message",
35-
"我想做一个能理解图片的客服机器人",
35+
"I want to build a customer service bot that understands images",
3636
"--non-interactive",
3737
"--output",
3838
"json",
@@ -44,20 +44,20 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
4444
candidateCount?: number;
4545
candidates?: Array<{ model?: string; score?: number }>;
4646
}>(stdout);
47-
expect(data.userInput).toBe("我想做一个能理解图片的客服机器人");
47+
expect(data.userInput).toBe("I want to build a customer service bot that understands images");
4848
expect(data.intent?.requiredCapabilities).toContain("VU");
4949
expect(data.intent?.inputModality).toContain("Image");
5050
expect(data.candidateCount).toBeGreaterThan(0);
5151
expect(data.candidates?.[0]?.model).toBeDefined();
5252
expect(data.candidates?.[0]?.score).toBeGreaterThan(0);
5353
}, 60_000);
5454

55-
test("advisor recommend 完整推荐流程返回结果", async () => {
55+
test("advisor recommend full flow returns results", async () => {
5656
const { stdout, stderr, exitCode } = await runCli([
5757
"advisor",
5858
"recommend",
5959
"--message",
60-
"低成本高并发的在线客服",
60+
"low-cost high-concurrency online customer service",
6161
"--non-interactive",
6262
"--output",
6363
"json",
@@ -81,15 +81,15 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
8181
expect(data.result?.recommendations?.[0]?.reason).toBeDefined();
8282
}, 120_000);
8383

84-
// ---- 模型偏好:正例 ----
84+
// ---- Model preference: positive cases ----
8585

86-
test("scoped 偏好限定系列时 intent modelPreference.mode=scoped", async () => {
86+
test("scoped preference — intent contains modelPreference.mode=scoped when family is specified", async () => {
8787
const { stdout, stderr, exitCode } = await runCli([
8888
"advisor",
8989
"recommend",
9090
"--dry-run",
9191
"--message",
92-
"deepseek系列中哪个模型最适合用来进行快速推理",
92+
"Which model in the deepseek family is best for fast reasoning?",
9393
"--non-interactive",
9494
"--output",
9595
"json",
@@ -107,13 +107,13 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
107107
).toBe(true);
108108
}, 60_000);
109109

110-
test("comparison 偏好对比模型时 intent modelPreference.mode=comparison", async () => {
110+
test("comparison preference — intent contains modelPreference.mode=comparison when comparing models", async () => {
111111
const { stdout, stderr, exitCode } = await runCli([
112112
"advisor",
113113
"recommend",
114114
"--dry-run",
115115
"--message",
116-
"qwen-max和deepseek-v3哪个更适合做代码生成",
116+
"Which is better for code generation, qwen-max or deepseek-v3?",
117117
"--non-interactive",
118118
"--output",
119119
"json",
@@ -126,13 +126,13 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
126126
expect(data.intent?.modelPreference?.targets?.length).toBeGreaterThanOrEqual(2);
127127
}, 60_000);
128128

129-
test("excludes 偏好排除模型时 intent 识别出 modelPreference", async () => {
129+
test("excludes preference — intent detects modelPreference when excluding models", async () => {
130130
const { stdout, stderr, exitCode } = await runCli([
131131
"advisor",
132132
"recommend",
133133
"--dry-run",
134134
"--message",
135-
"不要qwen,推荐一个适合文本生成的模型",
135+
"Not qwen, recommend a model suitable for text generation",
136136
"--non-interactive",
137137
"--output",
138138
"json",
@@ -151,15 +151,15 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
151151
expect(hasExcludes).toBe(true);
152152
}, 60_000);
153153

154-
// ---- 模型偏好:反例 ----
154+
// ---- Model preference: negative cases ----
155155

156-
test("无偏好 — 普通需求查询时 intent 不含 modelPreference mode=unconstrained", async () => {
156+
test("no preference — intent has no modelPreference or mode=unconstrained for generic queries", async () => {
157157
const { stdout, stderr, exitCode } = await runCli([
158158
"advisor",
159159
"recommend",
160160
"--dry-run",
161161
"--message",
162-
"我要做一个能理解图片的客服机器人",
162+
"I want to build a customer service bot that understands images",
163163
"--non-interactive",
164164
"--output",
165165
"json",

packages/core/src/advisor/constants/prompts.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ export const RANKING_MODEL_FAST = "qwen-flash";
44

55
export const INTENT_SYSTEM_PROMPT = `You are an intent analyzer. Given the user's requirement, understand the scenario first, then extract structured information.
66
7+
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. All text fields (taskSummary, scenarioHints) must be in English.
8+
79
## Analysis Steps
810
1. Summarize the user's core need in one sentence (taskSummary) — be specific about the scenario, not generic
911
2. Infer scenario hints (scenarioHints), e.g.: ["low-latency", "consumer-facing", "high-concurrency", "conversational", "offline-batch", "high-precision"]
@@ -50,6 +52,8 @@ Output only JSON, no other text.`;
5052

5153
export const SINGLE_SYSTEM_PROMPT = `You are a model recommendation advisor for Alibaba Cloud Model Studio. From the candidate models below, select the best recommendations.
5254
55+
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights, step, summary — must be written in English.
56+
5357
## Background
5458
The system has pre-filtered candidate models based on intent analysis. Your job is to rank and pick from these candidates.
5559
The intent includes budget and qualityPreference fields representing the user's actual needs.
@@ -91,6 +95,8 @@ Pipeline (only when confident multi-model is needed):
9195

9296
export const PIPELINE_SYSTEM_PROMPT = `You are a model recommendation advisor for Alibaba Cloud Model Studio. The user's need has been decomposed into multi-step pipeline. Select the best model for each step.
9397
98+
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights, step, summary — must be written in English.
99+
94100
## Background
95101
The system has pre-filtered candidate models for each step's requirements.
96102
The intent includes budget and qualityPreference fields representing the user's actual needs.
@@ -130,6 +136,8 @@ Or (if single model suffices):
130136

131137
export const COMPARISON_SYSTEM_PROMPT = `You are a model comparison advisor for Alibaba Cloud Model Studio. The user wants to compare specific models — analyze them against the use case.
132138
139+
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights — must be written in English.
140+
133141
## Background
134142
The user specified models to compare. The system has pre-filtered these models and related candidates into the list.
135143
The intent's modelPreference.targets are the models to compare.
@@ -151,6 +159,8 @@ The intent's modelPreference.targets are the models to compare.
151159

152160
export const ALTERNATIVE_SYSTEM_PROMPT = `You are a model alternative advisor for Alibaba Cloud Model Studio. The user has a reference model and wants to find alternatives.
153161
162+
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights — must be written in English.
163+
154164
## Background
155165
The user has a reference model and wants to find alternatives that are better in specific dimensions (cheaper, faster, more capable).
156166
The intent's modelPreference.targets is the reference model.

packages/core/src/advisor/recommend.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ export async function rankModels(
220220

221221
const userMessage =
222222
intent.complexity === Complexities.Pipeline
223-
? `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models for each pipeline step.`
224-
: `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models.`;
223+
? `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models for each pipeline step. Respond in English only.`
224+
: `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models. Respond in English only.`;
225225

226226
const body: Record<string, unknown> = {
227227
model: useThinkingModel ? RANKING_MODEL : RANKING_MODEL_FAST,

0 commit comments

Comments
 (0)