> ## 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.

# 使用预签名 URL 收集反馈

> 使用预签名反馈令牌从客户端应用程序收集用户反馈，无需暴露您的 LangSmith API 密钥。

预签名反馈令牌允许您从客户端应用程序（浏览器、移动应用等）收集[反馈](/langsmith/observability-concepts#feedback)，而无需暴露您的 [LangSmith API 密钥](/langsmith/create-account-api-key)。每个令牌生成一个 URL，该 URL 的作用域限定于特定的运行和反馈键。客户端通过直接调用该 URL 提交反馈，无需身份验证。

这在以下情况下很有用：

* 您的前端从最终用户那里收集点赞/点踩或星级评分。
* 您希望在电子邮件、Slack 消息或其他外部渠道中嵌入反馈链接。
* 您需要将反馈收集与后端解耦。

<Note>
  如果您正在使用 [Agent Server](/langsmith/agent-server)，当您在运行请求中包含 `feedback_keys` 时，预签名反馈 URL 会自动生成。有关该工作流程，请参阅[为 Agent Server 运行收集用户反馈](/langsmith/agent-server-feedback)。
</Note>

## 创建预签名反馈令牌

使用 [`create_presigned_feedback_token()`](https://reference.langchain.com/python/langsmith/client/Client/create_presigned_feedback_token) / [`createPresignedFeedbackToken`](https://reference.langchain.com/javascript/classes/langsmith.client.Client.html#createpresignedfeedbacktoken) 为特定的运行和反馈键生成令牌。返回的对象包含一个 `url`，客户端可以调用该 URL 来提交反馈：

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

  client = Client()

  run_id = "<run_id>"

  token = client.create_presigned_feedback_token(
      run_id,
      feedback_key="user_score",
  )

  print(token.url)
  # https://api.smith.langchain.com/api/v1/feedback/tokens/<token_id>
  ```

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

  const client = new Client();

  const runId = "<run_id>";

  const token = await client.createPresignedFeedbackToken(runId, "user_score");

  console.log(token.url);
  // https://api.smith.langchain.com/api/v1/feedback/tokens/<token_id>
  ```
</CodeGroup>

### 设置令牌过期时间

令牌默认在 3 小时后过期。传递 `expiration` 参数以使用 `timedelta`（相对时间）或 `datetime`（绝对时间）自定义此设置：

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

  client = Client()

  run_id = "<run_id>"

  token = client.create_presigned_feedback_token(
      run_id,
      feedback_key="user_score",
      expiration=datetime.timedelta(hours=24),
  )
  ```

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

  const client = new Client();

  const runId = "<run_id>";

  const token = await client.createPresignedFeedbackToken(runId, "user_score", {
    expiration: { hours: 24 },
  });
  ```
</CodeGroup>

### 限制反馈值

传递 `feedback_config` 以限制客户端可以提交的值。这对于强制执行特定的反馈模式（例如，点赞/点踩、1-5 星或分类标签）很有用：

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

  client = Client()

  run_id = "<run_id>"

  token = client.create_presigned_feedback_token(
      run_id,
      feedback_key="user_score",
      feedback_config={
          "type": "continuous",
          "min": 0,
          "max": 1,
      },
  )
  ```

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

  const client = new Client();

  const runId = "<run_id>";

  const token = await client.createPresignedFeedbackToken(runId, "user_score", {
    feedbackConfig: {
      type: "continuous",
      min: 0,
      max: 1,
    },
  });
  ```
</CodeGroup>

### 批量创建令牌（仅限 Python）

使用 `create_presigned_feedback_tokens`（复数形式）在一次调用中为多个反馈键生成令牌：

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

client = Client()

run_id = "<run_id>"

tokens = client.create_presigned_feedback_tokens(
    run_id,
    feedback_keys=["thumbs_up", "thumbs_down"],
)

for token in tokens:
    print(f"{token.id}: {token.url}")
```

## 使用预签名 URL 提交反馈

一旦您有了预签名 URL，您的前端代码或电子邮件客户端通过向其发送 `POST` 或 `GET` 请求来提交反馈。该 URL 不需要 API 密钥或身份验证，因为令牌提供了授权。

### POST 请求

当用户与反馈控件（例如，点击点赞按钮）交互时，从您的前端使用 `POST`。`POST` 支持 `score`、`value`、`comment`、`correction` 和 `metadata` 字段。

```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
curl --request POST \
  --url "https://api.smith.langchain.com/api/v1/feedback/tokens/<token_id>" \
  --header "Content-Type: application/json" \
  --data '{
    "score": 1,
    "comment": "This response was helpful!"
  }'
```

### GET 请求

当在电子邮件或 Slack 消息中嵌入反馈链接时使用 `GET`。用户的点击会触发该请求。`GET` 支持 `score`、`value`、`comment` 和 `correction` 作为查询参数。`metadata` 不支持与 `GET` 一起使用。

```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
curl --request GET \
  --url "https://api.smith.langchain.com/api/v1/feedback/tokens/<token_id>?score=1&comment=This%20response%20was%20helpful!"
```

### 使用 SDK 提交反馈

您也可以使用 SDK 从预签名令牌提交反馈，这对于您从另一个服务收到令牌 URL 的服务器端工作流程很有用。

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

  client = Client()

  client.create_feedback_from_token(
      "<token_or_url>",
      score=1,
      comment="This response was helpful!",
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  // 使用直接 HTTP 请求访问预签名 URL
  await fetch(tokenUrl, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      score: 1,
      comment: "This response was helpful!",
    }),
  });
  ```
</CodeGroup>

## 列出现有令牌

使用 `list_presigned_feedback_tokens` / `listPresignedFeedbackTokens` 检索某个运行的所有预签名反馈令牌。

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

  client = Client()

  run_id = "<run_id>"

  for token in client.list_presigned_feedback_tokens(run_id):
      print(f"ID: {token.id}, URL: {token.url}, Expires: {token.expires_at}")
  ```

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

  const client = new Client();

  const runId = "<run_id>";

  for await (const token of client.listPresignedFeedbackTokens(runId)) {
    console.log(`URL: ${token.url}, Expires: ${token.expires_at}`);
  }
  ```
</CodeGroup>

## 相关内容

* [反馈数据格式参考指南](/langsmith/feedback-data-format)
* [使用 SDK 记录反馈](/langsmith/attach-user-feedback)

***

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

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