Multi-turn state

The OpenAI-compatible chat completions endpoint is stateless. Every request you send must include the entire conversation so far. The agent carries that state in a Go slice and resends it, which is why growing message history is the thing that eats your context window.

agent/agent.go
go
// messages starts small
messages := []Message{
	{Role: "system", Content: a.System},
	{Role: "user", Content: userMsg},
}

// and grows on every turn
messages = append(messages, choice.Message) // assistant with tool_calls
messages = append(messages, Message{        // tool result
	Role:       "tool",
	ToolCallID: tc.ID,
	Name:       tc.Function.Name,
	Content:    result,
})

On iteration three, the request body includes iterations one and two. The server has no memory of the previous call. You are the memory.

Flashcards: Flashcards

Loading practice…

Quiz: Quiz

Loading practice…