Skip to main content

Knowledge Chat

Knowledge Base-grounded Q&A. Streams the answer over SSE in three phases: planning, tool calling, and generation.

Overview

  • Permissions: This API requires an Alibaba Cloud Model Studio API Key and a workspace. Obtain them on the API Key page and the Workspace Management page in the console.
  • Call method: HTTP REST, POST + application/json. The Base URL is https://{workspaceId}.cn-beijing.maas.aliyuncs.com, where {workspaceId} is the workspace ID.
  • Prerequisites: Create and publish a Knowledge Q&A service on the Knowledge Q&A service page in the console to obtain the application ID (agent_id); otherwise an Agent-not-published error is reported.
  • Multi-turn context: The platform does not persist conversation state — pass the full messages history on every request. Cap the history length (e.g. the last 10 turns) to stay within the model's context window. The response does not return session_id.
  • Streaming required: stream must be true; the current version supports only streaming responses. Passing false or leaving it empty fails the request.
  • In-chat files: After enabling in-chat file parsing in the console, you can pass files mid-conversation via parameters.agent_options.session_files (up to 10). File IDs are obtained through the addFile endpoint.
  • Rate limit: 25 QPS per user by default. If throttled, retry later.

Request Syntax

POST /api/v2/apps/knowledge/chat HTTP/1.1
Host: {workspaceId}.cn-beijing.maas.aliyuncs.com
Authorization: Bearer <API-Key>
Content-Type: application/json
Accept: text/event-stream

Request Parameters

The request body consists of three parts: input, parameters, and stream. Nested fields are shown with their hierarchy in the table below.

Name

Type

Required

Description

Example

input

object

Yes

Input parameters.

input.messages

array<object>

Yes

Conversation message list, in DashScope standard format.

messages[].role

string

Yes

Message role: user or assistant.

user

messages[].content

string\|array

Yes

Message content. Either a plain-text string or a multimodal array of ContentPart (e.g. [{"type":"text","text":"..."},{"type":"image_url","image_url":{"url":"..."}}]).

input.request_id

string

No

Custom request ID set by the caller.

parameters

object

Yes

Configuration parameters.

parameters.agent_options

object

Yes

Agent-specific options, including agent_id.

agent_options.agent_id

string

Yes

Q&A service (agent) application ID. Create and publish it on the Knowledge Q&A page in the console.

aid-xxxxxxxxxxxxxxxx

agent_options.session_files

array<string>

No

Session file ID list, up to 10. Only takes effect after enabling in-chat file parsing in the console; file IDs are obtained via the addFile (register file) endpoint.

agent_options.enable_cache_control

boolean

No

Whether to enable explicit context caching (KV Cache). When true, the request sets a cache breakpoint and deterministically hits the cache whenever the prefix matches — cached input tokens are billed at a discounted rate and time-to-first-token is reduced. When false (default), no breakpoint is set and any hit depends on the model's implicit caching capability. Only one cache mode applies per request; see Context Caching.

false

stream

boolean

Yes

Whether to stream the output. Must be true — the current version supports only streaming; passing false or omitting it fails the request.

true

Response Parameters

Top-level fields

Name

Type

Description

output

object

Model output.

output.request_id

string

