Agent Server 런에 대한 사용자 피드백 수집하기
Agent Server 런에 대한 사용자 피드백 수집하기
이 튜토리얼은 Agent Server 런에 대한 사용자 피드백을 수집하고, 이를 LangSmith의 트레이스에 자동으로 연결하는 방법을 보여줘요. 런을 만들 때 요청 본문의 feedback_keys 필드에 키들을 포함하면, 각 키에 대한 사전 서명된 URL이 응답으로 돌아와서 클라이언트가 그 URL로 Agent Server 런에 대한 사용자 피드백을 수집할 수 있답니다.
출처: 문서
본문
이 튜토리얼에서는 Agent Server 런에 대한 사용자 피드백을 수집하고, 이를 LangSmith의 트레이스에 자동으로 연결하는 방법을 보여줍니다. 런을 만들 때 요청 본문의 feedback_keys 필드에 키들을 포함하세요. 응답은 각 키에 대한 사전 서명된 URL을 반환하며, 클라이언트가 이 URL을 사용해 Agent Server 런에 대한 사용자 피드백을 수집할 수 있습니다.
LangSmith는 피드백을 사용해 에이전트 구현을 지속적으로 개선합니다. LangSmith에서 피드백이 어떻게 작동하는지 더 자세히 알아보려면 LangSmith 피드백을 참고하세요.
작동 방식
- 런을 만들고 요청 본문에
feedback_keys를 포함합니다. 예를 들어POST /threads/{thread_id}/runs/stream을 호출할 때 요청 본문의feedback_keys를 다음과 같이 설정합니다:["user_liked", "user_disliked"] - 응답의
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" } - 반환된 URL에 요청합니다 (예:
POST /api/v1/feedback/tokens/{token_id}). 그러면 피드백 키가 Agent Server 런에서 생성된 트레이스와 연결됩니다. 자세한 내용은 LangSmith API 레퍼런스를 참고하세요. - LangSmith는 선택한 피드백 키(예:
user_liked또는user_disliked)를 사용해 제출된 피드백을 런과 연결합니다.
feedback_keys로 스트리밍 런 API 호출하기
런을 만들고 응답에서 feedback 객체를 파싱합니다.
Python SDK
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":
# Example: {"user_liked": ".../feedback/tokens/<id>", "user_disliked": "..."}
feedback_urls = event.data
print("Feedback URLs:", feedback_urls)
elif event.event == "updates":
print(event.data)
JavaScript SDK
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: "<DEPLOYMENT_URL>", apiKey: *** });
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") {
// Example: { user_liked: ".../feedback/tokens/<id>", user_disliked: "..." }
feedbackUrls = event.data;
console.log("Feedback URLs:", feedbackUrls);
} else if (event.event === "updates") {
console.log(event.data);
}
}
cURL
curl --request POST \
--url "<DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream" \
--header "Content-Type: application/json" \
--header "x-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"]
}'
스트리밍된 feedback 이벤트 처리하기
스트림은 다음과 같은 feedback 이벤트를 방출합니다:
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로 POST 요청을 보냅니다. GET도 지원됩니다. 자세한 내용은 LangSmith API 레퍼런스를 참고하세요.
예를 들어 사용자가 엄지 내리기 버튼을 클릭하면 user_disliked URL을 호출합니다:
POST
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": {}
}'
GET
metadata는 GET에서 지원되지 않습니다.
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"
이 요청이 성공하면 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을 수동으로 호출하는 대신 프론트엔드를 통해 노출합니다.
구현의 높은 수준 예시:
- 백엔드 또는 프론트엔드에서 런을 만듭니다.
feedback객체를 캡처하고 반환된 URL을 저장합니다.- 엄지 위/아래 버튼과 피드백 폼 같은 피드백 컨트롤을 렌더링합니다.
- 피드백 제출 시 사용자의 피드백 의도에 따라 피드백 URL에
POST또는GET을 보냅니다. - 선택적으로 제출 후 피드백 컨트롤을 비활성화하고 사용자에게 확인을 표시합니다.
더 알아보기
- LangSmith에서 피드백이 작동하는 방식은 LangSmith feedback 문서를 참고하세요.
- API 레퍼런스는 LangSmith API reference 문서를 확인해 보세요.