AI Agents for Data Analysis: A Copy-and-Run Starter
Want AI agents for data analysis that write and run their own code against your data? This interactive guide gives you a working agent loop you can paste and adapt today.
import io, contextlib
from anthropic import Anthropic
client = Anthropic()
def run_code(code: str, df):
buf = io.StringIO()
scope = {"df": df, "result": None}
try:
with contextlib.redirect_stdout(buf):
exec(code, scope)
return {"ok": True, "stdout": buf.getvalue(), "result": scope.get("result")}
except Exception as e:
return {"ok": False, "error": repr(e)}
def analyze(question, df, max_steps=5):
schema = f"Columns: {list(df.columns)}\nRows: {len(df)}"
messages = [{"role": "user", "content":
f"{question}\n\n{schema}\nWrite pandas code assigning the answer to "
"`result`. I will run it and return output. Revise if it errors."}]
for _ in range(max_steps):
r = client.messages.create(model="claude-sonnet-4-6",
max_tokens=700, messages=messages)
text = r.content[0].text
code = extract_code(text) # pull the fenced python block
if not code:
return text # final natural-language answer
outcome = run_code(code, df)
messages += [{"role": "assistant", "content": text},
{"role": "user", "content": f"Execution: {outcome}"}]
return "Hit step limit without a final answer."Can an AI agent actually analyze your data, or does it just describe what analysis might look like? That's the question most people quietly have, and the answer depends entirely on one design choice: whether the agent can run code or only talk about it.
AI agents for data analysis that can execute code against your dataset are a different species from a chatbot that guesses at trends. This guide hands you a working loop, explains the knobs, and shows you the guardrail that stops the agent from confidently inventing numbers.
Quick-Start (Copy This Right Now)
Here's a data-analysis agent that writes pandas code, runs it in a sandbox, sees the result, and iterates until it answers your question:
[object Object], io, contextlib
,[object Object], anthropic ,[object Object], Anthropic
client = Anthropic()
,[object Object], ,[object Object],(,[object Object],):
buf = io.StringIO()
scope = {,[object Object],: df, ,[object Object],: ,[object Object],}
,[object Object],:
,[object Object], contextlib.redirect_stdout(buf):
,[object Object],(code, scope)
,[object Object], {,[object Object],: ,[object Object],, ,[object Object],: buf.getvalue(), ,[object Object],: scope.get(,[object Object],)}
,[object Object], Exception ,[object Object], e:
,[object Object], {,[object Object],: ,[object Object],, ,[object Object],: ,[object Object],(e)}
,[object Object], ,[object Object],(,[object Object],):
schema = ,[object Object],
messages = [{,[object Object],: ,[object Object],, ,[object Object],:
,[object Object],
,[object Object],}]
,[object Object], _ ,[object Object], ,[object Object],(max_steps):
r = client.messages.create(model=,[object Object],,
max_tokens=,[object Object],, messages=messages)
text = r.content[,[object Object],].text
code = extract_code(text) ,[object Object],
,[object Object], ,[object Object], code:
,[object Object], text ,[object Object],
outcome = run_code(code, df)
messages += [{,[object Object],: ,[object Object],, ,[object Object],: text},
{,[object Object],: ,[object Object],, ,[object Object],: ,[object Object],}]
,[object Object], ,[object Object],What this does: it lets the model write pandas code, actually executes that code against your dataframe, feeds the real output back, and loops until the model stops writing code and gives a grounded answer.
Paste it, wire
extract_codeWhy Execution Beats Description
Here's the insight that separates working AI agents for data analysis from impressive-looking demos: a model that only describes an analysis is guessing, and a model that runs the analysis is knowing. Ask a plain chatbot "what's the correlation between price and churn in my data" and it will produce a confident, plausible, and completely made-up number - because it never saw your data. It's pattern-matching on what such answers usually look like.
Wire the same model into an execution loop and everything changes. Now it writes
df[['price','churn']].corr()This is also why the code-first discipline matters so much. If you let the model narrate conclusions before it runs anything, you've thrown away the grounding and kept only the confidence. The whole architecture exists to make sure every stated fact has an executed computation behind it - and that a human can trace back to that computation in one scroll.
⚡ Pro tip: have the agent print intermediate results, not just the final answer. Seeing
df.shapeUnderstanding the Variables
Three knobs decide how this behaves.
max_stepsThe schema string is what grounds the agent. Passing column names and row count up front stops it from guessing at columns that don't exist. For messy data, add dtypes and a sample row - the single highest-impact change you can make to accuracy.
The execution feedback is the piece that makes this trustworthy. Because the agent sees real errors and real output - not its own imagination - it corrects itself instead of confidently pressing on. This is why an agent that runs code beats a one-shot "analyze this" prompt every time: the loop turns a guess into a verified result.
⚡ Pro tip: include
df.head(3).to_dict()status"ACTIVE""active"1Step-by-Step: How AI Agents for Data Analysis Answer a Real Question
Say you ask, "Which three regions had the biggest month-over-month revenue drop?"
First, the agent writes a groupby that pivots revenue by region and month. It runs, and maybe it errors because your date column is a string. The agent sees the traceback and rewrites with
pd.to_datetimeresultYou didn't debug anything. The loop did, because it could see what broke. That self-correction on a real traceback is the entire reason to build an agent instead of pasting your data into a chat window and hoping.
answer = analyze(,[object Object],, sales_df)
,[object Object],(answer)What this does: runs the full agent loop on your sales dataframe and prints a grounded natural-language answer backed by code that actually executed.
Now walk through what the human reviewer sees. Because every step logged its code and output, you can read the agent's reasoning as a sequence of verifiable operations - not a black box. If the final number looks surprising, you scroll up, find the exact
groupby⚠️ Common mistake: trusting numbers the agent states in prose without checking that they came from executed code. If your loop lets the model answer in words before running code, it will happily hallucinate a plausible-looking figure. Force the pattern "code first, prose only after real output" - and reject any final numeric claim that doesn't trace back to a printed result.
Pro-Level Variations
For bigger datasets, don't hand the agent the whole frame. Give it the schema and let it write SQL against a database connection, returning only aggregates. The agent reasons over structure; the database does the heavy lifting, and you never load a hundred million rows into memory to answer a question about monthly totals.
For recurring reports, freeze the agent's validated code once it works and schedule that code directly. You don't need the model in the loop every morning to run an analysis it already got right - use the agent to author the pipeline, then run the pipeline. This is the trick that turns an expensive per-run agent into a one-time authoring cost.
For multi-part questions, add a planning step where the agent lists sub-questions before writing any code. Decomposition dramatically cuts the flailing you see on vague asks - the agent commits to a plan, then executes it piece by piece instead of thrashing.
Three real uses make this concrete. A growth analyst at a subscription company points the agent at a cohort table and asks for retention curves by signup month - the agent writes the pivot, plots it, and flags the month where retention cratered, all without the analyst remembering pandas syntax. A finance team hands it a messy expense export and asks which vendors' spend grew fastest quarter over quarter; the agent cleans the dates, groups, and ranks in three self-corrected passes. A product manager drops in an event log and asks which feature correlates with upgrade - the agent runs the crosstab and reports the real lift, not a guess. Same loop, three departments, zero SQL expertise required from the human.
⚡ Pro tip: when the agent's plan looks wrong, correct the plan, not the code. Fixing reasoning at the planning step propagates to every downstream query; fixing one code block just patches a symptom.
⚡ Pro tip: log every code block the agent runs alongside its output. When a stakeholder asks "how did you get this number," you have the exact executable answer - which is more auditable than most human analysis, where the steps live only in someone's head.
⚡ Pro tip: set a hard row cap on any result the agent tries to return to itself. A
groupbyTroubleshooting Common Issues
If the agent loops without converging, your question is probably ambiguous - "analyze sales" has no finish line. Rewrite it as a question with a checkable answer, like "what was total revenue by region in Q2." A good agent question has exactly one correct answer you could verify by hand.
If it keeps writing code that references missing columns, your schema string is too thin. Add dtypes and a sample. Nine times out of ten, a "dumb" agent is a starved agent - it's guessing because you didn't show it the shape of the data.
If results feel off but the code looks right, check your data, not the agent. AI agents for data analysis surface dirty data ruthlessly - a "wrong" answer is often the agent faithfully computing on a column full of nulls you didn't know about. That's not a bug; that's the agent doing you a favor.
⚡ Pro tip: keep a small "golden" dataset with answers you already know by hand. Run the agent against it after any prompt change. If it misses a known answer, you caught a regression before it touched real work.
Your Turn
Start with the quick-start loop and one real question you already know the answer to. Watch how the agent handles an error - that self-correction is the whole reason to build an agent instead of asking a one-shot question. Then hand it a question you don't know the answer to, and verify the code before you trust the number.
As you refine the system prompt and schema conventions, save the versions that work. Teams doing serious analysis keep their agent prompts and schema templates in PromptABCD so a reliable "code-first, verify-output" analysis pattern is one paste away for everyone, instead of living in one notebook only its author remembers.
Continue Reading
Save the prompts from this post
PromptABCD is a free prompt manager. Paste, organize, and reuse your best AI prompts — no more hunting through chat history.
