Use Claude with reasoning
Have Claude think before it answers, and read what it thought.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/provider/types"
"github.com/digitallysavvy/go-ai/pkg/providers/anthropic"
)
func main() {
model, err := anthropic.New(anthropic.Config{APIKey: os.Getenv("ANTHROPIC_API_KEY")}).
LanguageModel(anthropic.ClaudeSonnet5_5)
if err != nil {
log.Fatal(err)
}
// One portable setting. The SDK maps it to Claude's thinking budget.
effort := types.ReasoningMedium
result, err := ai.GenerateText(context.Background(), ai.GenerateTextOptions{
Model: model,
Prompt: "A train leaves at 3:40 and the trip takes 2 hours 35 minutes. When does it arrive?",
Reasoning: &effort,
})
if err != nil {
log.Fatal(err)
}
// Reasoning blocks are content parts of the final step.
if len(result.Steps) > 0 {
for _, part := range result.Steps[len(result.Steps)-1].Content {
if rc, ok := part.(types.ReasoningContent); ok {
fmt.Println("reasoning:", rc.Text)
}
}
}
fmt.Println("answer:", result.Text)
}
Run it:
ANTHROPIC_API_KEY=... go run ./examples/recipes/claude-reasoning
Notes
Reasoningis a*types.ReasoningLevel. Pass a pointer totypes.ReasoningMediumor another level. Nil leaves the provider default.- The SDK maps the level to a thinking budget for the model you chose.
- Reasoning comes back as
types.ReasoningContentparts in the step content, not as a top-level field. - For provider-specific control, use
anthropic.ModelOptionswithThinkingConfigthroughLanguageModelWithOptions.
Go deeper
The full program is at examples/recipes/claude-reasoning/main.go.