Custom request ID set by the caller (mirrors the request's input.request_id).

output.choices

array<object>

Model output. Always length 1. See the table below for the structure.

code

string

Status code; 200 on success.

message

string

Status message; Success on success.

request_id

string

Request ID (DashScope platform-level; constant across the stream).

usage

object

Token usage (input_tokens / output_tokens / total_tokens / cached_tokens). Only present on settlement frames such as tool_calling and generation_end; ordinary stream chunks do not carry it. cached_tokens is the number of input tokens that hit the context cache in this request, accumulated across the multiple model calls; see Context Caching for how to enable it.

output.choices[] structure

Name

Type

Description

message

object

A single message, containing the model reply, tool call info, and the current phase.

message.role

string

Role: user, assistant, tool.

message.content

string\|array

Generated content / tool return content. During planning it is the planning text stream; during generating it is the answer text stream; boundary frames can be an empty string. Can also be a multimodal array.

message.id

string

Unique ID for this run (e.g. run--xxxx); constant within a turn.

message.type

string

Message type: ai (assistant frame: thinking/planning/generation) or tool (tool return frame).

message.tool_calls

array<object>

Tool call info. Only present on tool_calling frames; [] otherwise. Each element has index / id / type (always function) / function.name / function.arguments (a JSON string — parse twice).

message.tool_call_id

string

Tool return frame: matches tool_calls[].id, linking the trigger frame to the return frame.

message.additional_kwargs

object

Additional kwargs. {} on assistant frames; tool frames carry extra_json — the structured tool result (for retrieval tools, a docs chunk array).

message.extra

object

Step state info. See the table below.

message.response_metadata

object

Model call details. Boundary frames carry agent_name, request_id, and sometimes model_name, finish_reason; ordinary chunks are {}.

finish_reason

string

Finish reason. stop only on the final frame; "" during streaming.

message.extra structure

Name

Type

Description

group

string

Top-level phase: planning (with start and end events) or generating (with start and end events). During tool calling the top-level phase stays planning; only the finer-grained step switches to tool_calling.

step

string

Current step: planning, tool_calling, generating. step_change is sometimes not returned — rely on step instead.

step_change

string

Step transition event: plan_start / plan_end / tool_calling / tool_return / generation_start / generation_end, or empty (in progress). May be absent on empty frames.

Execution phases (group)

group

Description

planning

Planning; includes start and end events.

generating

Generating; includes start and end events.

Current step (step)

step

Description

planning

Planning.

tool_calling

Tool calling (group stays planning).

generating

Generating.

Step transition events (step_change)

step

step_change

Event

Description

planning

plan_start

Plan start

step becomes planning; subsequent content is the planning text.

planning

empty

Planning

content is the planning text stream.

planning

plan_end

Plan end

step is about to change; still planning at this event.

tool_calling

tool_calling

Tool call

Emits the full tool_calls (name and arguments); carries this round's usage.

tool_calling

tool_return

Tool return

role is tool; content is a result summary; additional_kwargs.extra_json is the structured result (docs for retrieval).

generating

generation_start

Generation start

Subsequent content is the final answer text stream.

generating

empty

Generating

content is the answer text stream.

generating

generation_end

Generation end

finish_reason is stop; carries the final usage.

Tool catalog During the tool-calling phase the model picks from the tools below; the tool name is in tool_calls[].function.name. arguments is a JSON string — parse it once more to get the actual parameters. The tool result lives in the tool_return frame's additional_kwargs.extra_json.docs.

function.name

Tool

arguments

Returned docs[]

semantic_search

Knowledge Base search

{"query", "target_ids"}

Matched chunk array with body and multi-dim scores.

obtain_file

Fetch full file content

{"file_id", "max_tokens"}

File-level info (incl. Markdown presigned URL); full text in message.content.

execute_sql

Run SQL query (NL2SQL)

{"sql", "knowledge_base_id"}

SQL result rows; each row = _citation_index + query columns.

section_browse

Section browse

{"knowledge_base_id", "file_id", "section_path"}

Section preview (first 300 chars).

section_peruse

Section peruse

{"knowledge_base_id", "file_id", "section_path", "max_tokens"}

Full section content.

max_tokens (obtain_file / section_peruse) is a numeric string, e.g. "989482". target_ids / knowledge_base_id is the Knowledge Base (pipeline) ID; section_path separates levels with >, e.g. API Docs>Calling Conventions. Multiple tools can be chained in one request (e.g. semantic_search to locate a file → obtain_file for the full text).

Context Caching

The Q&A pipeline is adapted for model-side context caching (KV Cache): the request prefix stays stable across multi-turn dialogue and multi-round tool calls, so cached input tokens are billed at a discounted rate and time-to-first-token drops. Two cache modes exist, and only one applies per request:
Implicit cacheExplicit cache
How to enableOn by default when the model supports it; no configuration needed and cannot be turned offPass enable_cache_control: true in the request
Hit determinismNon-deterministic; the system auto-detects common prefixesDeterministic — a matching prefix is a hit
Cache creation cost100% of input price (no extra charge)125% of input price
Cache hit price20% of input price10% of input price
TTLNon-deterministic; cleaned up by the system periodically5 minutes, reset on every hit
Minimum cacheable length1024 tokens1024 tokens
Pricing ratios and TTL are subject to the official Model Studio docs — Context Cache and Explicit Cache Best Practices — and your console bill. Internal benchmarks put the implicit-cache hit rate at roughly 75% of explicit caching; this is an empirical figure, not an official metric.

Enabling Explicit Caching

Add enable_cache_control under parameters.agent_options (default false); all other parameters stay unchanged:
curl -X POST "https://{workspaceId}.cn-beijing.maas.aliyuncs.com/api/v2/apps/knowledge/chat" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "messages": [
        {"role": "user", "content": "What are the producing regions of these wines?"}
      ]
    },
    "parameters": {
      "agent_options": {
        "agent_id": "aid-xxxxxxxxxxxxxxxx",
        "enable_cache_control": true
      }
    },
    "stream": true
  }'

