> ## Documentation Index
> Fetch the complete documentation index at: https://cndoc-langchain.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 SDK 查询线程

> 从你的 LangSmith 项目中以编程方式获取和检查多轮对话线程。

如果你正在构建对话代理或任何多轮应用，LangSmith 会自动将你的[运行](/langsmith/run-data-format)分组为[线程](/langsmith/observability-concepts#threads)。查询线程可以让你重放完整对话、跨会话审计代理行为、构建关于对话长度和延迟的分析，并为微调和评估等下游工作流提供数据。

SDK 提供了两种处理线程的方法：

| 方法                                                                                                                                                                                              | 使用场景              |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| [`list_threads`](https://reference.langchain.com/python/langsmith/client/Client/list_threads) / [`listThreads`](https://reference.langchain.com/javascript/langsmith/client/Client/listThreads) | 你想浏览项目中的所有线程      |
| [`read_thread`](https://reference.langchain.com/python/langsmith/client/Client/read_thread) / [`readThread`](https://reference.langchain.com/javascript/langsmith/client/Client/readThread)     | 你已知线程 ID 并需要其运行数据 |

## 线程的工作原理

你创建的每个运行都可以在其元数据中携带一个 `thread_id`。LangSmith 使用此 ID 将运行分组为线程。后端会在 `metadata` 中查找 `thread_id`（如果找不到，则回退到 `session_id` 或 `conversation_id`）。

<Note>
  我们建议使用 **UUID v7** 作为线程 ID。UUIDv7 嵌入了时间戳，这可以保持线程正确的时间顺序。LangSmith SDK 导出了一个 uuid7 辅助函数（Python v0.4.43+，JS v0.3.80+）：

  * **Python**: `from langsmith import uuid7`
  * **JS/TS**: `import { uuid7 } from 'langsmith'`
</Note>

如果你使用的是[追踪集成](/langsmith/integrations)，请在运行元数据中传递 `thread_id`：

<CodeGroup>
  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  from langsmith import traceable, uuid7

  THREAD_ID = str(uuid7())

  @traceable(metadata={"thread_id": THREAD_ID})
  def my_agent(user_message: str) -> str:
      ...
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { traceable } from "langsmith/traceable";
  import { uuid7 } from "langsmith";

  const THREAD_ID = uuid7();

  const myAgent = traceable(
    async (userMessage: string) => {
      // ...
    },
    { metadata: { thread_id: THREAD_ID } }
  );
  ```
</CodeGroup>

## 列出项目中的所有线程

`list_threads` / `listThreads` 获取项目中的所有线程，并将它们的运行数据分组在一起。结果按最近活动时间排序。

<CodeGroup>
  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  from langsmith import Client

  client = Client()

  threads = client.list_threads(project_name="my-project")

  for thread in threads:
      print(thread["thread_id"])
      print(f"  {thread['count']} runs")
      print(f"  last active: {thread['max_start_time']}")
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { Client } from "langsmith";

  const client = new Client();

  const threads = await client.listThreads({ projectName: "my-project" });

  for (const thread of threads) {
    console.log(thread.thread_id);
    console.log(`  ${thread.count} runs`);
    console.log(`  last active: ${thread.max_start_time}`);
  }
  ```
</CodeGroup>

结果按最近活动时间排序：

```text Output theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
conv-abc123
  3 runs
  last active: 2026-02-25T10:05:42+00:00
conv-def456
  1 runs
  last active: 2026-02-25T09:30:00+00:00
```

### 参数

| 参数                             | 类型                  | 默认值  | 描述                                                                  |
| ------------------------------ | ------------------- | ---- | ------------------------------------------------------------------- |
| `project_name` / `projectName` | `string`            | —    | 项目名称。如果未设置 `project_id`，则此项为必填。                                     |
| `project_id` / `projectId`     | `string`            | —    | 项目 ID。如果未设置 `project_name`，则此项为必填。                                  |
| `limit`                        | `int`               | 全部   | 要返回的最大线程数。                                                          |
| `offset`                       | `int`               | `0`  | 要跳过的线程数（用于分页）。                                                      |
| `filter`                       | `string`            | —    | 获取运行时应用的过滤表达式，使用 [LangSmith 追踪查询语法](/langsmith/trace-query-syntax)。 |
| `start_time` / `startTime`     | `datetime` / `Date` | 1 天前 | 仅包含在此时间之后开始的运行。扩大此时间窗口以显示更早的线程。                                     |

### 返回值

一个线程对象列表，每个对象包含：

| 字段               | 类型                                                                      | 描述                      |
| ---------------- | ----------------------------------------------------------------------- | ----------------------- |
| `thread_id`      | `string`                                                                | 线程标识符。                  |
| `runs`           | `[Run](https://reference.langchain.com/python/langsmith/schemas/Run)[]` | 此线程中的根运行，按时间顺序排序（最早在前）。 |
| `count`          | `int`                                                                   | 此线程中的运行数量。              |
| `min_start_time` | `string \| null`                                                        | 最早运行的 ISO 时间戳。          |
| `max_start_time` | `string \| null`                                                        | 最近运行的 ISO 时间戳。          |

<Note>
  `list_threads` 始终只返回根运行。如果你需要子运行（例如，工具调用、子链），请改用 `read_thread`，它接受一个 `is_root` / `isRoot` 参数，你可以将其设置为 `false`。
</Note>

## 读取单个线程的运行数据

当你已知 `thread_id` 时，使用 `read_thread` / `readThread`。它直接返回线程运行数据的迭代器，无需先获取所有线程。

<CodeGroup>
  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  from langsmith import Client

  client = Client()

  for run in client.read_thread(
      thread_id="conv-abc123",
      project_name="my-project",
  ):
      print(run.id, run.name, run.start_time)
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { Client } from "langsmith";

  const client = new Client();

  for await (const run of client.readThread({
    threadId: "conv-abc123",
    projectName: "my-project",
  })) {
    console.log(run.id, run.name, run.start_time);
  }
  ```
</CodeGroup>

与 `list_threads` 不同，这里的每个项目都是一个 `Run` 对象本身——没有分组包装器。默认情况下，运行按时间升序返回。

```python Output theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
[
    Run(id=UUID("a1b2..."), name="my_agent", run_type="chain", status="success", start_time=datetime(2026, 2, 25, 10, 0, 0, tzinfo=utc), ...),
    Run(id=UUID("c3d4..."), name="my_agent", run_type="chain", status="success", start_time=datetime(2026, 2, 25, 10, 3, 11, tzinfo=utc), ...),
    Run(id=UUID("e5f6..."), name="my_agent", run_type="chain", status="error",   start_time=datetime(2026, 2, 25, 10, 5, 42, tzinfo=utc), ...),
]
```

### 参数

| 参数                             | 类型                   | 默认值     | 描述                                         |
| ------------------------------ | -------------------- | ------- | ------------------------------------------ |
| `thread_id` / `threadId`       | `string`             | —       | **必填。** 要查询的线程。                            |
| `project_name` / `projectName` | `string`             | —       | 项目名称。如果未设置 `project_id`，则此项为必填。            |
| `project_id` / `projectId`     | `string \| string[]` | —       | 项目 ID 或 ID 列表。如果未设置 `project_name`，则此项为必填。 |
| `is_root` / `isRoot`           | `bool`               | `true`  | 仅返回根运行。设置为 `false` 以包含子运行。                 |
| `limit`                        | `int`                | 全部      | 要返回的最大运行数。                                 |
| `filter`                       | `string`             | —       | 附加过滤表达式（与线程过滤器组合）。                         |
| `order`                        | `"asc" \| "desc"`    | `"asc"` | 排序顺序。`"asc"` 按时间升序返回运行（最早在前）。              |
| `select`                       | `string[]`           | 所有字段    | 要返回的特定运行字段，以减小响应大小。                        |

### 返回值

一个 `Run` 对象的迭代器（[Python](https://reference.langchain.com/python/langsmith)）或异步迭代器（[TypeScript](https://reference.langchain.com/javascript/langsmith)）。

## 示例

### 按运行属性过滤线程

传递过滤表达式以使用 [LangSmith 追踪查询语法](/langsmith/trace-query-syntax)缩小结果范围。例如，仅显示包含至少一个失败运行的线程：

<CodeGroup>
  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  threads = client.list_threads(
      project_name="my-project",
      filter='eq(status, "error")',
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  const threads = await client.listThreads({
    projectName: "my-project",
    filter: 'eq(status, "error")',
  });
  ```
</CodeGroup>

### 回溯超过 24 小时

默认情况下，`list_threads` 仅显示过去一天内有运行的线程。传递 `start_time` 以扩大时间窗口：

<CodeGroup>
  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import datetime

  threads = client.list_threads(
      project_name="my-project",
      start_time=datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=2),
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  const threads = await client.listThreads({
    projectName: "my-project",
    startTime: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
  });
  ```
</CodeGroup>

### 重建对话

使用 `read_thread` 并设置 `order="asc"` 以逐轮重放对话：

<CodeGroup>
  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  runs = list(
      client.read_thread(
          thread_id="conv-abc123",
          project_name="my-project",
          order="asc",
      )
  )

  for run in runs:
      user_msg = run.inputs.get("messages", [{}])[-1].get("content", "")
      assistant_msg = (run.outputs or {}).get("content", "")
      print(f"User:      {user_msg}")
      print(f"Assistant: {assistant_msg}")
      print()
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  const runs: Run[] = [];
  for await (const run of client.readThread({
    threadId: "conv-abc123",
    projectName: "my-project",
    order: "asc",
  })) {
    runs.push(run);
  }

  for (const run of runs) {
    const messages = (run.inputs?.messages ?? []) as Array<Record<string, string>>;
    const userMsg = messages.at(-1)?.content ?? "";
    const assistantMsg = (run.outputs as Record<string, string>)?.content ?? "";
    console.log(`User:      ${userMsg}`);
    console.log(`Assistant: ${assistantMsg}`);
  }
  ```
</CodeGroup>

***

<div className="source-links">
  <Callout icon="terminal-2">
    [将这些文档](/use-these-docs)通过 MCP 连接到 Claude、VSCode 等，以获取实时答案。
  </Callout>

  <Callout icon="edit">
    [在 GitHub 上编辑此页面](https://github.com/langchain-ai/docs/edit/main/src/langsmith/query-threads.mdx) 或 [提交问题](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
