Repository navigation
Questions EN
English | 简体中文
Four question kinds are supported: Noul (yes/no), Choice (categorical), Score (ordinal rubric), and Box (bounding box object localization).
All accept instructions — what the model should decide or find — as a string, a JSON object, or an array, and all are answered with a calibrated probability distribution or bounding box coordinates you can threshold yourself.
Questions travel as a map (typesafe.Questions) because the names are yours to choose: they are the keys you read the answers back with, so they cannot be struct fields. The map's values are typed as typesafe.Question, which means a value that is not a question fails to compile. For a question shape this version does not model, wrap a plain map in typesafe.RawQuestion. A caller holding an untyped map[string]any passes it to the client directly; SystemOne accepts any of the containers typesafe.NormalizeQuestions documents and validates them at run time.
The probability that a statement holds, in [0, 1]. Values near 1 mean yes or true, values near 0 mean no or false, and values near 0.5 mean the content does not decide it.
typesafe.NewNoul("Is this message spam?")
typesafe.NewNoul("Is this message spam?", typesafe.WithNoulCriteria(typesafe.NoulCriteria{
True: "Unsolicited advertising or phishing",
False: "A legitimate conversation",
}))NewNoul(instructions any, opts ...QuestionOption) *NoulQuestion — the instructions may be a string, a map, or a slice, and may be "" when criteria alone describe the question. Criteria are free-form: use a string, or a structured object when examples help.
typesafe.NewNoul("", typesafe.WithNoulCriteria(typesafe.NoulCriteria{
True: map[string]any{"meaning": "Payments or invoices", "examples": []any{"charged twice", "refund"}},
}))Threshold the answer where your decision needs it:
if response.Nouls()["is_spam"].Noul > 0.9 {
quarantine(message)
}The best-matching label, with the model's confidence and a probability for every label. Use it whenever the options are known ahead of time and exactly one applies.
typesafe.NewChoice(
map[string]any{
"billing": "Charges, refunds, or invoices",
"technical": "Bugs, crashes, or API problems",
"other": nil, // nil means "no description needed"
},
typesafe.WithInstructions("Which department should handle this request?"),
)NewChoice(criteria map[string]any, opts ...QuestionOption) *ChoiceQuestion. Each criteria value is a label description: a string, a JSON object, an array, or nil for a label the name already describes. Supports up to 255 options. A choice question with no criteria is rejected before the request is sent.
answer := response.Choices()["category"]
fmt.Println(answer.Choice) // billing
fmt.Println(answer.Confidence) // 0.87
fmt.Println(answer.Probabilities) // map[billing:0.87 technical:0.09 other:0.04]An expected value across an ordered rubric whose levels start at 0. Use it for priority, quality, and severity scales where "how much" matters more than "which one".
typesafe.NewScore(
[]any{"routine", "elevated", "critical emergency"},
typesafe.WithInstructions("Rate the severity of this issue"),
)NewScore(criteria []any, opts ...QuestionOption) *ScoreQuestion. The score is the probability-weighted average of the rubric levels, so it may fall between two levels; the reported legend and probabilities are keyed by level, so you can always read the distribution. Supports between 2 and 10 levels. An empty rubric or fewer than 2 levels is rejected with a *typesafe.ScoreError.
answer := response.Scores()["urgency"]
fmt.Println(answer.Score) // 1.7
fmt.Println(answer.Confidence) // 0.85
fmt.Println(answer.Legend[2]) // "critical emergency"
fmt.Println(answer.Probabilities[2]) // 0.80Locates an object or subject described by instructions within an image, returning normalized bounding box coordinates (BoxCoordinates).
Note: Box questions require image support enabled via
WithImages(true)orWithCallImages(true)(x-typesafe-images: trueheader) and a multimodal model (such asjev-preview).
typesafe.NewBox("the coffee mug in the photo")
typesafe.NewBox("the person wearing glasses in state.photo")NewBox(instructions any, opts ...QuestionOption) *BoxQuestion:
-
instructionsdescribe the subject to locate in the image. - Box questions do not accept criteria (bounding box prediction is continuous spatial localization, not a discrete set of categories).
- Returns normalized bounding box coordinates in
[0, 1]:-
Top: Distance from top edge as fraction of image height. -
Bottom: Distance from top edge as fraction of image height. -
Left: Distance from left edge as fraction of image width. -
Right: Distance from left edge as fraction of image width. -
Confidence: Optional model confidence float.
-
answer := response.Boxes()["cup_box"]
fmt.Printf("Top=%.2f, Bottom=%.2f, Left=%.2f, Right=%.2f\n",
answer.Box.Top, answer.Box.Bottom, answer.Box.Left, answer.Box.Right)| Option | Effect |
|---|---|
WithInstructions(any) |
The question to ask: a string, a JSON object, or an array. Overrides instructions passed positionally. |
WithNoulCriteria(NoulCriteria) |
Describes the yes and no outcomes of a noul question. |
WithQuestionField(key string, value any) |
Adds a field this version does not model to the wire form; a colliding field replaces the modeled one. |
Instructions that are nil or blank are left off the wire entirely, so typesafe.NewNoul("", typesafe.WithNoulCriteria(...)) sends a question described only by its criteria. A structured instruction (an object or an array) is always sent, even when empty.
RawQuestion sends a question as a plain map, for request fields this version does not model:
typesafe.Questions{
"billing": typesafe.RawQuestion{"type": "noul", "instructions": "Is this about billing?"},
"queue": typesafe.RawQuestion{
"type": "choice",
"criteria": map[string]any{"billing": nil, "other": nil},
"weight": 3, // a hypothetical field a newer API accepts
},
}NormalizeQuestions(questions) is the same validation the client applies. It accepts Questions, map[string]Question, the typed question maps (map[string]*NoulQuestion, map[string]*BoxQuestion, and siblings), map[string]any, and RawQuestion, and rejects an empty set with At least one question is required.
| Input | When a mistake is caught |
|---|---|
typesafe.Questions with a non-question value |
Compile time |
NewChoice with no criteria |
Before the request is sent |
NewScore with an empty rubric (< 2 levels) |
Before the request is sent |
An untyped map[string]any question |
Before the request is sent, by NormalizeQuestions
|
| A field the server rejects | The server's 400/422, as a typed error |
Validation happens before the request is built, so an invalid question never reaches the network.
- 指南
- Guides