Model Support

The two cache modes are supported on different model sets. The model is configured on the platform side — this endpoint exposes no model-selection parameter — so which cache mode is available depends on the model your Q&A service actually runs on:
ModelExplicit cacheImplicit cache
qwen3.6-plus (current default)SupportedNot supported
qwen3.6-flashSupportedNot supported
qwen3.7-plusSupportedSupported
The current default model qwen3.6-plus does not support implicit caching: without enable_cache_control, no cache is in effect at all and cached_tokens stays 0 — this is a model-side capability limit, not an endpoint defect. To gain cache benefits (lower cost + lower TTFT), turn on explicit caching. Only when the service runs on qwen3.7-plus does "implicit caching as a fallback" hold. For the model support list, refer to the "Supported models" section of the official explicit-cache doc.

When to Use It

Cache gains fall into two categories — intra-request gains are more stable and more significant than cross-request ones. Strongly recommended: multiple retrieval and reasoning rounds within one request. When one question triggers multiple tool-calling rounds (repeated semantic_search / execute_sql / section browsing plus intermediate reasoning), the cache breakpoint moves forward with each new tool result, and the previous round's full context (including retrieval results) becomes a stable prefix for the next. The more complex the question, the more retrieval rounds, and the longer the results, the greater the savings — unaffected by the 5-minute TTL or cross-request prefix drift. Recommended: cross-request reuse:
ScenarioWhy
Multi-turn continuous dialogueFrom the second turn on, the request hits the full history prefix of the previous turn; the longer the dialogue, the greater the gain
Long system prompt / large table schemasStructured Knowledge Base schemas are stitched into the system prompt — large and stable within a session, ideal cache content
Repeated follow-ups on the same long document / session fileHigh share of stable prefix; create once, hit many times
Latency-sensitive workloads needing deterministic hitsExplicit caching is deterministic and unaffected by backend scheduling
Break-even: explicit caching costs 25% extra on first write and saves 90% on every subsequent hit — one hit is enough to beat no caching at all. Not recommended (no gain, or even more expensive):
ScenarioWhy
One-shot single-turn short Q&ACreates but never hits — you pay the 25% creation premium for nothing
Prefix shorter than 1024 tokensBelow the minimum cacheable length; nothing gets cached
Low-frequency calls spaced over 5 minutes apartThe explicit cache expires in 5 minutes; the next request re-creates it
Cross-request reuse in multimodal document scenariosImage content blocks participate in prefix computation and easily diverge across requests; count only on intra-request gains
Switching Knowledge Bases / service configs every sessionDifferent prefixes (schemas, KB info) cannot be reused
"Not recommended" only means explicit caching doesn't pay off there. Because the default model qwen3.6-plus doesn't support implicit caching, leaving enable_cache_control off doesn't fall back to implicit caching — it means no caching at all. If you still want some cache benefit in these scenarios, evaluate and enable it anyway.

Observing Cache Hits

cached_tokens in the final frame's usage is the number of input tokens that hit the cache in this request:
{
  "usage": {
    "input_tokens": 12345,
    "output_tokens": 678,
    "total_tokens": 13023,
    "cached_tokens": 9800
  }
}
  • cached_tokens is accumulated across the multiple model calls within the request;
  • The first request of a session always returns cached_tokens: 0 — it only creates the cache and has nothing to hit yet; this is expected;
  • From the second turn on, cached_tokens should be greater than 0 and grow with the dialogue history.

