refactor(auth): remove deprecated AK/SK auth for knowledge retrieve

AK/SK signing was used only by `knowledge retrieve`'s deprecated fallback,
which the api-key auth gate now makes unreachable. Drop it; the command is
pure api-key.

- knowledge/retrieve: remove the AK/SK path + --access-key-id/secret/workspace-id
  flags; api-key only
- delete client/ak-sign.ts and its signRequest/AkSignConfig exports
- drop access_key_id/access_key_secret from config schema, loader, and
  `config show` / `config set`
- remove the now-unused PascalCase KnowledgeRetrieve request/response types
This commit is contained in:
若麒
2026-06-28 22:24:59 +08:00
parent 95eb07d04a
commit 2f9558c161
19 changed files with 65 additions and 478 deletions
-12
View File
@@ -156,18 +156,6 @@ Required for console capability commands (`app list`, `usage free`, `usage stats
bl auth login --console
```
### Alibaba Cloud AK/SK (Knowledge Base only)
Required for `knowledge retrieve`. Get your AccessKey from [RAM Console](https://ram.console.aliyun.com/manage/ak).
> Recommended: create a RAM sub-account with minimum privileges instead of using the root account's AK/SK.
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=LTAI5t...
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=...
export BAILIAN_WORKSPACE_ID=ws-...
```
## Configuration
```bash
-12
View File
@@ -151,18 +151,6 @@ bl text chat --api-key sk-xxxxx --message "你好"
bl auth login --console
```
### 阿里云 AK/SK仅知识库检索
`knowledge retrieve` 命令需要阿里云 AccessKey。前往 [RAM 控制台](https://ram.console.aliyun.com/manage/ak) 获取。
> 建议:创建 RAM 子账号并授予最小权限,避免使用主账号 AK/SK。
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=LTAI5t...
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=...
export BAILIAN_WORKSPACE_ID=ws-...
```
## 配置
```bash
-12
View File
@@ -156,18 +156,6 @@ Required for console capability commands (`app list`, `usage free`, `usage stats
bl auth login --console
```
### Alibaba Cloud AK/SK (Knowledge Base only)
Required for `knowledge retrieve`. Get your AccessKey from [RAM Console](https://ram.console.aliyun.com/manage/ak).
> Recommended: create a RAM sub-account with minimum privileges instead of using the root account's AK/SK.
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=LTAI5t...
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=...
export BAILIAN_WORKSPACE_ID=ws-...
```
## Configuration
```bash
-12
View File
@@ -151,18 +151,6 @@ bl text chat --api-key sk-xxxxx --message "你好"
bl auth login --console
```
### 阿里云 AK/SK仅知识库检索
`knowledge retrieve` 命令需要阿里云 AccessKey。前往 [RAM 控制台](https://ram.console.aliyun.com/manage/ak) 获取。
> 建议:创建 RAM 子账号并授予最小权限,避免使用主账号 AK/SK。
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=LTAI5t...
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=...
export BAILIAN_WORKSPACE_ID=ws-...
```
## 配置
```bash
-5
View File
@@ -30,11 +30,6 @@ DASHSCOPE_API_KEY=
# -------------------------------
BAILIAN_E2E_VIDEO_TASK_ID=b499a8cb-1fc4-4d43-9495-e23c7f78ae0d
# -------------------------------
# 阿里云 AK
ALIBABA_CLOUD_ACCESS_KEY_ID=
# 阿里云 SK
ALIBABA_CLOUD_ACCESS_KEY_SECRET=
# -------------------------------
# 知识库 ID
BAILIAN_WORKSPACE_ID=
# 索引 ID
+2 -14
View File
@@ -117,23 +117,11 @@ export function e2eLabelFromMetaUrl(metaUrl: string): string {
return basename(fileURLToPath(metaUrl), ".ts").replace(/\.e2e\.test$/, "");
}
/** 知识库用例:须显式索引 ID + API-KEY 或 AK/SK */
/** 知识库用例:须显式索引 ID + API-KEY */
export function isKnowledgeE2EReady(): boolean {
if (!isBailianE2EEnabled()) return false;
if (!process.env.BAILIAN_E2E_INDEX_ID) return false;
const hasApiKey = isDashScopeE2EReady();
const hasAkSk =
!!process.env.ALIBABA_CLOUD_ACCESS_KEY_ID && !!process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET;
return hasApiKey || hasAkSk;
}
export function isKnowledgeAkSkReady(): boolean {
return (
isBailianE2EEnabled() &&
!!process.env.ALIBABA_CLOUD_ACCESS_KEY_ID &&
!!process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET &&
!!process.env.BAILIAN_E2E_INDEX_ID
);
return isDashScopeE2EReady();
}
export interface RunCliResult {
@@ -35,7 +35,6 @@ describe("e2e: knowledge retrieve", () => {
expect(stderr).toMatch(/--query/i);
expect(stderr).toMatch(/--rerank-top-n/i);
expect(stderr).toMatch(/deprecated/i);
expect(stderr).toMatch(/--workspace-id/i);
});
test("缺少 --index-id 时打印帮助并退出 (0)", async () => {
@@ -82,8 +81,6 @@ describe("e2e: knowledge retrieve errors", () => {
{
DASHSCOPE_API_KEY: undefined,
DASHSCOPE_ACCESS_TOKEN: undefined,
ALIBABA_CLOUD_ACCESS_KEY_ID: undefined,
ALIBABA_CLOUD_ACCESS_KEY_SECRET: undefined,
BAILIAN_CONFIG_DIR: tmpdir(),
},
);
+2 -6
View File
@@ -21,15 +21,13 @@ const VALID_KEYS = [
"default_image_model",
"default_speech_model",
"default_omni_model",
"access_key_id",
"access_key_secret",
"workspace_id",
];
// Keys whose values are secrets. Their stored value must never be echoed back in
// cleartext (CI logs, pipes, shared terminals); show a masked form instead — the
// same policy `config show` and `auth status` already follow.
const SECRET_KEYS = new Set(["api_key", "access_token", "access_key_id", "access_key_secret"]);
const SECRET_KEYS = new Set(["api_key", "access_token"]);
// Allow hyphen-style keys (e.g. default-text-model → default_text_model)
const KEY_ALIASES: Record<string, string> = {
@@ -42,8 +40,6 @@ const KEY_ALIASES: Record<string, string> = {
"default-image-model": "default_image_model",
"default-speech-model": "default_speech_model",
"default-omni-model": "default_omni_model",
"access-key-id": "access_key_id",
"access-key-secret": "access_key_secret",
"workspace-id": "workspace_id",
};
@@ -56,7 +52,7 @@ export default defineCommand({
type: "string",
valueHint: "<key>",
description:
"Config key (base_url, output, output_dir, timeout, api_key, access_token, default_*_model, access_key_id, access_key_secret, workspace_id)",
"Config key (base_url, output, output_dir, timeout, api_key, access_token, default_*_model, workspace_id)",
required: true,
},
value: { type: "string", valueHint: "<value>", description: "Value to set", required: true },
@@ -27,11 +27,6 @@ export default defineCommand({
if (typeof result.api_key === "string") result.api_key = maskToken(result.api_key);
if (typeof result.access_token === "string")
result.access_token = maskToken(result.access_token);
if (typeof result.access_key_id === "string")
result.access_key_id = maskToken(result.access_key_id);
if (typeof result.access_key_secret === "string") {
result.access_key_secret = maskToken(result.access_key_secret);
}
emitResult(result, format);
},
@@ -1,27 +1,13 @@
import {
defineCommand,
knowledgeRetrievePath,
signRequest,
detectOutputFormat,
maskToken,
resolveApiKeyCredential,
trackingHeaders,
type Client,
type Config,
type Flags,
type FlagsDef,
type KnowledgeRetrieveRequest,
type KnowledgeRetrieveResponse,
type DashScopeKnowledgeRetrieveRequest,
type DashScopeKnowledgeRetrieveResponse,
type OutputFormat,
BailianError,
ExitCode,
} from "bailian-cli-core";
import { emitResult, emitBare } from "bailian-cli-runtime";
const BAILIAN_HOST = "bailian.cn-beijing.aliyuncs.com";
const RETRIEVE_FLAGS = {
indexId: {
type: "string",
@@ -67,87 +53,29 @@ const RETRIEVE_FLAGS = {
valueHint: "<n>",
description: "Number of results (deprecated, use --rerank-top-n)",
},
workspaceId: {
type: "string",
valueHint: "<id>",
description: "Bailian workspace ID (only needed for deprecated AK/SK auth)",
},
accessKeyId: {
type: "string",
valueHint: "<key>",
description: "Deprecated: use global --api-key instead",
},
accessKeySecret: {
type: "string",
valueHint: "<key>",
description: "Deprecated: use global --api-key instead",
},
} satisfies FlagsDef;
type RetrieveFlags = Flags<typeof RETRIEVE_FLAGS>;
export default defineCommand({
description: "Retrieve from a Bailian knowledge base",
auth: "apiKey",
usageArgs: "--index-id <id> --query <text> [flags]",
flags: RETRIEVE_FLAGS,
notes: [
"Authentication: pass `--api-key <key>`. AK/SK auth is deprecated and will be removed in a future version.",
"`--workspace-id` is NOT required when using --api-key.",
],
exampleArgs: [
'--index-id idx_xxx --query "How to use Alibaba Cloud Bailian"',
'--api-key $DASHSCOPE_API_KEY --index-id idx_xxx --query "RAG retrieval" --rerank --rerank-model qwen3-rerank-hybrid',
'--index-id idx_xxx --query "RAG retrieval" --rerank --rerank-model qwen3-rerank-hybrid',
],
async run(ctx) {
const { config, flags } = ctx;
const indexId = flags.indexId;
const query = flags.query;
const format = detectOutputFormat(config.output);
const hasExplicitApiKey = !!config.apiKey;
const hasExplicitAkSk = !!(flags.accessKeyId && flags.accessKeySecret);
if (hasExplicitApiKey) {
await runWithApiKey(ctx.client, config, flags, indexId, query, format);
} else if (hasExplicitAkSk) {
await runWithAkSk(config, flags, indexId, query, format);
} else {
let useApiKey = false;
try {
await resolveApiKeyCredential(config);
useApiKey = true;
} catch {
// No API-KEY credential available
}
if (useApiKey) {
await runWithApiKey(ctx.client, config, flags, indexId, query, format);
} else {
await runWithAkSk(config, flags, indexId, query, format);
}
}
},
});
// ---- API-KEY path (DashScope gateway, snake_case) ----
async function runWithApiKey(
client: Client,
config: Config,
flags: RetrieveFlags,
indexId: string,
query: string,
format: OutputFormat,
): Promise<void> {
if (flags.topK !== undefined && flags.rerankTopN === undefined) {
process.stderr.write("Warning: --top-k is deprecated. Use --rerank-top-n instead.\n");
flags.rerankTopN = flags.topK;
}
const body: DashScopeKnowledgeRetrieveRequest = {
index_id: indexId,
query,
index_id: flags.indexId,
query: flags.query,
search_filters: [],
};
@@ -168,11 +96,11 @@ async function runWithApiKey(
}
if (config.dryRun) {
emitResult({ endpoint: client.url(knowledgeRetrievePath()), request: body }, format);
emitResult({ endpoint: ctx.client.url(knowledgeRetrievePath()), request: body }, format);
return;
}
const response = await client.requestJson<DashScopeKnowledgeRetrieveResponse>({
const response = await ctx.client.requestJson<DashScopeKnowledgeRetrieveResponse>({
path: knowledgeRetrievePath(),
method: "POST",
body,
@@ -184,140 +112,15 @@ async function runWithApiKey(
} else {
emitResult(response, format);
}
}
// ---- AK/SK path (Bailian OpenAPI gateway, PascalCase) ----
async function runWithAkSk(
config: Config,
flags: RetrieveFlags,
indexId: string,
query: string,
format: OutputFormat,
): Promise<void> {
const accessKeyId = flags.accessKeyId || config.accessKeyId;
const accessKeySecret = flags.accessKeySecret || config.accessKeySecret;
const workspaceId = flags.workspaceId || config.workspaceId;
if (!accessKeyId || !accessKeySecret) {
throw new BailianError(
"No credentials found.\n" +
"Preferred: set DASHSCOPE_API_KEY or pass --api-key.\n" +
"Legacy (deprecated): set ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET.",
ExitCode.AUTH,
);
}
if (!workspaceId) {
throw new BailianError(
"Knowledge retrieve requires a workspace ID.\n" +
`Set via: --workspace-id flag, or env: BAILIAN_WORKSPACE_ID, or config: ${config.binName} config set workspace_id <id>`,
ExitCode.USAGE,
);
}
process.stderr.write(
"Warning: AK/SK auth for knowledge retrieve is deprecated. Prefer --api-key or DASHSCOPE_API_KEY.\n",
);
const body: KnowledgeRetrieveRequest = {
IndexId: indexId,
Query: query,
};
if (flags.topK !== undefined && flags.rerankTopN === undefined) {
process.stderr.write("Warning: --top-k is deprecated. Use --rerank-top-n instead.\n");
flags.rerankTopN = flags.topK;
}
if (flags.rerank) body.EnableReranking = true;
if (flags.rerankTopN !== undefined) body.RerankTopN = flags.rerankTopN;
if (flags.denseSimilarityTopK !== undefined) body.DenseSimilarityTopK = flags.denseSimilarityTopK;
if (flags.sparseSimilarityTopK !== undefined)
body.SparseSimilarityTopK = flags.sparseSimilarityTopK;
if (flags.rerankModel) {
const rerank: { ModelName: string; RerankMode?: string; RerankInstruct?: string } = {
ModelName: flags.rerankModel,
};
if (flags.rerankMode) rerank.RerankMode = flags.rerankMode;
if (flags.rerankInstruct) rerank.RerankInstruct = flags.rerankInstruct;
body.Rerank = [rerank];
}
const pathname = `/${workspaceId}/index/retrieve`;
if (config.dryRun) {
emitResult(
{
endpoint: `https://${BAILIAN_HOST}${pathname}`,
workspaceId,
request: body,
},
format,
);
return;
}
const bodyStr = JSON.stringify(body);
const headers = signRequest({
accessKeyId,
accessKeySecret,
action: "Retrieve",
version: "2023-12-29",
body: bodyStr,
host: BAILIAN_HOST,
pathname,
});
const url = `https://${BAILIAN_HOST}${pathname}`;
if (config.verbose) {
process.stderr.write(`> POST ${url}\n`);
process.stderr.write(`> AK: ${maskToken(accessKeyId)}\n`);
}
const timeoutMs = config.timeout * 1000;
const res = await fetch(url, {
method: "POST",
headers: { ...headers, ...trackingHeaders() },
body: bodyStr,
signal: AbortSignal.timeout(timeoutMs),
});
if (config.verbose) {
process.stderr.write(`< ${res.status} ${res.statusText}\n`);
}
const data = (await res.json()) as KnowledgeRetrieveResponse & {
Code?: string;
Message?: string;
};
if (!res.ok || (data.Code && data.Code !== "Success")) {
throw new BailianError(
`Knowledge retrieve failed: ${data.Code || res.status} - ${data.Message || res.statusText}`,
ExitCode.GENERAL,
);
}
const nodes = data.Data?.Nodes || [];
if (config.quiet || format === "text") {
emitTextNodes(nodes.map((n) => ({ text: n.Text, score: n.Score })));
} else {
emitResult(data, format);
}
}
// ---- Shared text output ----
});
function emitTextNodes(nodes: Array<{ text: string; score: number }>): void {
if (nodes.length === 0) {
emitBare("No results found.");
} else {
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
const node = nodes[i]!;
emitBare(`[${i + 1}] (score: ${node.score.toFixed(4)})`);
emitBare(node.text);
emitBare("");
-80
View File
@@ -1,80 +0,0 @@
/**
* Alibaba Cloud V3 Signature (ROA style) for Bailian Cloud API.
*
* Used by Knowledge Base Retrieve API which requires AK/SK authentication
* instead of Bearer token.
*
* Reference: https://help.aliyun.com/document_detail/2712195.html
*/
import { createHmac, createHash, randomUUID } from "crypto";
export interface AkSignConfig {
accessKeyId: string;
accessKeySecret: string;
action: string;
version: string;
body: string;
host: string;
pathname: string;
method?: string;
}
export function signRequest(cfg: AkSignConfig): Record<string, string> {
const method = cfg.method ?? "POST";
const now = new Date();
const dateISO = now.toISOString().replace(/\.\d{3}Z$/, "Z");
const nonce = randomUUID();
const hashedBody = sha256Hex(cfg.body);
const headers: Record<string, string> = {
host: cfg.host,
"x-acs-action": cfg.action,
"x-acs-version": cfg.version,
"x-acs-date": dateISO,
"x-acs-signature-nonce": nonce,
"x-acs-content-sha256": hashedBody,
"content-type": "application/json",
};
// Build canonical headers (sorted, lowercase)
const signedHeaderKeys = Object.keys(headers)
.filter((k) => k === "host" || k === "content-type" || k.startsWith("x-acs-"))
.sort();
const canonicalHeaders = signedHeaderKeys.map((k) => `${k}:${headers[k]}`).join("\n") + "\n";
const signedHeadersStr = signedHeaderKeys.join(";");
// Build canonical request
const canonicalRequest = [
method,
cfg.pathname,
"", // query string (empty for POST)
canonicalHeaders,
signedHeadersStr,
hashedBody,
].join("\n");
// Build string to sign
const algorithm = "ACS3-HMAC-SHA256";
const hashedCanonical = sha256Hex(canonicalRequest);
const stringToSign = `${algorithm}\n${hashedCanonical}`;
// Calculate signature
const signature = hmacSHA256Hex(cfg.accessKeySecret, stringToSign);
headers["authorization"] =
`${algorithm} Credential=${cfg.accessKeyId},SignedHeaders=${signedHeadersStr},Signature=${signature}`;
return headers;
}
function sha256Hex(data: string): string {
return createHash("sha256").update(data, "utf8").digest("hex");
}
function hmacSHA256Hex(key: string, data: string): string {
return createHmac("sha256", key).update(data, "utf8").digest("hex");
}
-2
View File
@@ -1,5 +1,3 @@
export type { AkSignConfig } from "./ak-sign.ts";
export { signRequest } from "./ak-sign.ts";
export {
appCompletionPath,
chatPath,
-3
View File
@@ -69,9 +69,6 @@ export function loadConfig(flags: GlobalFlags): Config {
defaultImageModel: file.default_image_model,
defaultSpeechModel: file.default_speech_model,
defaultOmniModel: file.default_omni_model,
accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID || file.access_key_id || undefined,
accessKeySecret:
process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET || file.access_key_secret || undefined,
workspaceId: process.env.BAILIAN_WORKSPACE_ID || file.workspace_id || undefined,
consoleSite: (flags.consoleSite as Config["consoleSite"]) || file.console_site || undefined,
consoleRegion: (flags.consoleRegion as string) || file.console_region || undefined,
-8
View File
@@ -27,8 +27,6 @@ export interface ConfigFile {
default_image_model?: string;
default_speech_model?: string;
default_omni_model?: string;
access_key_id?: string;
access_key_secret?: string;
workspace_id?: string;
console_site?: "domestic" | "international";
console_region?: string;
@@ -80,10 +78,6 @@ export function parseConfigFile(raw: unknown): ConfigFile {
out.default_speech_model = obj.default_speech_model;
if (typeof obj.default_omni_model === "string" && obj.default_omni_model.length > 0)
out.default_omni_model = obj.default_omni_model;
if (typeof obj.access_key_id === "string" && obj.access_key_id.length > 0)
out.access_key_id = obj.access_key_id;
if (typeof obj.access_key_secret === "string" && obj.access_key_secret.length > 0)
out.access_key_secret = obj.access_key_secret;
if (typeof obj.workspace_id === "string" && obj.workspace_id.length > 0)
out.workspace_id = obj.workspace_id;
if (typeof obj.console_site === "string" && VALID_CONSOLE_SITES.has(obj.console_site))
@@ -121,8 +115,6 @@ export interface Config {
defaultImageModel?: string;
defaultSpeechModel?: string;
defaultOmniModel?: string;
accessKeyId?: string;
accessKeySecret?: string;
workspaceId?: string;
consoleSite?: "domestic" | "international";
consoleRegion?: string;
-36
View File
@@ -352,42 +352,6 @@ export interface UserProfileResponse {
};
}
// ---- Knowledge Retrieve (Bailian Cloud API) ----
export interface KnowledgeRetrieveRequest {
IndexId: string;
Query: string;
DenseSimilarityTopK?: number;
SparseSimilarityTopK?: number;
EnableReranking?: boolean;
EnableRewrite?: boolean;
RerankTopN?: number;
TopK?: number;
Rerank?: Array<{
ModelName?: string;
RerankMode?: string;
RerankInstruct?: string;
}>;
RerankTopN_legacy?: number;
SearchFilters?: Array<{
Key: string;
Value: string;
Operator: string;
}>;
}
export interface KnowledgeRetrieveResponse {
Success: boolean;
RequestId: string;
Data: {
Nodes: Array<{
Text: string;
Score: number;
Metadata: Record<string, unknown>;
}>;
};
}
// ---- Knowledge Retrieve (DashScope protocol — snake_case) ----
export interface DashScopeKnowledgeRetrieveRequest {
-2
View File
@@ -30,8 +30,6 @@ export type {
DashScopeVideoEditRequest,
DashScopeVideoRefRequest,
DashScopeVideoRequest,
KnowledgeRetrieveRequest,
KnowledgeRetrieveResponse,
MemoryAddRequest,
MemoryAddResponse,
MemoryMessage,
+1 -1
View File
@@ -55,7 +55,7 @@ Do not guess flags — use the reference files or `--help`.
| Bailian agent / workflow | `bl app call` | Needs `--app-id` |
| Find app by name | `bl app list` then `bl app call` | Console auth |
| Memory CRUD / profile | `bl memory *` | [`reference/memory.md`](reference/memory.md) |
| Knowledge RAG | `bl knowledge retrieve` | RAM AK/SK + index ID |
| Knowledge RAG | `bl knowledge retrieve` | API key + index ID |
| Upload file to temp OSS | `bl file upload` | When you need `oss://` URL explicitly |
| Model selection / recommendation | `bl advisor recommend` | Intent → candidate recall → LLM ranking |
| MCP tool discovery / call | `bl mcp list` / `tools` / `call` | Bailian MCP marketplace |
+2 -2
View File
@@ -25,8 +25,8 @@ Index: [index.md](index.md)
#### Flags
| Flag | Type | Required | Description |
| ----------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `--key <key>` | string | yes | Config key (base*url, output, output_dir, timeout, api_key, access_token, default*\*\_model, access_key_id, access_key_secret, workspace_id) |
| ----------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------- |
| `--key <key>` | string | yes | Config key (base*url, output, output_dir, timeout, api_key, access_token, default*\*\_model, workspace_id) |
| `--value <value>` | string | yes | Value to set |
#### Examples
+2 -10
View File
@@ -24,7 +24,7 @@ Index: [index.md](index.md)
#### Flags
| Flag | Type | Required | Description |
| ------------------------------- | ------ | -------- | ------------------------------------------------------------ |
| ------------------------------- | ------ | -------- | -------------------------------------------------- |
| `--index-id <id>` | string | yes | Knowledge base index ID (required) |
| `--query <text>` | string | yes | Search query (required) |
| `--dense-similarity-top-k <n>` | number | no | Dense retrieval top K |
@@ -35,14 +35,6 @@ Index: [index.md](index.md)
| `--rerank-mode <mode>` | string | no | Rerank mode: qa, similar, or custom |
| `--rerank-instruct <text>` | string | no | Custom rerank instruction, when mode=custom |
| `--top-k <n>` | number | no | Number of results (deprecated, use --rerank-top-n) |
| `--workspace-id <id>` | string | no | Bailian workspace ID (only needed for deprecated AK/SK auth) |
| `--access-key-id <key>` | string | no | Deprecated: use global --api-key instead |
| `--access-key-secret <key>` | string | no | Deprecated: use global --api-key instead |
#### Notes
- Authentication: pass `--api-key <key>`. AK/SK auth is deprecated and will be removed in a future version.
- `--workspace-id` is NOT required when using --api-key.
#### Examples
@@ -51,5 +43,5 @@ bl knowledge retrieve --index-id idx_xxx --query "How to use Alibaba Cloud Baili
```
```bash
bl knowledge retrieve --api-key $DASHSCOPE_API_KEY --index-id idx_xxx --query "RAG retrieval" --rerank --rerank-model qwen3-rerank-hybrid
bl knowledge retrieve --index-id idx_xxx --query "RAG retrieval" --rerank --rerank-model qwen3-rerank-hybrid
```