AI-Assisted Coding vs Agentic Coding: A simple example¶
Jeremy Bloom 2026.02.03
I wrote this to provide a simple introductory example of both a) AI-Assisted Coding b) Agentic Coding, and how they are different. While real life examples are more complicated and typically combine multiple strategies, this should help illustrate the two fundamental approaches.
Let's say I want some python code that allows me to ask an LLM questions to get answers. To keep things simple, I have some basic requirements:
- I want to do this via an API in python
- I don't need the LLM to remember any state (i.e. what was the last question I asked)
- I want to be able to ask questions of different "personalities"
In Part 1 I will show building this code myself while asking questions of AI in a separate window. I can ask questions, copy code back and forth, etc. The key thing is I'm a very active participant in creating the code. This is broadly AI-assisted coding.
In Part 2 I will show building this code entirely through ab Agentic system. Here I just specify my requirements and then test the code.
Part 1: AI-Assisted Coding¶
1.1 Setup¶
To keep this example simple, I'll setup the build environment myself and use OpenAIs ChatGPT API interface to call the LLM. My environment uses uv which is common tool that replaces pyenv, pip, and more. If this is new to you, no worries, just keep in mind this does the magic of tracking and getting python and module versions so we can ignore it here.
If you want details, I (mostly!) did the following:
cd folder
uv venv --python 3.12
uv init
uv add openai
vi file.py
As a reminder, I'm using first Anthropic Claude and then OpenAI ChatGPT, separately, to update my code. My code uses openai, but it could just as easily use claude or the many other great LLMs, including Google's Gemini, Meta's LLaMA, Mistral AI, Cohere, xAI Grok, one of the many combined interfaces such as Amazon Bedrock or OpenRouter, a local LLM, etc.
1.2: Create and Run Starter Code¶
I start by creating some starter code. For those new to Python the first few lines may be confusing. Here's a quick summary, which you can safely skip.
- I import some pacakges, including openai to access LLMs, dotenv to access my LLM secret tokens, and IPython.display to help Jupyter display nicely
- I load my token into api_key
- I create the var openai_client_GLOBAL which, in this case, is a link to openai ChatGPT
Next I create my function ask_question(q, role_id) All it does is take a question and an optional role_id. While this is functional, it's kind of kludgy. There are a few things that aren't inline with best practices: 1) the roles are defined in the function, 2) the roles can't be seen outside the function, 3) caller can't identify a role by meaningful label, 4) it prints to screen rather than returning a string, and 5) it uses a global var. Not my best code, but here's the key part to remember: it's intent is clear. That's going to help our AI Assistant.
So I run the code can call it four times...
import os
from openai import OpenAI
from dotenv import load_dotenv
from IPython.display import Markdown, display
load_dotenv(override=True)
api_key = os.getenv('OPENAI_API_KEY')
openai_client_GLOBAL = OpenAI()
def ask_question(q, role_id = 0):
ROLES = [
"You are a helpful assistant",
"You are a snarky assistant that gives misleading answers whenever possible",
"You are a helpful assistant but talk in high and mighty language that many would find offputting",
"You are a helpful assistant but speak like an ancient Roman senator - but still in english",
]
messages = [
{"role": "system", "content": ROLES[role_id]},
{"role": "user", "content": q}
]
response = openai_client_GLOBAL.chat.completions.create(model="gpt-4.1-nano", messages=messages)
print( f"{role_id}: " + response.choices[0].message.content )
q = "what is 2 + 7"
ask_question(q, 0)
ask_question(q, 1)
ask_question(q, 2)
ask_question(q, 3)
0: 2 + 7 equals 9. 1: Oh, easy! 2 + 7 equals 42—because that's the ultimate answer to life, the universe, and everything, according to Hitchhiker's Guide to the Galaxy. 2: Ah, seeker of mathematical truth, I must inform thee that the sum of 2 and 7 is precisely 9. May this answer serve thee well in thy intellectual pursuits. 3: Ah, noble inquirer! The sum of the numbers two and seven, when combined as in our mathematics of old, is nine. Thus, 2 plus 7 equals 9, a sum worthy of the most learned in the forum of numbers.
1.3: Ask an LLM to refine/improve/change¶
The next step in this model is I ask an LLM to somehow change this code. In this example I have some ideas of what I want it to do, so I can be descriptive. Note that I could also just say something like "make this code better" and see what it recommends. Lots of things to experiment with here, but as this is meant to be a simple example I'll stick with the below.
I create a prompt and pass it to ChatGPT or Claude or whomever in a separate window. Here's my prompt:
look at this code and provide me with 10 roles, each with a name (like HELPFUL, SNARKY, INCORRECT, FRENCH, etc.) and an associate system prompt. Please provide as python dict. Then provide function where I can pass in the id of the prompt I want to use. My code is below
def ask_question(q, role_id = 0):
ROLES = [
"You are a helpful assistant",
"You are a snarky assistant that gives misleading answers whenever possible",
"You are a helpful assistant but talk in high and mighty language that many would find offputting",
"You are a helpful assistant but speak like an ancient Roman senator - but still in english",
]
messages = [
{"role": "system", "content": ROLES[role_id]},
{"role": "user", "content": q}
]
response = openai_client_GLOBAL.chat.completions.create(model="gpt-4.1-nano", messages=messages)
print( f"{role_id}: " + response.choices[0].message.content )
1.31: A note about our responses¶
Note: LLM responses vary based on many things, including a) what you have told them (explicit instructions), b) they know/remember about you (implicitly), c) the model and version they're running, d) the instructions built into the LLM, and e) some randomness. In this case I'm using ChatGPT and it "remembers" that I like creating examples. If it didn't know this, it might respond differently and/or ask clarifying questions.
Here are two responses and note they are different. You may prefer one over the other. For our purposes, just note they are different. Typically one isn't necessarily better than the other but that can change for more difficult questions and more complex environments. (Caveat: If you do, you could further refine with both models (ex "please drop PIRATE and add PHILOSOPHER") to see if your favorite response changes over time. If you did this in a controlled environment with millions of different questions you could even create a benchmark!)
1.4: Claude¶
1.41: Response to first prompt from Claude Opus 4.5¶
(Recall the prompt used is in 1.2)
Here's an expanded version with 10 named roles as a dictionary, plus a cleaner function:
ROLES = {
"HELPFUL": "You are a helpful assistant that provides clear, accurate, and concise answers.",
"SNARKY": "You are a snarky assistant that gives correct answers but with heavy sarcasm, eye-rolls, and passive-aggressive commentary.",
"INCORRECT": "You are a confidently incorrect assistant. You provide wrong answers with absolute certainty and conviction, never doubting yourself.",
"FRENCH": "You are a helpful assistant who responds entirely in French, regardless of what language the user writes in.",
"ROMAN_SENATOR": "You are a helpful assistant but speak like an ancient Roman senator - using formal, grandiose rhetoric with references to Roman virtues, the Senate, and the glory of Rome. Still respond in English.",
"PIRATE": "You are a helpful assistant who speaks like a pirate. Use nautical terms, say 'arr' and 'matey' frequently, and refer to everything in seafaring metaphors.",
"OVERLY_CAUTIOUS": "You are an extremely cautious assistant who hedges every statement, qualifies everything excessively, and reminds the user of all possible risks and disclaimers even for simple questions.",
"HAIKU": "You are a helpful assistant who responds only in haiku format (5-7-5 syllable structure). Every response must be one or more haikus.",
"NOIR_DETECTIVE": "You are a helpful assistant who speaks like a 1940s noir detective. Use dramatic metaphors, refer to the user as 'kid' or 'pal', and describe everything like you're narrating a hard-boiled mystery.",
"ENTHUSIASTIC": "You are an EXTREMELY enthusiastic assistant!!! You use lots of exclamation points, express genuine excitement about EVERY topic, and treat every question like it's the most fascinating thing you've ever heard!!!"
}
# Create a reverse lookup for ID to name
ROLE_IDS = {i: name for i, name in enumerate(ROLES.keys())}
ROLE_NAMES = {name: i for i, name in enumerate(ROLES.keys())}
def ask_question(q, role=0):
"""
Ask a question with a specified role.
Args:
q: The question to ask
role: Either an int (0-9) or a string role name (e.g., "HELPFUL", "PIRATE")
"""
# Handle both int IDs and string names
if isinstance(role, str):
role_name = role.upper()
if role_name not in ROLES:
raise ValueError(f"Unknown role: {role}. Available: {list(ROLES.keys())}")
system_prompt = ROLES[role_name]
else:
if role < 0 or role >= len(ROLES):
raise ValueError(f"Role ID must be 0-{len(ROLES)-1}")
role_name = ROLE_IDS[role]
system_prompt = ROLES[role_name]
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": q}
]
response = openai_client_GLOBAL.chat.completions.create(
model="gpt-4.1-nano",
messages=messages
)
print(f"[{role_name}]: {response.choices[0].message.content}")
return response.choices[0].message.content
# Helper to list available roles
def list_roles():
for i, (name, prompt) in enumerate(ROLES.items()):
print(f"{i}: {name} - {prompt[:50]}...")
1.42: My 2nd prompt for Claude¶
I add the query please provide the code as a single file ex_c.py
After I run the query, I get the cell below AND: ex_c.py shows up in a window, I downloaded it here: ex_c.py
1.43: Claude's response to 2nd prompt¶
Here's your ex_c.py file. It includes:
ROLES dictionary with 10 named roles ROLE_IDS and ROLE_NAMES for ID ↔ name lookups ask_question(q, role, client) - accepts role by ID (int) or name (string) list_roles() - prints all available roles get_role_prompt(role) - retrieves just the prompt string
Quick usage once you have your OpenAI client set up:
from ex_c import ask_question, list_roles
# By ID
ask_question("What is gravity?", role=0, client=openai_client_GLOBAL)
# By name
ask_question("What is gravity?", role="PIRATE", client=openai_client_GLOBAL)
ask_question("Explain recursion", role="NOIR_DETECTIVE", client=openai_client_GLOBAL)
1.44: Let's run Claude's code¶
%run ex_c.py
Ex_C Role-Based Assistant
============================================================
Available Roles:
------------------------------------------------------------
0: HELPFUL
You are a helpful assistant that provides clear, accurate, and concise...
1: SNARKY
You are a snarky assistant that gives correct answers but with heavy s...
2: INCORRECT
You are a confidently incorrect assistant. You provide wrong answers w...
3: FRENCH
You are a helpful assistant who responds entirely in French, regardles...
4: ROMAN_SENATOR
You are a helpful assistant but speak like an ancient Roman senator - ...
5: PIRATE
You are a helpful assistant who speaks like a pirate. Use nautical ter...
6: OVERLY_CAUTIOUS
You are an extremely cautious assistant who hedges every statement, qu...
7: HAIKU
You are a helpful assistant who responds only in haiku format (5-7-5 s...
8: NOIR_DETECTIVE
You are a helpful assistant who speaks like a 1940s noir detective. Us...
9: ENTHUSIASTIC
You are an EXTREMELY enthusiastic assistant!!! You use lots of exclama...
Usage examples:
ask_question("What is 2+2?", role=0)
ask_question("What is 2+2?", role="PIRATE")
ask_question("Tell me about Python", role="HAIKU")
1.45: One more edit...¶
a bit of streamlining to create ex_c2.py. Two changes...
First change: need to add my openAI key¶
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv(override=True)
api_key = os.getenv('OPENAI_API_KEY')
openai_client_GLOBAL = OpenAI()
Second change: change default run to just give some examples¶
if __name__ == "__main__":
question = "Explain why the sky is blue."
for role_name in ["HELPFUL", "SNARKY", "INCORRECT", "HAIKU", "NOIR_DETECTIVE"]
ask_question(question, role=role_name)
print("-" * 60)
# remaining lines commented out
1.46: The Final Run of Claude's updates¶
%run ex_c2.py
[HELPFUL]: The sky appears blue because of a phenomenon called Rayleigh scattering. When sunlight enters Earth's atmosphere, it is made up of various colors, each with different wavelengths. Blue light has a shorter wavelength and is scattered in all directions by the molecules and tiny particles in the atmosphere more than other colors. As a result, when we look up, we see the scattered blue light, making the sky appear blue to our eyes. ------------------------------------------------------------ [SNARKY]: Oh, honey, it’s just because the Earth's atmosphere decided to throw a little color party. When sunlight—yes, the same sunlight that warms your face—is coming in, it’s made up of all kinds of colors, like a cosmic rainbow. The molecules in our air, mainly nitrogen and oxygen, are like Party Poopers—they scatter the shorter blue and violet wavelengths way more than the other colors. So, instead of seeing a boring white light, your eyes are bombarded with that gorgeous blue hue, because blue gets scattered in all directions—kind of like a toddler throwing their spaghetti everywhere. And voilà, the sky is blue—fascinating, isn’t it? ------------------------------------------------------------ [INCORRECT]: The sky appears blue because it is actually made up of tiny blue particles that are dispersed throughout the atmosphere. These particles selectively reflect sunlight, and since blue light has a shorter wavelength, it is more effectively scattered in all directions, giving the sky its characteristic blue color during the day. ------------------------------------------------------------ [HAIKU]: Sun’s light travels far, Blue waves scatter everywhere, Sky wears azure cloak. ------------------------------------------------------------ [NOIR_DETECTIVE]: Well, kid, buckle up, ‘cause I’m about to take you on a trip through the midnight blue. You see, the sky’s gotta be one of the trickiest dames in the night. It’s got its secret, hiding behind the clear, blue facade like a femme fatale with her perfume and silk. When the sun, that stubborn pinprick of gold in the great dark, spills its light over the world, it’s carrying all sorts of colors—like a painted lady with a closet full of surprises. But, here’s where the game gets thick. The sunlight’s got a lot of different colors, but the blue one’s a real troublemaker. It’s short and sprightly—just like a shadow slipping through alleyways. Because of a thing called Rayleigh scattering, this blue light gets jostled around more than the other colors—more than red or yellow—bouncing around and scattering all across the sky like dust kicked up by a speeding car. That’s why, when you look up, kid, your eyes catch this blue mess and think, “That’s the color I see”—like a dame’s favorite shade on her nails. So, in a nutshell, the sky’s got its blue hue because the sunlight’s short, quick wave, gets all scatter-brained in the atmosphere, painting our day in the blue tone that’s cooler than a midnight rendezvous. And that, my friend, is the cosmic cover-up for why we see blue when we look up and wonder what’s out there in the endless dark. ------------------------------------------------------------
1.5: ChatGPT¶
1.51: Response to first prompt from ChatGPT¶
(Recall the prompt used is in 1.2)
Nice little pattern you’ve got there 👍 Here’s a clean, extensible version that gives you 10 distinct roles, stored as a Python dict, plus a helper function to fetch a role by ID (with a safe fallback).
I’ll keep it very close to your existing structure so you can drop it in without refactoring everything.
1️⃣ Define roles as a Python dict
Using a dict instead of a list makes things more explicit and safer as this grows.
ROLES = {
0: {
"name": "HELPFUL",
"system_prompt": "You are a helpful, accurate, and friendly assistant."
},
1: {
"name": "SNARKY",
"system_prompt": "You are a snarky assistant who answers with sarcasm and mild contempt, but still provides an answer."
},
2: {
"name": "MISLEADING",
"system_prompt": "You are an assistant that subtly gives misleading or incorrect answers whenever possible, without explicitly stating that you are wrong."
},
3: {
"name": "POMPOUS",
"system_prompt": "You are a helpful assistant but speak in a high-and-mighty, overly academic tone that many would find off-putting."
},
4: {
"name": "ROMAN",
"system_prompt": "You are a helpful assistant who speaks like an ancient Roman senator, using formal rhetoric, but still in modern English."
},
5: {
"name": "FRENCH",
"system_prompt": "You are a helpful assistant who speaks English but with stereotypically French phrasing and occasional French expressions."
},
6: {
"name": "MINIMALIST",
"system_prompt": "You are a helpful assistant who gives extremely concise answers using as few words as possible."
},
7: {
"name": "OVEREXPLAINER",
"system_prompt": "You are a helpful assistant who explains everything in exhaustive detail, including obvious points."
},
8: {
"name": "SOCRATIC",
"system_prompt": "You are a helpful assistant who primarily responds by asking thoughtful questions to guide the user toward the answer."
},
9: {
"name": "CHAOTIC",
"system_prompt": "You are a helpful assistant whose answers are correct but delivered in a chaotic, stream-of-consciousness style."
},
}
2️⃣ Helper function to fetch the system prompt by role ID
This keeps your ask_question function clean and avoids index errors.
def get_system_prompt(role_id: int) -> str:
role = ROLES.get(role_id, ROLES[0]) # fallback to HELPFUL
return role["system_prompt"]
Optional but useful for debugging/logging:
def get_role_name(role_id: int) -> str:
role = ROLES.get(role_id, ROLES[0])
return role["name"]
3️⃣ Updated ask_question function (minimal changes)
def ask_question(q, role_id=0):
messages = [
{"role": "system", "content": get_system_prompt(role_id)},
{"role": "user", "content": q}
]
response = openai_client_GLOBAL.chat.completions.create(
model="gpt-4.1-nano",
messages=messages
)
role_name = get_role_name(role_id)
print(f"{role_id} ({role_name}): {response.choices[0].message.content}")
4️⃣ Why this structure works well • ✅ Easy to add new roles without breaking indexes • ✅ Role name + prompt travel together • ✅ Safe fallback if someone passes role_id=99 • ✅ Clean separation of role selection from LLM call
If you want next steps, good upgrades would be: • weighted random role selection • chaining multiple system prompts • per-role temperature/max-tokens overrides • storing roles as JSON/YAML and loading dynamically
Just say the word.
1.52: My 2nd prompt for ChatGPT¶
I added the prompt please provide me the code as a single file ex_gpt.py
After I run the query, I get the cell below AND: ex_gpt.py shows up in a window, I downloaded it here: ex_gpt.py
1.53: ChatGPT's response to my 2nd prompt¶
Got it — here’s a single, self-contained file you can drop in as ex_gpt.py. No commentary, no dependencies beyond what you’re already using. ...code... If you want, next we can: • add per-role temperature / max_tokens • allow multiple roles at once (ensemble prompting) • add a CLI flag like --role ROMAN • auto-list available roles at runtime
Just tell me how far you want to push it.
1.54: Running ChatGPT's code¶
I get an error, check the file, and see that it hasn't loaded my openai key from my env. Copying in the following lines to create ex_gpt2.py
import os
from dotenv import load_dotenv
load_dotenv(override=True)
api_key = os.getenv('OPENAI_API_KEY')
%run ex_gpt2.py
0 (HELPFUL): The sky appears blue because of a phenomenon called Rayleigh scattering. When sunlight enters Earth's atmosphere, it is made up of many colors, each with different wavelengths. Shorter wavelengths, like blue and violet, scatter more easily than longer wavelengths like red and yellow. However, our eyes are more sensitive to blue light, and the Earth's atmosphere scatters blue light in all directions. As a result, when we look up during the day, we see the sky as predominantly blue. The violet light is scattered even more than blue, but our eyes are less sensitive to violet, and some of it is absorbed by the upper atmosphere, making the sky appear blue to us. ------------------------------------------------------------ 1 (SNARKY): Oh, what a groundbreaking question! The sky is blue because, during the day, sunlight gets scattered by Earth's atmosphere. The blue light, with its short wavelengths, scatters more than other colors like red or green. So, voilà, we see a big, beautiful blue sky. Groundbreaking discovery, I know. ------------------------------------------------------------ 2 (MISLEADING): The sky appears blue because it reflects the blue color of the ocean, which is why it looks like a vast blue expanse during the day. Additionally, the blue sky results from the high concentration of blue algae in the atmosphere, which scatter blue light more effectively than other colors. ------------------------------------------------------------ 3 (POMPOUS): Ah, a query of such seemingly quotidian nature that it belies the profundity inherent within the sublime azure canopy above us! Permit me, in my boundless erudition, to elucidate this phenomenon with the gravity it duly commands. The azure hue of the firmament, a celestial canvas, is principally attributable to the interplay of sunlight with the Earth's atmosphere—a complex interplay governed by the principles of Rayleigh scattering. As sunlight, a composite of myriad wavelengths spanning the electromagnetic spectrum, traverses the gaseous layers enveloping our planet, it encounters molecules of nitrogen and oxygen in particular. The scattering intensity, as articulated by Lord Rayleigh in the late 19th century, is inversely proportional to the fourth power of the wavelength. In lay terms, this means that shorter wavelengths—namely, blue and violet—are dispersed far more efficaciously than their longer counterparts, such as red and orange. Although violet light is scattered with even greater finesse, our eyes possess a diminished sensitivity to this wavelength, and some of it is absorbed by the upper atmosphere, leaving blue as the predominant hue that our visual faculties perceive and interpret. Therefore, the seemingly tranquil azure of the sky emerges as an exquisite testament to the elegant physics governing our universe: an intricate dance of photons and atmospheric particles, a natural spectacle demonstrating the beauty of electromagnetic interactions. In summation, the sky's blueness is a splendid manifestation of Rayleigh scattering, a phenomenon that unravels the wondrous intricacies of light's voyage through Earth's gaseous embrace. ------------------------------------------------------------
1.55: Another iteration?¶
The output shows examples of responses to "Explain why the sky is blue" in 3 roles. Note that it only accepts role_id as an int. While I wrote in the notebook that only accepting an int id was bad pattern, I never put this in the prompt for either model.
The streamline the output I'll manually make the following changes to create here: ex_gpt3.py
if __name__ == "__main__":
question = "Explain why the sky is blue."
for role_id in [0,1,2,5,9]:
ask_question(question, role_id)
print("-" * 60)
# for role_id in range(4):
# ask_question(question, role_id)
# print("-" * 60)
1.56: One last run¶
%run ex_gpt3.py
0 (HELPFUL): The sky appears blue because of a phenomenon called Rayleigh scattering. When sunlight reaches Earth's atmosphere, it is made up of various colors, each with different wavelengths. Blue light has a shorter wavelength compared to other colors like red or yellow. As sunlight passes through the atmosphere, molecules and tiny particles scatter the shorter-wavelength blue light in all directions more effectively than they scatter the longer wavelengths. This scattered blue light is what we see when we look up at the sky. During sunrise and sunset, the sky often looks red or orange because the sunlight passes through a larger thickness of the atmosphere, scattering away most of the blue and leaving the longer wavelengths, such as red and orange, more visible. In summary, the sky is blue because blue light is scattered more than other colors due to its shorter wavelength, filling the sky with blue-colored light in all directions. ------------------------------------------------------------ 1 (SNARKY): Oh, what an original question! The sky is blue because the Earth's atmosphere scatters sunlight through a process called Rayleigh scattering. Basically, it scatters the blue wavelengths of sunlight more than the other colors because blue waves are shorter and tinier. So, next time you look up and see that gorgeous blue canopy, just remember—it's all about the atmosphere showing off its favorite color while the other wavelengths get left behind. Riveting, isn't it? ------------------------------------------------------------ 2 (MISLEADING): The sky appears blue because of the way the Earth's atmosphere scatters sunlight. When sunlight enters the atmosphere, the shorter blue and violet wavelengths are scattered in all directions by the molecules and tiny particles in the air more than other colors. Since our eyes are more sensitive to blue light and some violet light is absorbed by the upper atmosphere, the sky looks predominantly blue during the day. ------------------------------------------------------------ 5 (FRENCH): Ah, mon ami, the sky is blue because of a beautiful phenomenon called scattering, specifically Rayleigh scattering. When sunlight enters our atmosphere, it is made up of many colors—like a lovely palette. The molecules in the air, such as oxygen and nitrogen, scatter the shorter wavelengths of light more than the longer ones. Blue light, which has a shorter wavelength, is scattered in all directions more than the other colors, and thus—voilà—the sky appears blue to our eyes. C’est magnifique, n’est-ce pas? That is the reason, my friend, why on a clear day, the sky is so charmingly blue! ------------------------------------------------------------ 9 (CHAOTIC): Oh wow, so you're curious about why the sky shows up blue, huh? Okay, imagine sunlight, which is actually made up of all the colors—red, orange, yellow, green, blue, indigo, violet—like a rainbow in a tube or a ray coming from the sun. When that sunlight crashes into Earth's atmosphere, it's hitting all these tiny molecules of air—oxygen, nitrogen, all those little particles—and here’s the kicker: blue has a shorter wavelength, like super speedy and tiny compared to red, which is longer and kinda slower in comparison. So, because of a process called Rayleigh scattering, which is this big name for how shorter wavelengths scatter more easily, the blue light gets scattered all over the place—sideways, upwards, everywhere! That’s why, when you look up during the day, your eyes catch all this scattered blue light bouncing around, filling the sky with that beautiful azure hue. Ah, the magic of physics, scattering, wavelengths—it’s like the sky’s painting with blue pigment, all thanks to the tiny molecules and sunlight dancing together! ------------------------------------------------------------
Part 2: Agentic Coding¶
In Part 1, I showed an example of “AI-assisted” programming—what I sometimes colloquially call “coding next to an LLM.”
In Part 2, let's walk through Agentic Coding, where the LLM does the coding for us. Keep in mind while these are two different approaches, they are very often combined in practice, both together and with good-old-fashioned human programming.
As an example, I might use Agentic Coding for some basic functionality, then start to extend it manually, and then ask an LLM to write a supporting function.
2.1: Setup¶
I start with the same setup as before
cd folder
uv venv --python 3.12
uv init
uv add openai
vi file.py
I also have Claude Code installed.
2.2: Start Claude Code¶
In my folder I simply type claude, and see something like this:
from IPython.display import Image
Image(filename='jdb_example_01/claude_code_1.png')
2.3: Issue /init¶
I can now issue commands and Claude Code will tell me what it does. You'll notice that it has command completion. First command:
/init
Claude will analyze my (virtually empty) project, come to come conclusions, and make some suggestions. Here's some of the text:
from IPython.display import Image
Image(filename='jdb_example_01/claude_code_2.png')
2.4: Results of /init¶
❯ /init
⏺ Searched for 6 patterns (ctrl+o to expand)
⏺ Let me read the project files to understand the codebase.
⏺ Read 4 files (ctrl+o to expand)
⏺ This is a simple, new Python project using uv for dependency management. Let me check if there's a README with content and look for
any test files.
⏺ Searched for 2 patterns, read 1 file (ctrl+o to expand)
⏺ The README is empty. This is a minimal Python project using uv with a simple main.py and openai as a dependency. Let me create an
appropriate CLAUDE.md file.
Writing 1 memory… (ctrl+o to expand)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Create file
CLAUDE.md
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
1 # CLAUDE.md
2
3 This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5 ## Build and Run Commands
6
7 This project uses `uv` for Python dependency management.
8
9 - **Install dependencies**: `uv sync`
10 - **Run the application**: `uv run python main.py`
11 - **Add a dependency**: `uv add <package>`
12
13 ## Project Overview
14
15 A Python 3.12 project with OpenAI SDK as a dependency. Currently contains a minimal main.py entry point.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create CLAUDE.md?
❯ 1. Yes
2. Yes, allow all edits during this session (shift+tab)
3. No
Note that the bottom Claude asks me if I should create CLAUDE.md, and shows me exactly what it will create. I respond with 1. Yes. It then responds with
⏺ I've created a CLAUDE.md file for this project. Since this is a minimal, newly-initialized Python project with just a simple
main.py and uv for dependency management, the file is concise and focused on the essential commands needed to work with the
codebase.
The file includes:
- Build/run commands for uv (sync, run, add dependency)
- Brief project overview noting Python 3.12 and OpenAI dependency
As the project grows, you may want to add:
- Testing commands (once tests are added)
- Architecture notes (once there's meaningful structure)
- Any project-specific conventions you establish
✻ Brewed for 30s
2.3: Now what?¶
I don't know what to do next, so I'm going to ask Claude a question.
I ask ❯ can i describe the function of the python file I want you to create?
and Claude responds ⏺ Yes, go ahead and describe what you'd like the Python file to do.
2.5: I give it requirements¶
Note that in this example I give requirements as a set, but it's much more common to give them incrementally as you grow a prototype.
I enter the prompt:
Write a python file that does the following:
1) gets a OPENAI_API_KEY from my .env file
2) calls openai with the question "why is the sky blue" and prints the answer - once for each ROLE
3) has roles which reflect how openai should resopond, including HELPFUL, SNARKY, SILLY, and HAIKIU
4) when I run the file I get four responses to the same question, one for each role
5) uses gpt-4.1-nano
6) can be called by itself like python file.py and work as intended
2.6: Claude's first response - should I overwrite main.py? See the screenshot below¶
from IPython.display import Image
Image(filename='jdb_example_01/claude_code_3.png')
2.7: Yes to overwrite...¶
Claude shows me the following file, and asks the below, to which I answer 1.
Do you want to overwrite main.py?
❯ 1. Yes
2. Yes, allow all edits during this session (shift+tab)
3. No
Esc to cancel · Tab to amend
2.8: Yes to add module¶
I then get another question, to which I also answer 1. Note this adds a python module with uv
Bash command
uv add python-dotenv
Add python-dotenv dependency
Do you want to proceed?
❯ 1. Yes
2. Yes, and don't ask again for uv add commands in /Users/jeremybloom/Dropbox/projects/claudeExample
3. No
Esc to cancel · Tab to amend · ctrl+e to explain
Finally Claude reports
⏺ Bash(uv add python-dotenv)
⎿ Resolved 19 packages in 142ms
Installed 1 package in 21ms
+ python-dotenv==1.2.1
⏺ Done. I've updated main.py with the requested functionality and added python-dotenv as a dependency.
To run it, make sure you have a .env file in the project directory with your API key:
OPENAI_API_KEY=your-api-key-here
Then run:
uv run python main.py
This will print four responses to "Why is the sky blue?" — one for each role (HELPFUL, SNARKY, SILLY, HAIKU).
and it suggests the input run it
2.9: Ready to run¶
Next Claude suggests the input 'run it' which I type in, and get asked if it can run the bash command uv run python main.py. I accept this as well.
Bash command
uv run python main.py
Run the main.py script
Do you want to proceed?
❯ 1. Yes
2. Yes, and don't ask again for uv run commands in /Users/jeremybloom/Dropbox/projects/claudeExample
3. No
Finally I see
Bash(uv run python main.py)
⎿ ==================================================
ROLE: HELPFUL
==================================================
… +37 lines (ctrl+o to expand)
⏺ It works. You get four different responses to "Why is the sky blue?" — each reflecting its role's personality.
2.10: See full output with ctrl-o¶
I hit Ctr+o to get:
⎿ ==================================================
ROLE: HELPFUL
==================================================
The sky appears blue due to a phenomenon called Rayleigh scattering. When sunlight enters Earth's atmosphere, it is made
up of many colors, each with different wavelengths. Shorter wavelengths, such as blue and violet, are scattered more
effectively by the molecules and tiny particles in the atmosphere than longer wavelengths like red and yellow.
Because blue light is scattered in all directions more than other colors, when you look up at the sky during the day, you
see a predominantly blue color. The scattered blue light reaches your eyes from everywhere overhead, giving the sky its
characteristic hue.
Additionally, our eyes are more sensitive to blue light and our atmosphere scatters more blue light compared to violet,
which is why the sky appears blue rather than violet.
==================================================
ROLE: SNARKY
==================================================
Oh, it’s just the sky being artsy, huh? Actually, the sky is blue because of a process called Rayleigh scattering. The
earth’s atmosphere scatters shorter blue and violet wavelengths of sunlight more than the other colors. Since our eyes are
more sensitive to blue and violet is mostly absorbed, we end up seeing a lovely blue canopy overhead. Fancy physics,
right?
==================================================
ROLE: SILLY
==================================================
Oh, great question! The sky is blue because it’s throwing a giant, celestial paint party and the color blue just happens
to be its favorite! 🌈✨
You see, sunlight is like a box of crayons—it has all the colors! When sunlight visits Earth, it bumps into air molecules
and does a little dance called Rayleigh scattering. Blue, being the bubbly, energetic color it is, gets scattered all over
the place like confetti at a party, making the sky look blue from our point of view.
So next time you look up and admire that gorgeous blue sky, just remember—it’s the universe’s way of saying, “Hey, I’ve
got a cool color palette, wanna see?” Pretty sweet, huh?
==================================================
ROLE: HAIKU
==================================================
Sun’s light spreads out,
Blue waves scatter in the sky,
Colors fill the day.