A1.0 What This Teaches
- The
input()loop that drives an interactive console app - Maintaining conversation history across turns with the
messageslist - The
/quitcommand to exit cleanly - Appending both user and assistant messages to preserve context
- Adding a system prompt to specialize the chat session
- Context window limits and what to do when history grows large
A1.1 Application Design
- Print the
You:prompt and wait for input - Read the user's text with
input() - If the input is
/quit, print a goodbye message and break - Append a
{"role": "user", "content": ...}dict to the history list - Call
client.messages.createwith the full history - Extract the reply text from
response.content[0].text - Print the reply
- Append a
{"role": "assistant", "content": reply}dict to the history list
A1.2 Complete Implementation
# chat_loop.py - interactive console chat with conversation history.
import anthropic
client = anthropic.Anthropic()
messages = []
print("Claude Chat - type /quit to exit")
print("-" * 40)
while True:
user_input = input("You: ").strip()
if not user_input:
continue
if user_input.lower() == "/quit":
print("Goodbye.")
break
messages.append({"role": "user", "content": user_input})
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages
)
reply = response.content[0].text
messages.append({"role": "assistant", "content": reply})
print(f"Claude: {reply}")
print()
chat_loop.py and run
it. Each call passes the full messages list, so the model always sees
the complete conversation.
A1.3 How Conversation History Works
messages.create includes every prior turn. After 10
exchanges the list has 20 entries; after 20 exchanges it has 40. All of that text
is sent to the API on each call and counts against the model's context window.
# Add this check inside the loop, after appending the user message.
if len(messages) > 40:
print("[Warning: conversation is getting long. Consider /clear to reset history.]")
A1.4 Adding a System Prompt
create call as the system parameter:
# chat_loop_system.py - specialize the assistant with a system prompt.
import anthropic
client = anthropic.Anthropic()
messages = []
SYSTEM = "You are a Python coding assistant. Keep answers concise and include code examples."
print("Python Coding Assistant - type /quit to exit")
print("-" * 40)
while True:
user_input = input("You: ").strip()
if not user_input:
continue
if user_input.lower() == "/quit":
print("Goodbye.")
break
messages.append({"role": "user", "content": user_input})
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=SYSTEM, # applied to every turn automatically
messages=messages
)
reply = response.content[0].text
messages.append({"role": "assistant", "content": reply})
print(f"Claude: {reply}")
print()
system string is not part of the messages list. Pass
it as a separate keyword argument. It applies to the entire conversation.
A1.5 Adding a /clear Command
# Inside the while loop, before appending the user message:
if user_input.lower() == "/clear":
messages = []
print("[History cleared. Starting fresh.]")
continue
/clear, messages is an empty list. The next user
turn starts a brand-new conversation with no prior context.
A1.6 Running the Application
python chat_loop.py
Claude Chat - type /quit to exit
----------------------------------------
You: What is a Python list?
Claude: A Python list is an ordered, mutable collection of items. You create one
with square brackets: my_list = [1, 2, 3]. Items can be any type and the list
grows or shrinks as you add or remove elements.
You: How do I add an item?
Claude: Use .append() to add to the end: my_list.append(4). Use .insert(index, item)
to add at a specific position.
You: /quit
Goodbye.
A1.7 Exercise
Exercise
Extend
Handle both commands before the API call so they do not add anything to the
chat_loop.py with two new commands:
-
/history - print every message in the
messageslist. For each entry, print the role and the first 60 characters of the content on one line, for example:user: What is a Python list? -
/tokens - print an estimated total token count for the current
history. Use
len(m["content"]) // 4as a rough estimate per message, and sum across all messages.
messages list.
A1.8 Common Mistakes
Not appending the assistant reply to messages
# Bad - the loop appends user messages but not assistant replies.
while True:
user_input = input("You: ").strip()
messages.append({"role": "user", "content": user_input})
response = client.messages.create(model="claude-sonnet-4-6",
max_tokens=1024, messages=messages)
reply = response.content[0].text
# Missing: messages.append({"role": "assistant", "content": reply})
print(f"Claude: {reply}")
Growing history without bound
Calling input() without .strip()
# Bad - " /quit " with surrounding spaces will not match "/quit".
user_input = input("You: ")
if user_input == "/quit": # fails if user types with spaces
# Good - strip whitespace before comparing.
user_input = input("You: ").strip()
if user_input.lower() == "/quit": # matches regardless of spacing or case
.strip()
immediately after input().
A1.9 Key Terms
| Term | Meaning |
|---|---|
| chat loop | A while True loop that repeatedly reads user input and calls the API |
| conversation history | The growing list of user and assistant messages passed on every API call |
| /quit command | A special input string the loop checks to break out cleanly |
| context limit | The maximum total tokens (prompt + response) a model can process in one call |
| system prompt for chat | A fixed instruction string passed via the system parameter that shapes the model's behavior across all turns |
| interactive console | A terminal application that reads from stdin and writes to stdout in a loop |