Implementation:Ollama Ollama Thinking Parser
| Knowledge Sources | |
|---|---|
| Domains | Thinking, Output Parsing |
| Last Updated | 2025-02-15 00:00 GMT |
Overview
State-machine parser that separates LLM output into thinking content (reasoning traces) and regular content based on configurable opening/closing tags.
Description
The Parser tracks five states: looking for opening tag, eating whitespace after opening, collecting thinking content, eating whitespace after closing tag, and done thinking. AddContent accepts streaming text chunks and returns thinking and remaining content separately. The parser handles partial tag matches by buffering ambiguous content until it can be disambiguated. If no opening tag is found (model skips thinking), all content is returned as regular content. The overlap helper detects partial tag matches at chunk boundaries to avoid splitting tags across calls.
Usage
Used in the streaming response pipeline to separate thinking/reasoning content from final answers, enabling the client to display them differently.
Code Reference
Source Location
- Repository: Ollama
- File: thinking/parser.go
- Lines: 1-173
Signature
type Parser struct {
state thinkingState
OpeningTag string
ClosingTag string
acc strings.Builder
}
func (s *Parser) AddContent(content string) (thinking string, remaining string)
Import
import "github.com/ollama/ollama/thinking"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| content | string | Yes | Streaming text chunk from the model |
Outputs
| Name | Type | Description |
|---|---|---|
| thinking | string | Thinking/reasoning content extracted from this chunk |
| remaining | string | Regular content to display to the user |
Usage Examples
parser := &thinking.Parser{
OpeningTag: "<think>",
ClosingTag: "</think>",
}
// Process streaming output
t1, r1 := parser.AddContent("<think>Let me")
// t1="", r1="" (buffering partial tag)
t2, r2 := parser.AddContent(" analyze this...")
// t2="Let me analyze this...", r2=""
t3, r3 := parser.AddContent("</think>The answer is 42.")
// t3="", r3="The answer is 42."