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

# 如何为 Agent Server 运行收集用户反馈

本教程向您展示如何为 [Agent Server](/langsmith/agent-server) 运行收集用户反馈，并将其自动关联到 LangSmith 中的[跟踪](/langsmith/observability-concepts#traces)。创建运行时，请在请求体的 `feedback_keys` 字段中包含这些键。响应将为每个键返回一个预签名 URL，您的客户端可以使用该 URL 为 Agent Server 运行收集用户反馈。

LangSmith 使用反馈来持续改进您的代理实现。要了解更多关于反馈在 LangSmith 中如何运作的信息，请参阅 [LangSmith 反馈](/langsmith/observability-concepts#feedback)。

## 工作原理

1. 创建一个运行，并在请求体中包含 `feedback_keys`。例如，调用 `POST /threads/{thread_id}/runs/stream` 时，在请求体中将 `feedback_keys` 设置为：
   ```
   ["user_liked", "user_disliked"]
   ```
2. 响应中的 `feedback` 对象包含每个键的预签名 URL。例如，`feedback` 对象为：
   ```
   {
       "user_liked": "https://api.smith.langchain.com/api/v1/feedback/tokens/ef19fedf-dcac-4cbb-a59c-00661efd6425",
       "user_disliked": "https://api.smith.langchain.com/api/v1/feedback/tokens/e952734e-c0a0-417b-a04d-fc2209691ed5"
   }
   ```
3. 请求返回的 URL（例如 `POST /api/v1/feedback/tokens/{token_id}`）以将反馈键与从 Agent Server 运行生成的跟踪关联起来。更多详情，请参阅 [LangSmith API 参考](https://api.smith.langchain.com/redoc)。
4. LangSmith 使用选定的反馈键（例如 `user_liked` 或 `user_disliked`）将提交的反馈与运行关联起来。

## 使用 `feedback_keys` 调用流式运行 API

创建一个运行，并从响应中解析 `feedback` 对象。

<Tabs>
  <Tab title="Python SDK">
    ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    from langgraph_sdk import get_client

    client = get_client(url="<DEPLOYMENT_URL>", api_key="<API_KEY>")

    thread = await client.threads.create()
    thread_id = thread["thread_id"]

    feedback_urls = {}

    async for event in client.runs.stream(
        thread_id,
        "agent",
        input={
            "messages": [
                {"role": "user", "content": "Tell me a joke about databases."}
            ]
        },
        stream_mode="updates",
        feedback_keys=["user_liked", "user_disliked"],
    ):
        if event.event == "feedback":
            # 示例: {"user_liked": ".../feedback/tokens/<id>", "user_disliked": "..."}
            feedback_urls = event.data
            print("Feedback URLs:", feedback_urls)
        elif event.event == "updates":
            print(event.data)
    ```
  </Tab>

  <Tab title="JavaScript SDK">
    ```javascript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    import { Client } from "@langchain/langgraph-sdk";

    const client = new Client({ apiUrl: "<DEPLOYMENT_URL>", apiKey: "<API_KEY>" });

    const thread = await client.threads.create();
    const threadId = thread.thread_id;

    let feedbackUrls = {};

    const streamResponse = client.runs.stream(threadId, "agent", {
      input: {
        messages: [{ role: "user", content: "Tell me a joke about databases." }],
      },
      streamMode: "updates",
      feedbackKeys: ["user_liked", "user_disliked"],
    });

    for await (const event of streamResponse) {
      if (event.event === "feedback") {
        // 示例: { user_liked: ".../feedback/tokens/<id>", user_disliked: "..." }
        feedbackUrls = event.data;
        console.log("Feedback URLs:", feedbackUrls);
      } else if (event.event === "updates") {
        console.log(event.data);
      }
    }
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
      --url "<DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream" \
      --header "Content-Type: application/json" \
      --header "x-api-key: <API_KEY>" \
      --data '{
        "assistant_id": "agent",
        "input": {
          "messages": [
            {
              "role": "user",
              "content": "Tell me a joke about databases."
            }
          ]
        },
        "stream_mode": "updates",
        "feedback_keys": ["user_liked", "user_disliked"]
      }'
    ```
  </Tab>
</Tabs>

## 处理流式 `feedback` 事件

流会发出如下所示的 `feedback` 事件：

```text theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
event: feedback
data: {"user_liked":"https://api.smith.langchain.com/api/v1/feedback/tokens/ef19fedf-dcac-4cbb-a59c-00661efd6425", "user_disliked": "https://api.smith.langchain.com/api/v1/feedback/tokens/e952734e-c0a0-417b-a04d-fc2209691ed5"}
```

`data` 中的每个键与您在 `feedback_keys` 中传递的值之一匹配。每个值都是一个生成的 URL，您的客户端可以调用该 URL 为该运行提交反馈。

## 使用生成的 URL 提交反馈

当用户选择一个反馈选项时，向相应的 URL 发送 `POST` 请求。也支持 `GET` 请求。更多详情，请参阅 [LangSmith API 参考](https://api.smith.langchain.com/redoc)。

例如，如果用户点击了“踩”按钮，请调用 `user_disliked` URL：

<Tabs>
  <Tab title="POST">
    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request POST \
      --url "https://api.smith.langchain.com/api/v1/feedback/tokens/e952734e-c0a0-417b-a04d-fc2209691ed5" \
      --header "Content-Type: application/json" \
      --data '{
        "score": 1,
        "value": 0,
        "comment": "I didn't like this joke because it didn't make me laugh.",
        "correction": {},
        "metadata": {}
      }'
    ```
  </Tab>

  <Tab title="GET">
    `GET` 不支持 `metadata`。

    ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl --request GET \
      --url "https://api.smith.langchain.com/api/v1/feedback/tokens/e952734e-c0a0-417b-a04d-fc2209691ed5?score=1&value=0&comment=I%20didn%27t%20like%20this%20joke%20because%20it%20didn%27t%20make%20me%20laugh.&correction=%7B%7D"
    ```
  </Tab>
</Tabs>

此请求成功后，LangSmith 使用键 `user_disliked` 在跟踪上记录反馈。

## 优化反馈数据模型

`user_liked` 和 `user_disliked` 键也可以建模在单个键下，例如 `user_score`。

例如：

* 对于 `user_liked`，使用 `key="user_score"` 和 `score=1`
* 对于 `user_disliked`，使用 `key="user_score"` 和 `score=-1`

这可以简化分析，因为所有用户偏好信号都归组在一个反馈键下。

反馈数据模型是灵活的，应根据您的用例进行设计。例如，某些应用程序可能更喜欢单独的布尔型键（`user_liked`、`user_disliked`），而其他应用程序可能更喜欢单个数字分数（`user_score`）或具有多个反馈键的更丰富的评分标准。

## 在客户端 UI 中实现生产化

生产化解决方案将通过您的前端暴露生成的反馈 URL，而不是手动调用它们。

高级实现示例：

1. 从您的后端或前端创建运行。
2. 捕获 `feedback` 对象并存储返回的 URL。
3. 渲染反馈控件，例如“赞/踩”按钮和反馈表单。
4. 提交反馈时，根据用户的反馈意图向反馈 URL 发送 `POST` 或 `GET` 请求。
5. 可选地，在提交后禁用反馈控件并向用户显示确认信息。

***

<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/agent-server-feedback.mdx) 或 [提交问题](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