Notes and Limits

  1. The two cache modes are mutually exclusive: enable_cache_control: true means explicit caching only, no implicit caching. On the default model qwen3.6-plus there is no implicit cache, so leaving it off means no cache — not a "fallback to implicit".
  2. No hit on the first turn is normal: any cache must be created first; cached_tokens=0 doesn't indicate a malfunction.
  3. 5-minute TTL for explicit cache: every hit resets it to 5 minutes; after a long pause, the next request re-creates the cache.
  4. Tool-definition changes invalidate the cache: tool definitions are part of the system prompt used in cache computation. For structured Knowledge Bases, carrying search_filters suppresses the execute_sql tool — if filters come and go within one session, the tool list changes and the system prefix misses. Keep kb_search_configs stable within a session.
  5. The prefix must be byte-for-byte stable: rebinding Knowledge Bases, changing service configs (e.g. custom instructions, the session-file switch), or a platform-side model change all alter the prefix and force cache re-creation.
  6. Cross-request hits are unstable in multimodal scenarios: with image input, image content blocks participate in prefix computation and easily diverge across requests; gains in such scenarios come mainly from intra-request multi-round retrieval — don't estimate by cross-request hits.
  7. Backtracking limit on very long turns: cache matching backtracks at most 20 content blocks from the breakpoint; extreme turns with many messages (multiple tool calls + image blocks) may exceed the range and miss.
  8. Caches are isolated by account and model: no sharing across accounts, or across models within one account.
  9. input_tokens ≠ created + hit: the backend appends a few tokens (usually under 10) after the prompt; they count toward total input but not toward cache statistics.

Verifying the Benefit

  1. Add enable_cache_control: true and run a complex question that triggers multi-round retrieval; check whether the final frame's cached_tokens is greater than 0;
  2. Follow up 2-3 more turns in the same session (within 5 minutes); check whether cached_tokens grows with history and compare time-to-first-token;
  3. A/B against the same request without the parameter (baseline should be cached_tokens=0 on the default model), then decide whether to keep it on based on "When to Use It".

Error Codes

In the SSE stream, errors are returned as event: error frames (the data: payload is an error JSON with code / message / request_id). Authentication failures are returned at the HTTP layer.

HTTP Status

Error Code

Description

401

InvalidApiKey

Authentication failed; the API Key is invalid or missing.

500

AgentApp.NotFound

The Agent does not exist or is not published, or another server-side error; returned as an SSE error frame.

Examples

The following example asks the published Knowledge Q&A service "What is a Bailian Knowledge Base?"; replace agent_id with your actual Q&A service ID.

cURL

curl -X POST "https://{workspaceId}.cn-beijing.maas.aliyuncs.com/api/v2/apps/knowledge/chat" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "input": {
      "messages": [
        {"role": "user", "content": [{"type": "text", "text": "What is a Bailian Knowledge Base?"}]}
      ]
    },
    "parameters": {
      "agent_options": {
        "agent_id": "aid-xxxxxxxxxxxxxxxx"
      }
    },
    "stream": true
  }'

Python

import os
import requests

resp = requests.post(
    "https://{workspaceId}.cn-beijing.maas.aliyuncs.com/api/v2/apps/knowledge/chat",
    headers={
        "Authorization": f"Bearer {os.getenv('DASHSCOPE_API_KEY')}",
        "Content-Type": "application/json",
        "Accept": "text/event-stream",
    },
    json={
        "input": {
            "messages": [
                {"role": "user", "content": [{"type": "text", "text": "What is a Bailian Knowledge Base?"}]}
            ]
        },
        "parameters": {
            "agent_options": {
                "agent_id": "aid-xxxxxxxxxxxxxxxx"
            }
        },
        "stream": True,
    },
    stream=True,
)
for line in resp.iter_lines():
    if line:
        print(line.decode())
Managed Agent API
Flow Agent API
Sandbox API
RAG API
Long-term Memory
ParseX API
Security API
Framework Integration
Knowledge Chat - 阿里云百炼