AI programming sounds like a new discipline. Mostly, it is ordinary software engineering with a few unfamiliar primitives: tokens, prompts, embeddings, and API calls that cost money and return different answers each time. If you can write a function and read a stack trace, you can build something useful. The fastest way to learn is to take one small tool from blank file to working program.
Here is a concrete path. We will build a command-line tool that reads messy meeting notes and outputs action items with owners and due dates. It is small enough to finish in an afternoon, but it touches the core skills behind most AI programming projects.
1. Choose a Problem Small Enough to Finish
Skip the chatbot that does everything. Start with one input and one output.
- Input: a text file of meeting notes, roughly 300 to 1,000 words.
- Output: a JSON list of action items. Each item has a task, an owner, and a due date.
- Success: on 8 of 10 sample notes, the owners and dates are correct.
That scope keeps you focused on the AI parts instead of authentication and UI design. The tooling has shifted quickly, with agents and model APIs doing more heavy lifting, but the core loop remains: send text, get structured data, verify it. The shift in AI programming tools and agents is worth skimming before you commit to a stack.
2. Set Up Python and an API Key Without Extra Frameworks
Use Python 3.10 or newer. Create a virtual environment so your project stays clean.
python -m venv .venv
source .venv/bin/activate
pip install openai python-dotenv
On Windows, activate the environment from the Scripts folder inside .venv. Create .env and add OPENAI_API_KEY=sk-your-key-here. Do not commit that file. Add .env to .gitignore before your first commit.
If you have only used ChatGPT through the browser, the API feels different: you send messages programmatically and pay per token. The guide to what ChatGPT gets wrong and how to use it well covers why prompts that work in the browser sometimes fail in code.
Resist the urge to install a big framework
Libraries like LangChain and LlamaIndex are useful later. At the start they hide the details you need to learn: how messages are structured, how tokens are counted, and where errors come from. Write the first version with the raw SDK.
3. Write the First API Call in About 20 Lines
Create extract_actions.py:
import os, json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def extract_actions(notes: str) -> list:
response = client.chat.completions.create(
model='gpt-4o-mini',
temperature=0,
response_format={'type': 'json_object'},
messages=[
{'role': 'system', 'content': 'Extract action items. Return only JSON with a key named actions. Each item has task, owner, due_date. Use null when unknown.'},
{'role': 'user', 'content': notes}
]
)
raw = response.choices[0].message.content
return json.loads(raw)['actions']
if __name__ == '__main__':
notes = open('meeting.md').read()
for item in extract_actions(notes):
print(item['task'], '|', item['owner'], '|', item['due_date'])
Run it on a real file. The first run usually returns something close but slightly wrong: an owner listed as ‘the team’ when the notes say ‘Priya will send the deck,’ or a due date left as ‘next Friday.’ That is normal. The next step is making the output boring and predictable.
4. Turn Fuzzy Text into a Strict Contract
Models are probabilistic. Software needs contracts. For each field, decide what valid means before you write the prompt.
- task: a short verb phrase, maximum 12 words.
- owner: a person’s name from the notes, or
null. - due_date: ISO format
YYYY-MM-DD, ornull.
Update the system message with those rules and one example. Then validate the response in Python. If parsing fails, log the raw output and retry once with a shorter prompt. A small validation function catches most problems:
def validate(items):
clean = []
for item in items:
if not item.get('task'):
continue
if item.get('due_date') and len(item['due_date']) != 10:
item['due_date'] = None
clean.append(item)
return clean
This is the part most tutorials skip. In production AI programming, the model is only one component. The code around it enforces correctness, retries failures, and keeps bad data out of your database.
5. Add One Retrieval Step Only When You Need It
Suppose you want the tool to remember decisions from past meetings. You can add embeddings without a vector database. For a few thousand notes, load them into memory and compare with cosine similarity.
from openai import OpenAI
import numpy as np
client = OpenAI()
def embed(text: str):
result = client.embeddings.create(model='text-embedding-3-small', input=text)
return result.data[0].embedding
def most_similar(query, notes):
q = np.array(embed(query))
scored = [(np.dot(q, np.array(embed(n))) / (np.linalg.norm(q) * np.linalg.norm(embed(n))), n) for n in notes]
return max(scored, key=lambda x: x[0])[1]
That is enough for a personal tool. You do not need Pinecone, Weaviate, or a dedicated vector store until your data outgrows memory or you need filtering and updates. If you prefer to learn these pieces in a visual environment first, building a small project in AI Studio gives you a structured afternoon exercise with the same concepts.
6. Test the Tool Like Software
Create a folder called fixtures with ten meeting notes. Include edge cases: no owner mentioned, multiple owners, relative dates like ‘end of month,’ and bullet fragments. Then write a small test script.
def test_extract():
notes = open('fixtures/meeting_01.md').read()
items = extract_actions(notes)
assert len(items) == 3
assert items[0]['owner'] == 'Priya'
assert items[0]['due_date'] == '2025-04-18'
Track your pass rate. If you get 8 out of 10 correct, you have a useful tool. If you get 3 out of 10, change one thing at a time: the prompt, the model, or the post-processing. Evaluations tell you whether the tool works on the notes your team actually writes.
7. Ship It as a CLI First, a UI Second
A command-line interface is faster to build and easier to automate. Add argument parsing and CSV output in a few lines:
import argparse, csv
parser = argparse.ArgumentParser()
parser.add_argument('file')
args = parser.parse_args()
items = extract_actions(open(args.file).read())
with open('actions.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['task', 'owner', 'due_date'])
writer.writeheader()
writer.writerows(items)
Now run python extract_actions.py meeting.md and open the CSV in any spreadsheet. If people ask for a web page, wrap the same function in Streamlit later. The logic does not change.
8. Watch Costs, Latency, and Failure Modes
API calls are not free. A small model like gpt-4o-mini costs a fraction of a cent for a 500-word meeting note, but costs add up when you process thousands of documents or use larger models. Understanding what you rent in the AI cloud helps you separate token costs, storage, and compute before your bill surprises you.
Three failure modes show up again and again:
- Hallucinated owners. The model invents a name not in the notes. Validate against a known team list.
- Wrong relative dates. ‘Next Friday’ depends on today. Pass the current date in the prompt and ask for ISO format.
- Prompt injection. A note that says ‘ignore previous instructions’ can hijack the output. Keep system instructions separate and validate the final JSON shape.
Log every request and response while developing. When an output surprises you, the log tells you whether the model failed or your parsing did.
9. Next Projects That Build Real Skill
Once the action-item extractor works, choose a project that adds one new primitive:
- Add function calling so the model can query your task database instead of guessing.
- Summarize support tickets and route them by urgency using a second model call.
- Turn a git changelog into release notes, then compare the output to a human-written version.
- Build a code review bot that reads a diff and flags missing tests or unclear variable names.
- Add a feedback loop where you correct bad outputs and store them as future examples.
Each project teaches one layer: retrieval, tool use, evaluation, or deployment. After three or four small tools, the concepts stop feeling like AI magic and start feeling like normal engineering with a new dependency. That is the moment AI programming becomes just programming.

