mirror of
https://github.com/modelstudioai/cli.git
synced 2026-09-14 19:49:23 +08:00
feat: model recommend use english output
This commit is contained in:
@@ -2,21 +2,21 @@ import { describe, expect, test } from "vite-plus/test";
|
||||
import { isDashScopeE2EReady, parseStdoutJson, runCli } from "./helpers.ts";
|
||||
|
||||
describe("e2e: advisor recommend", () => {
|
||||
test("advisor 分组展示子命令帮助且成功退出", async () => {
|
||||
test("advisor shows subcommand groups and exits successfully", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli(["advisor"]);
|
||||
expect(exitCode, stderr).toBe(0);
|
||||
expect(`${stdout}\n${stderr}`).toMatch(/advisor|recommend/i);
|
||||
});
|
||||
|
||||
test("advisor recommend --help 正常退出", async () => {
|
||||
test("advisor recommend --help exits successfully", async () => {
|
||||
const { stderr, exitCode } = await runCli(["advisor", "recommend", "--help"]);
|
||||
expect(exitCode, stderr).toBe(0);
|
||||
expect(stderr).toMatch(/recommend|--message|dry-run/i);
|
||||
});
|
||||
});
|
||||
|
||||
describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)", () => {
|
||||
test("advisor recommend 缺少 --message 时打印帮助并退出 (0)", async () => {
|
||||
describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", () => {
|
||||
test("advisor recommend without --message prints help and exits", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
@@ -26,13 +26,13 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
expect(`${stdout}\n${stderr}`).toMatch(/--message|Usage:/i);
|
||||
});
|
||||
|
||||
test("advisor recommend --dry-run 输出意图分析和候选列表", async () => {
|
||||
test("advisor recommend --dry-run outputs intent analysis and candidates", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
"--dry-run",
|
||||
"--message",
|
||||
"我想做一个能理解图片的客服机器人",
|
||||
"I want to build a customer service bot that understands images",
|
||||
"--non-interactive",
|
||||
"--output",
|
||||
"json",
|
||||
@@ -44,7 +44,7 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
candidateCount?: number;
|
||||
candidates?: Array<{ model?: string; score?: number }>;
|
||||
}>(stdout);
|
||||
expect(data.userInput).toBe("我想做一个能理解图片的客服机器人");
|
||||
expect(data.userInput).toBe("I want to build a customer service bot that understands images");
|
||||
expect(data.intent?.requiredCapabilities).toContain("VU");
|
||||
expect(data.intent?.inputModality).toContain("Image");
|
||||
expect(data.candidateCount).toBeGreaterThan(0);
|
||||
@@ -52,12 +52,12 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
expect(data.candidates?.[0]?.score).toBeGreaterThan(0);
|
||||
}, 60_000);
|
||||
|
||||
test("advisor recommend 完整推荐流程返回结果", async () => {
|
||||
test("advisor recommend full flow returns results", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
"--message",
|
||||
"低成本高并发的在线客服",
|
||||
"low-cost high-concurrency online customer service",
|
||||
"--non-interactive",
|
||||
"--output",
|
||||
"json",
|
||||
@@ -81,15 +81,15 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
expect(data.result?.recommendations?.[0]?.reason).toBeDefined();
|
||||
}, 120_000);
|
||||
|
||||
// ---- 模型偏好:正例 ----
|
||||
// ---- Model preference: positive cases ----
|
||||
|
||||
test("scoped 偏好 — 限定系列时 intent 含 modelPreference.mode=scoped", async () => {
|
||||
test("scoped preference — intent contains modelPreference.mode=scoped when family is specified", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
"--dry-run",
|
||||
"--message",
|
||||
"deepseek系列中哪个模型最适合用来进行快速推理",
|
||||
"Which model in the deepseek family is best for fast reasoning?",
|
||||
"--non-interactive",
|
||||
"--output",
|
||||
"json",
|
||||
@@ -107,13 +107,13 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
).toBe(true);
|
||||
}, 60_000);
|
||||
|
||||
test("comparison 偏好 — 对比模型时 intent 含 modelPreference.mode=comparison", async () => {
|
||||
test("comparison preference — intent contains modelPreference.mode=comparison when comparing models", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
"--dry-run",
|
||||
"--message",
|
||||
"qwen-max和deepseek-v3哪个更适合做代码生成",
|
||||
"Which is better for code generation, qwen-max or deepseek-v3?",
|
||||
"--non-interactive",
|
||||
"--output",
|
||||
"json",
|
||||
@@ -126,13 +126,13 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
expect(data.intent?.modelPreference?.targets?.length).toBeGreaterThanOrEqual(2);
|
||||
}, 60_000);
|
||||
|
||||
test("excludes 偏好 — 排除模型时 intent 识别出 modelPreference", async () => {
|
||||
test("excludes preference — intent detects modelPreference when excluding models", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
"--dry-run",
|
||||
"--message",
|
||||
"不要qwen,推荐一个适合文本生成的模型",
|
||||
"Not qwen, recommend a model suitable for text generation",
|
||||
"--non-interactive",
|
||||
"--output",
|
||||
"json",
|
||||
@@ -151,15 +151,15 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
|
||||
expect(hasExcludes).toBe(true);
|
||||
}, 60_000);
|
||||
|
||||
// ---- 模型偏好:反例 ----
|
||||
// ---- Model preference: negative cases ----
|
||||
|
||||
test("无偏好 — 普通需求查询时 intent 不含 modelPreference 或 mode=unconstrained", async () => {
|
||||
test("no preference — intent has no modelPreference or mode=unconstrained for generic queries", async () => {
|
||||
const { stdout, stderr, exitCode } = await runCli([
|
||||
"advisor",
|
||||
"recommend",
|
||||
"--dry-run",
|
||||
"--message",
|
||||
"我要做一个能理解图片的客服机器人",
|
||||
"I want to build a customer service bot that understands images",
|
||||
"--non-interactive",
|
||||
"--output",
|
||||
"json",
|
||||
|
||||
@@ -4,6 +4,8 @@ export const RANKING_MODEL_FAST = "qwen-flash";
|
||||
|
||||
export const INTENT_SYSTEM_PROMPT = `You are an intent analyzer. Given the user's requirement, understand the scenario first, then extract structured information.
|
||||
|
||||
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.
|
||||
|
||||
## Analysis Steps
|
||||
1. Summarize the user's core need in one sentence (taskSummary) — be specific about the scenario, not generic
|
||||
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.`;
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Background
|
||||
The system has pre-filtered candidate models based on intent analysis. Your job is to rank and pick from these candidates.
|
||||
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):
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Background
|
||||
The system has pre-filtered candidate models for each step's requirements.
|
||||
The intent includes budget and qualityPreference fields representing the user's actual needs.
|
||||
@@ -130,6 +136,8 @@ Or (if single model suffices):
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Background
|
||||
The user specified models to compare. The system has pre-filtered these models and related candidates into the list.
|
||||
The intent's modelPreference.targets are the models to compare.
|
||||
@@ -151,6 +159,8 @@ The intent's modelPreference.targets are the models to compare.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Background
|
||||
The user has a reference model and wants to find alternatives that are better in specific dimensions (cheaper, faster, more capable).
|
||||
The intent's modelPreference.targets is the reference model.
|
||||
|
||||
@@ -220,8 +220,8 @@ export async function rankModels(
|
||||
|
||||
const userMessage =
|
||||
intent.complexity === Complexities.Pipeline
|
||||
? `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models for each pipeline step.`
|
||||
: `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models.`;
|
||||
? `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.`
|
||||
: `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models. Respond in English only.`;
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
model: useThinkingModel ? RANKING_MODEL : RANKING_MODEL_FAST,
|
||||
|
||||
Reference in New Issue
Block a user