Skip to content
LangSmith 文档版本 跟随上游 源快照 d22ea3ee 更新于 2026-10-18

使用 SDK 查询线程

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

如果你正在构建对话 agent 或任何多轮应用,LangSmith 会自动将你的运行分组成线程。查询线程可以让你重放完整对话、跨会话审计 agent 行为、构建对话长度和延迟分析,并为微调和评估等下游工作流提供数据。

SDK 提供两种用于处理线程的方法:

方法使用场景
list_threads / listThreads你想浏览项目中的所有线程
read_thread / readThread你已知道线程 ID,并需要其运行

线程如何工作

你创建的每个运行都可以在其元数据中携带 thread_id。LangSmith 使用它将运行分组为线程。后端在 metadata 中查找 thread_id(回退到 session_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'

如果你使用的是追踪集成,请在运行元数据中传递 thread_id:

python
from langsmith import traceable, uuid7

THREAD_ID = str(uuid7())

@traceable(metadata={"thread_id": THREAD_ID})
def my_agent(user_message: str) -> str:
    ...
typescript
import { traceable } from "langsmith/traceable";
import { uuid7 } from "langsmith";

const THREAD_ID = uuid7();

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

列出项目中的所有线程

list_threads / listThreads 获取项目中的所有线程并将其运行分组在一起。结果按最近活动优先排序。

python
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
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}`);
}

结果按最近活动排序:

text
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 / projectNamestring—项目名称。如果未设置 project_id,则为必填。
project_id / projectIdstring—项目 ID。如果未设置 project_name,则为必填。
limitint全部要返回的最大线程数。
offsetint0要跳过的线程数(用于分页)。
filterstring—获取运行时所应用的过滤表达式,使用 LangSmith 追踪查询语法。
start_time / startTimedatetime / Date1 天前仅包含在此时间之后开始的运行。扩大此窗口以显示更早的线程。

返回值

线程对象列表,每个对象包含:

字段类型描述
thread_idstring线程标识符。
runs[Run](https://reference.langchain.com/python/langsmith/schemas/Run)[]此线程中的根运行,按时间顺序排序(最旧优先)。
countint此线程中的运行数。
min_start_timestring | null最早运行的 ISO 时间戳。
max_start_timestring | null最近运行的 ISO 时间戳。

NOTE

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

读取单个线程的运行

当你已经知道 thread_id 时,请使用 read_thread / readThread。它直接返回线程运行的迭代器,而无需先获取所有线程。

python
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
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);
}

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

python
[
    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 / threadIdstring—必填。 要查询的线程。
project_name / projectNamestring—项目名称。如果未设置 project_id,则为必填。
project_id / projectIdstring | string[]—项目 ID 或 ID 列表。如果未设置 project_name,则为必填。
is_root / isRootbooltrue仅返回根运行。设置为 false 以包含子运行。
limitint全部要返回的最大运行数。
filterstring—附加过滤表达式(与线程过滤器组合)。
order"asc" | "desc""asc"排序顺序。"asc" 返回最旧的运行优先(按时间顺序)。
selectstring[]所有字段要返回的特定运行字段,以减小响应大小。

返回值

Run 对象的迭代器(Python)或异步迭代器(TypeScript)。

示例

按运行属性过滤线程

传递过滤表达式,使用 LangSmith 追踪查询语法缩小结果范围。例如,仅显示包含至少一个失败运行的线程:

python
threads = client.list_threads(
    project_name="my-project",
    filter='eq(status, "error")',
)
typescript
const threads = await client.listThreads({
  projectName: "my-project",
  filter: 'eq(status, "error")',
});

回溯超过 24 小时

默认情况下,list_threads 仅显示过去一天有运行的线程。传递 start_time 以扩大窗口:

python
import datetime

threads = client.list_threads(
    project_name="my-project",
    start_time=datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=2),
)
typescript
const threads = await client.listThreads({
  projectName: "my-project",
  startTime: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
});

重建对话

使用 read_thread 并设置 order="asc",逐轮重放对话:

python
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
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}`);
}

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