主题
使用预签名 URL 收集反馈
使用预签名反馈 token 从客户端应用收集用户反馈,而无需暴露你的 LangSmith API 密钥。
预签名反馈 token 让你可以从客户端应用(浏览器、移动应用等)收集反馈,而无需暴露你的 LangSmith API 密钥。每个 token 都会生成一个 URL,其作用域限定为特定运行和反馈键。客户端通过直接调用该 URL 提交反馈,无需身份验证。
这在以下情况中很有用:
- 你的前端从最终用户收集点赞/点踩或星级评分。
- 你希望将反馈链接嵌入电子邮件、Slack 消息或其他外部渠道。
- 你需要将反馈收集与后端解耦。
NOTE
如果你使用 Agent Server,在运行请求中包含 feedback_keys 时会自动生成预签名反馈 URL。对于该工作流,请参阅为 Agent Server 运行收集用户反馈。
创建预签名反馈 token
使用 create_presigned_feedback_token() / createPresignedFeedbackToken 为特定运行和反馈键生成 token。返回的对象包含一个 url,客户端可以调用它提交反馈:
python
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
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>设置 token 过期时间
token 默认在 3 小时后过期。传入 expiration,使用 timedelta(相对)或 datetime(绝对)自定义:
python
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
import { Client } from "langsmith";
const client = new Client();
const runId = "<run_id>";
const token = await client.createPresignedFeedbackToken(runId, "user_score", {
expiration: { hours: 24 },
});约束反馈值
传入 feedback_config 以限制客户端可以提交的值。这对于强制执行特定反馈 schema(例如点赞/点踩、1–5 星或分类标签)很有用:
python
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
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,
},
});批量创建 token(仅 Python)
使用 create_presigned_feedback_tokens(复数)在单次调用中为多个反馈键生成 token:
python
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 密钥或身份验证,因为 token 提供了授权。
预签名 URL 反馈默认会将基础保留期的追踪延长到延长保留期。预签名 URL 没有选择退出的参数。有关完整保留模型,请参阅数据保留自动升级。
POST 请求
当用户与反馈控件交互(例如点击点赞按钮)时,从前端使用 POST。POST 支持 score、value、comment、correction 和 metadata 字段。
bash
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 作为查询参数。GET 不支持 metadata。
bash
curl --request GET \
--url "https://api.smith.langchain.com/api/v1/feedback/tokens/<token_id>?score=1&comment=This%20response%20was%20helpful!"使用 SDK 提交反馈
你也可以使用 SDK 从预签名 token 提交反馈,这对于你从另一个服务收到 token URL 的服务器端工作流很有用。
python
from langsmith import Client
client = Client()
client.create_feedback_from_token(
"<token_or_url>",
score=1,
comment="This response was helpful!",
)typescript
// Use a direct HTTP request to the presigned URL
await fetch(tokenUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
score: 1,
comment: "This response was helpful!",
}),
});列出已有 token
使用 list_presigned_feedback_tokens / listPresignedFeedbackTokens 检索某个运行的所有预签名反馈 token。
python
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
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}`);
}