프리미티브(질문)
TypeSafe의 세 가지 질문 유형(Choice, Score, Noul), 각각이 반환하는 타입이 지정된 답변, 이들 중에서 선택하는 방법, 그리고 여러 개를 한 번에 질문하는 방법입니다.
TypeSafe의 프리미티브는 코드에서 조합하는 작고 타입이 지정된 빌딩 블록입니다. 이들은 짝을 이룹니다. 질문은 System One 모델이 상태에 대해 내릴 하나의 판단을 정의하고, 그 답변은 돌아오는 타입 지정된 값입니다. 여러분은 코드에서 답변을 조합하여 결정을 내립니다. 질문 유형은 세 가지이며, 각각 다른 모양의 답변을 반환합니다.
| 유형 | 답하는 것 | 반환 |
|---|---|---|
| Choice | 이 중 어느 선택지입니까? | choice, probabilities, confidence |
| Score | 어느 레벨입니까? | score, legend, probabilities, confidence |
| Noul | 이것이 참입니까? | noul (0에서 1) |
질문을 하나만 하거나 여러 개를 함께 보낼 수 있습니다. 요청의 모든 질문은 같은 상태를 보며, 독립적으로 평가되고, 여러분이 고른 ID 아래에 타입이 지정된 답변을 반환합니다.
질문마다 즉각적인 판단 하나를 요청합니다
System One 모델은 빠르고 집중된 판단을 위해 만들어졌습니다. 올바른 컨텍스트가 주어졌을 때 지식이 풍부한 사람이 1초 만에 내리는 판단을 요청하십시오. “이 메시지가 긴급성을 전달합니까?“는 좋은 질문입니다. “이 메시지를 분석하고 최선의 행동 방침을 결정하십시오”는 그렇지 않습니다. 그것은 느린 추론이 필요하며, 작업을 작은 질문으로 나누고 답변을 코드에서 조합하라는 신호입니다.
원하는 판단이 여러 독립적인 요인에 달려 있다면, 각 요인을 따로 질문하고 답변을 자체 로직으로 결합하십시오. “이 스타트업 피치를 평가하십시오” 대신 시장 규모, 기술적 실현 가능성, 차별성을 질문한 다음, 상대적 중요도에 따라 코드에서 가중치를 부여하십시오. 우선순위가 바뀌면 프롬프트를 다시 쓰는 대신 가중치 값을 바꾸십시오. 이 방법은 여러 질문을 함께 하기에 나옵니다.
질문 정의하기
모든 질문에는 ID, type, instructions가 있습니다. Choice와 Score 질문은 추가로 criteria를 받는데, 이것은 Choice 질문의 선택지 또는 Score의 레벨을 정의합니다. Noul 질문은 yes와 no의 의미를 선택적으로 명확히 하는 criteria를 받습니다.
- ID.
refund_requested처럼 여러분이 고르는 키입니다. 응답에서 답변을 식별합니다. type.choice,score,noul중 하나입니다.instructions. 상태에 대해 던지는 질문입니다. 여기에 평가 로직이 들어갑니다. 명확하고 구체적인 질문으로 쓰거나, 모델이 판단할 진술문으로 쓰십시오. 대부분의 질문에는 문자열로 충분합니다. 객체나 배열일 수도 있는데, 이는 질문을 한 필드에, 그것이 참조하는 데이터를 다른 필드에 넣습니다. 질문에 구조 사용하기를 참조하십시오.criteria. 가능한 답변입니다. Choice 질문의 선택지 맵, Score의 정렬된 레벨 목록, Noul의 yes와 no에 대한 선택적 설명입니다. 각 질문 유형 페이지에서 그 형태를 다룹니다.
다음 질문은 고객이 환불을 요청했는지 묻습니다.
from typesafe_sdk import Noul
questions = {
"refund_requested": Noul(
instructions="Does the customer request a refund?",
),
}
질문 유형 선택하기
필요한 답변의 모양에 맞는 유형을 고르십시오.
-
Choice는 답변이 서로 순서가 없는 알려진 선택지 집합 중 하나일 때 적합합니다. 티켓을 부서로 라우팅하기, 문서 유형 분류하기, 프로그래밍 언어 감지하기 등입니다. 선택지의 전체 목록을 제공하고, 목록이 모든 입력을 포괄하지 못할 수 있으면
other또는none of the above선택지를 추가하십시오. -
Score는 답변이 스펙트럼 위에 있고 그 스펙트럼의 각 지점이 무엇을 의미하는지 설명할 수 있을 때 적합합니다. 버그 심각도, 고객 불만, 기술 수준 등입니다. 레벨은 여러분이 정의하며, 모델은 그 위의 위치를 반환합니다.
-
Noul은 확률 자체가 유용한 신호인 명확한 yes/no 질문에 적합합니다. 이 메시지에 개인 식별 정보가 포함되어 있는지, 고객이 환불을 요청하는지, 이력서에 분산 시스템이 언급되어 있는지 등입니다.
두 유형이 모두 적합해 보이면, 코드가 답변에 직접 작용할 수 있는 쪽을 선호하십시오. refund, rebook, information 사이의 Choice는 세 개의 코드 경로에 그대로 대응합니다. 고객 불만의 Score는 임계값에 대응합니다. Noul은 if에 대응합니다.
무엇이 반환되는가
답변도 프리미티브입니다. 각 질문 유형은 코드가 비교하거나, 임계값을 적용하거나, 정렬하거나, 추가 로직에 넘기거나, 후속 요청의 상태에 넣을 수 있는 타입 지정된 값을 반환합니다(한 질문이 다른 질문에 의존할 때 참조).
| 유형 | 답변 필드 | 읽는 방법 |
|---|---|---|
| Choice | choice, probabilities, confidence |
choice는 선택된 선택지입니다. probabilities는 모든 선택지에 걸친 분포입니다. confidence는 그 분포가 얼마나 뾰족한지 요약합니다. |
| Score | score, legend, probabilities, confidence |
score는 레벨을 따라가는 위치이며 두 레벨 사이에 떨어질 수 있습니다. legend는 레벨을 번호로 반복합니다. probabilities는 레벨에 걸친 분포입니다. |
| Noul | noul |
답변이 yes일 확률입니다. 1에 가까우면 강한 yes, 0에 가까우면 강한 no, 0.5에 가까우면 불확실합니다. Noul에는 별도의 confidence가 없습니다. |
이 답변들의 두 가지 속성이 이들을 조합 가능하게 만듭니다.
- 모든 답변은 여러분이 제공한 선택지로 제한됩니다. 모델은 선택지나 레벨에 걸친 확률 분포를 반환하며, 결코 그 밖의 값을 반환하지 않습니다. 코드가 생성된 산문에서 값을 복구할 필요가 없습니다.
- 모든 답변은 독립적입니다. 한 질문의 답변이 다른 질문의 숨은 컨텍스트가 되지 않습니다. 다른 질문의 결과를 바꾸지 않고 질문을 추가하거나 제거할 수 있습니다.
신뢰도는 confidence가 probabilities에서 어떻게 도출되는지, 그리고 언제 자동으로 행동하고 언제 사람에게 에스컬레이션할지 결정하는 데 어떻게 사용하는지 설명합니다.
특정 필드 참조하기
평가되는 콘텐츠인 상태는 흔히 대화, 기록, 정책 등 여러 부분으로 이루어진 JSON 객체입니다. 질문이 그중 한 부분에 관한 것이라면, instructions에서 백틱을 포함한 점과 인덱스 경로로 그 키를 지명하십시오. 그러면 모델이 상태의 어느 부분을 판단해야 하는지 알게 됩니다.
State 페이지의 지원 대화를 예로 들어 보겠습니다.
{
"ticket": {
"subject": "Duplicate charge",
"messages": [
{"from": "customer", "text": "I was charged twice for order A-104. Please refund the duplicate."},
{"from": "support", "text": "We are checking the charges."}
]
},
"order": {
"id": "A-104",
"charges": [
{"amount_usd": 49, "status": "captured"},
{"amount_usd": 49, "status": "captured"}
]
},
"refund_policy": "Duplicate charges are eligible for a refund."
}
다음 두 질문은 경로로 고객의 메시지, 정책, 청구 내역을 가리킵니다.
questions = {
"refund_requested": {
"type": "noul",
"instructions": "Does `ticket.messages[0].text` request a refund?",
},
"policy_supports_refund": {
"type": "noul",
"instructions": (
"Does `refund_policy` support the refund requested "
"in `ticket.messages[0].text`, given `order.charges`?"
),
},
}
명시적 경로는 구조화된 상태의 어느 부분이 각 판단에 영향을 주어야 하는지 분명히 합니다. 입력을 구조화하는 방법은 상태를 참조하십시오.
여러 질문을 함께 하기
같은 상태를 사용하는 모든 질문을 하나의 요청에 보내십시오. 질문 유형을 자유롭게 섞을 수 있습니다. System One 모델은 요청의 모든 질문을 병렬로 평가합니다. 질문을 추가해도 응답 시간은 거의 변하지 않으며, 추가 질문에 대한 토큰만 소모되는데 이는 저렴합니다. 필요하지 않을 수도 있는 질문을 하는 것은 거의 무료입니다.
다음 요청은 고객 메시지를 분류하고, 긴급성을 확인하고, 불만을 점수화하는 것을 한 번에 수행합니다.
{
"state": "Our API integration started returning 500 errors on every request about 20 minutes ago, and we can't process any customer orders until this is fixed.",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this",
"criteria": {
"billing": "Payment or subscription issues",
"technical": "Bugs or integration problems",
"sales": "Pricing or account questions"
}
},
"is_urgent": {
"type": "noul",
"instructions": "The message conveys urgency or time-sensitivity"
},
"frustration": {
"type": "score",
"instructions": "How frustrated the customer appears",
"criteria": [
"Calm, just stating facts",
"Frustrated but civil",
"Very angry, strong language"
]
}
}
}저희 클라이언트 SDK는 타입이 지정된 질문과 답변을 제공합니다. Python에서는 Choice, Noul, Score 객체의 questions 딕셔너리를 client.system_one(...)에 전달하십시오. 다음 요청은 티켓과 환불 정책을 한 번 보내고 각 질문에 대한 타입 지정된 답변을 받습니다.
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
state = {
"ticket_message": "My flight was cancelled. Can I get a refund?",
"refund_policy": "Cancelled flights are eligible for a full refund.",
}
with TypeSafeClient() as client:
response = client.system_one(
state=state,
questions={
"refund_requested": Noul(
instructions="Does `ticket_message` request a refund?",
),
"request_type": Choice(
instructions="What is the main request in `ticket_message`?",
criteria={
"refund": "The customer wants money returned.",
"rebooking": "The customer wants a replacement flight.",
"information": "The customer is asking for information only.",
},
),
"frustration": Score(
instructions="How frustrated does the customer appear in `ticket_message`?",
criteria=[
"Calm and neutral.",
"Concerned but civil.",
"Very angry or using strong language.",
],
),
},
)
print(response.answers["refund_requested"].noul)
print(response.answers["request_type"].choice)
print(response.answers["frustration"].score)
설치 및 사용 언어별 사용법은 클라이언트 SDK를 참조하십시오.
투기적 질문 하기
코드가 필요로 할 수 있는 모든 질문을 하십시오. 답변이 일부 입력에만 중요한 질문도 포함하고, 어떤 답변을 사용할지는 코드가 결정하게 하십시오. 티켓이 버그 보고가 아닌 것으로 밝혀지면 심각도 답변을 무시하십시오. 이것을 투기적 팬아웃 패턴이라고 합니다. 병렬 질문 쿡북은 13개 질문을 하나의 호출로 묶는 것이 13개의 개별 호출보다 11.5배 저렴하고 9.6배 빠르며, 답변은 변하지 않는다는 것을 보여줍니다.
복잡한 판단을 여러 질문으로 나누기
여러 가지에 달려 있는 판단은 한 가지당 하나의 질문으로 나누는 것이 가장 좋습니다. 코드에서 답변을 결합하고 각각에 상대적 중요도에 따른 가중치를 부여하십시오. 가중치는 여러분의 것입니다. 결합된 결과가 팀이 내릴 결정과 맞지 않으면 코드에서 바꾸고 다시 실행하십시오. 질문들은 하나의 요청 안에서 병렬로 실행되므로 추가해도 응답 시간은 거의 변하지 않습니다. 분할은 약간의 추가 질문 토큰을 소모합니다.
예를 들어 티켓 우선순위는 세 개의 Score 질문으로 구성할 수 있습니다. 버그가 얼마나 심각한지, 고객이 얼마나 불만인지, 보고서가 엔지니어에게 얼마나 많은 정보를 주는지입니다. Score 페이지에서는 이 요청과 답변을 정규화하고 가중치를 부여하는 코드를 복잡한 판단을 여러 Score로 나누기에서 자세히 다룹니다. 이 기법을 복합 스코어링 패턴이라고 합니다.
한 질문이 다른 질문에 의존할 때
같은 요청의 질문들은 독립적입니다. 한 답변이 다른 질문의 컨텍스트가 되지 않습니다. 뒤의 판단이 앞의 답변에 의존한다면 코드에서 두 번째 요청을 만드십시오. 의존성은 코드가 첫 번째 답변을 얻기 전까지 두 번째 요청을 구성할 수 없을 때만 실제입니다. 상태를 위한 데이터를 더 가져오거나, 상태가 무엇으로 이루어졌는지 결정하거나, 다음 질문의 선택지를 고르기 위해 답변이 필요할 때입니다. 그렇지 않다면 질문을 함께 하고 답변을 코드에서 결합하십시오.
두 번의 요청은 규칙이 아니라 예외입니다. 두 번째 요청의 질문을 원래 상태에 대해 물을 수 있었다면, 첫 번째 요청에서 함께 하고 코드가 필요 없는 것을 무시하게 하십시오. 세 개의 쿡북이 실제 이유로 두 번째 요청을 합니다. 스킬 제안은 한 요청에서 182개의 스킬을 순위 매긴 뒤, 상위 세 개의 전체 텍스트를 가져와 더 나은 근거로 다시 판단합니다. 구조 복구는 각 줄 바꿈이 문장을 나눴는지 질문하고, 그 답변으로 줄을 블록으로 병합한 다음 블록을 분류합니다. 블록은 첫 번째 요청이 답하기 전까지 존재하지 않았습니다. 계층적 분류는 각 Choice 답변을 사용해 다음 요청이 제공할 선택지를 결정합니다.
워크플로를 집중된 판단으로 나누는 지침은 TypeSafe로 구축하는 방법을 참조하십시오.
다음 단계
Choice
고정된 목록에서 하나의 선택지를 고릅니다.
Score
정렬된 레벨을 따라 상태를 평가합니다.
Noul
어떤 진술이 참일 확률을 얻습니다.
이것들이 시스템 아키텍처로 어떻게 구성되는지 보려면 패턴으로 가십시오.