主题
chat API 内置一个 RAG 智能体,可以在你的一个或多个索引上回答问题。它管理对话会话、以 Server-Sent Events 流式返回响应,并在内部处理检索、工具调用与推理。
创建会话
会话保存对话历史。你可以在创建时可选地把它绑定到若干索引 —— 一旦发出第一条消息,绑定的索引就在该会话的整个生命周期内锁定。
- Python
- TypeScript
- Go
- Java
- CLI
# Session bound to specific indexes
session = await client.chat.create(
index_ids=["<index-id-1>", "<index-id-2>"],
)
print(session.session_id)
# Unbound session (indexes specified per-message)
session = await client.chat.create()// Session bound to specific indexes
const session = await client.chat.create({
index_ids: ["<index-id-1>", "<index-id-2>"],
});
console.log(session.session_id);
// Unbound session
const unboundSession = await client.chat.create({});// Session bound to specific indexes
session, err := client.Chat.New(ctx, llamacloud.ChatNewParams{
IndexIDs: []string{"<index-id-1>", "<index-id-2>"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(session.SessionID)
// Unbound session (indexes specified per-message)
session, err = client.Chat.New(ctx, llamacloud.ChatNewParams{})
if err != nil {
log.Fatal(err)
}import ai.llamaindex.llamacloud.models.chat.ChatCreateParams;
import ai.llamaindex.llamacloud.models.chat.ChatCreateResponse;
// Session bound to specific indexes
ChatCreateResponse session = client.chat().create(
ChatCreateParams.builder()
.addIndexId("<index-id-1>")
.addIndexId("<index-id-2>")
.build());
System.out.println(session.sessionId());
// Unbound session (indexes specified per-message)
ChatCreateResponse unboundSession = client.chat().create();终端窗口
# Session bound to specific indexes
SESSION_ID=$(llp beta:chat create \
--index-id '["<index-id-1>", "<index-id-2>"]' | jq -r '.session_id')
echo "$SESSION_ID"
# Unbound session (indexes specified per-message)
SESSION_ID=$(llp beta:chat create | jq -r '.session_id')注意
一个会话最多绑定 10 个索引。每一轮都会向所有绑定的索引扇出检索。
流式输出消息
发送一条消息,并以 Server-Sent Events 流接收智能体的响应。这个流包含思考步骤、工具调用(检索)以及最终的文本响应。
每个 SDK 都提供一个原始响应访问器,把尚未读取的 HTTP 响应体交回给你 —— Python 里是 with_streaming_response、TypeScript 里是 .asResponse()、Go 里是 option.WithResponseBodyInto、Java 里是 withRawResponse() —— 于是可以逐行解析随到随来的事件。
- Python
- TypeScript
- Go
- Java
- CLI
import json
response = client.chat.with_streaming_response.stream(
session.session_id,
index_ids=["<index-id>"],
prompt="What are the key findings in the Q3 report?",
)
async with response as stream:
async for line in stream.iter_lines():
if not line or line.startswith(":"):
continue
if line.startswith("data: "):
data = json.loads(line[6:])
if data.get("type") == "text_delta":
print(data["content"], end="", flush=True)
elif data.get("type") == "stop":
print("\n--- Done ---")
else:
print(data) # handle other event types as neededconst response = await client.chat.stream(session.session_id, {
index_ids: ["<index-id>"],
prompt: "What are the key findings in the Q3 report?",
}).asResponse();
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
// SSE records end with a blank line; keep incomplete records between reads.
const records = buffer.split(/\r?\n\r?\n/);
buffer = records.pop()!;
for (const record of records) {
for (const line of record.split(/\r?\n/)) {
if (line.startsWith("data: ")) {
const data = JSON.parse(line.slice(6));
if (data.type === "text_delta") {
process.stdout.write(data.content);
}
else if (data.type === "stop") {
console.log("\n--- Done ---");
} else {
console.log(data); // handle other event types as needed
}
}
}
}
if (done) break; // Discard any incomplete record at EOF.
}import (
"bufio"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
llamacloud "github.com/run-llama/llama-parse-go"
"github.com/run-llama/llama-parse-go/option"
)
var raw *http.Response
if _, err := client.Chat.Stream(ctx, session.SessionID, llamacloud.ChatStreamParams{
IndexIDs: []string{"<index-id>"},
Prompt: "What are the key findings in the Q3 report?",
}, option.WithResponseBodyInto(&raw)); err != nil {
log.Fatal(err)
}
defer raw.Body.Close()
scanner := bufio.NewScanner(raw.Body)
for scanner.Scan() {
line := scanner.Text()
if !strings.HasPrefix(line, "data: ") {
continue
}
var data map[string]any
if err := json.Unmarshal([]byte(line[6:]), &data); err != nil {
continue
}
switch data["type"] {
case "text_delta":
fmt.Print(data["content"])
case "stop":
fmt.Println("\n--- Done ---")
default:
fmt.Println(data) // handle other event types as needed
}
}import ai.llamaindex.llamacloud.core.http.HttpResponseFor;
import ai.llamaindex.llamacloud.models.chat.ChatStreamParams;
import ai.llamaindex.llamacloud.models.chat.ChatStreamResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
ObjectMapper mapper = new ObjectMapper();
try (HttpResponseFor<ChatStreamResponse> response =
client.chat().withRawResponse().stream(
session.sessionId(),
ChatStreamParams.builder()
.addIndexId("<index-id>")
.prompt("What are the key findings in the Q3 report?")
.build());
BufferedReader reader =
new BufferedReader(new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("data: ")) {
continue;
}
JsonNode data = mapper.readTree(line.substring(6));
String type = data.path("type").asText();
if (type.equals("text_delta")) {
System.out.print(data.path("content").asText());
} else if (type.equals("stop")) {
System.out.println("\n--- Done ---");
} else {
System.out.println(data); // handle other event types as needed
}
}
}终端窗口
llp beta:chat stream \
--session-id "$SESSION_ID" \
--index-id "<index-id>" \
--prompt "What are the key findings in the Q3 report?"CLI 是例外:llp beta:chat stream 会把整轮缓冲下来,等智能体结束后一次性打印累积的事件载荷,所以它适合回看某一轮,不适合实时渲染增量。
事件类型
这个流会发出两类事件:
增量事件(event: delta)—— 用于实时展示的渐进内容:
| 类型 | 说明 |
|---|---|
text_delta | 智能体响应文本的一块。 |
thinking_delta | 智能体推理的一块(若已暴露)。 |
消息事件(event: message)—— 完整、离散的事件:
| 类型 | 说明 |
|---|---|
text | 智能体完整的响应文本。 |
thinking | 智能体完整的推理块。 |
user_input | 用户的原始消息。 |
tool_call | 智能体的一次工具调用(例如检索)。 |
tool_result | 某次工具调用的结果。 |
stop | 流的结束,含 token 用量。 |
warning | 提示性警告(例如被跳过的索引)。 |
列出会话
- Python
- TypeScript
- Go
- Java
- CLI
sessions = await client.chat.list()
for s in sessions.items:
print(f"{s.session_id}: {s.generated_title or '(untitled)'}")const sessions = await client.chat.list();
for (const s of sessions.items) {
console.log(`${s.session_id}: ${s.generated_title ?? "(untitled)"}`);
}iter := client.Chat.ListAutoPaging(ctx, llamacloud.ChatListParams{})
for iter.Next() {
s := iter.Current()
title := s.GeneratedTitle
if title == "" {
title = "(untitled)"
}
fmt.Printf("%s: %s\n", s.SessionID, title)
}
if err := iter.Err(); err != nil {
log.Fatal(err)
}import ai.llamaindex.llamacloud.models.chat.ChatListPage;
import ai.llamaindex.llamacloud.models.chat.ChatListResponse;
ChatListPage page = client.chat().list();
for (ChatListResponse s : page.autoPager()) {
System.out.println(s.sessionId() + ": " + s.generatedTitle().orElse("(untitled)"));
}终端窗口
llp beta:chat list \
--max-items 100 \
| jq -r '"\(.session_id): \(.generated_title // "(untitled)")"'获取会话详情
可以取回一份会话摘要,或带上其事件历史的完整会话。
- Python
- TypeScript
- Go
- Java
- CLI
# Summary only
summary = await client.chat.get_summary(session.session_id)
print(summary.generated_title)
print(summary.job_metadata)
# Full session with event history
full = await client.chat.retrieve(session.session_id)
for event in full.events:
print(event.type, event.content[:100] if hasattr(event, "content") else "")// Summary only
const summary = await client.chat.getSummary(session.session_id);
console.log(summary.generated_title);
// Full session with events
const full = await client.chat.retrieve(session.session_id);
for (const event of full.events) {
console.log(event.type);
}// Summary only
summary, err := client.Chat.GetSummary(ctx, session.SessionID, llamacloud.ChatGetSummaryParams{})
if err != nil {
log.Fatal(err)
}
fmt.Println(summary.GeneratedTitle)
// Full session with event history
full, err := client.Chat.Get(ctx, session.SessionID, llamacloud.ChatGetParams{})
if err != nil {
log.Fatal(err)
}
for _, event := range full.Events {
content := event.Content
if runes := []rune(content); len(runes) > 100 {
content = string(runes[:100])
}
fmt.Println(event.Type, content)
}import ai.llamaindex.llamacloud.models.chat.ChatGetSummaryResponse;
import ai.llamaindex.llamacloud.models.chat.ChatRetrieveResponse;
// Summary only
ChatGetSummaryResponse summary = client.chat().getSummary(session.sessionId());
System.out.println(summary.generatedTitle().orElse("(untitled)"));
// Full session with event history
ChatRetrieveResponse full = client.chat().retrieve(session.sessionId());
for (ChatRetrieveResponse.Event event : full.events()) {
if (event.isText()) {
System.out.println("text: " + event.asText().content());
} else if (event.isTextDelta()) {
System.out.println("text_delta: " + event.asTextDelta().content());
} else if (event.isThinking()) {
System.out.println("thinking: " + event.asThinking().content());
} else if (event.isThinkingDelta()) {
System.out.println("thinking_delta: " + event.asThinkingDelta().content());
} else if (event.isUserInput()) {
System.out.println("user_input: " + event.asUserInput().content());
} else if (event.isToolCall()) {
System.out.println("tool_call: " + event.asToolCall().name());
} else if (event.isToolResult()) {
System.out.println("tool_result: " + event.asToolResult().name());
} else if (event.isStop()) {
System.out.println("stop: " + event.asStop().usage());
}
}终端窗口
# Summary only
llp beta:chat get-summary --session-id "$SESSION_ID" \
| jq -r '.generated_title // "(untitled)"'
# Full session with event history
llp beta:chat retrieve --session-id "$SESSION_ID" \
| jq -r '.events[] | "\(.type): \((.content // "")[0:100])"'删除会话
- Python
- TypeScript
- Go
- Java
- CLI
await client.chat.delete(session.session_id)await client.chat.delete(session.session_id);err := client.Chat.Delete(ctx, session.SessionID, llamacloud.ChatDeleteParams{})
if err != nil {
log.Fatal(err)
}client.chat().delete(session.sessionId());终端窗口
llp beta:chat delete --session-id "$SESSION_ID"