Skip to content
LlamaParse 文档版本 跟随上游 源快照 1ccba70f 更新于 2026-10-16

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 needed
const 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"

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。