We are going to build a Meeting Notes Summarizer that turns messy, unstructured notes into a clean markdown report. It is a single Python script that calls an LLM through Oxlo.ai, and it is useful for anyone who leaves a meeting with a wall of text and no time to rewrite it.
What you'll need
- Python 3.10 or newer installed on your machine.
- The OpenAI SDK. Install it with
pip install openai. - An Oxlo.ai API key from https://portal.oxlo.ai.
Step 1: Install the SDK and connect to Oxlo.ai
Create a new directory and a file named meeting_bot.py. Start by importing the client and pointing it at Oxlo.ai. If you do not have an API key yet, grab one from the portal.
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY" # Replace with your key from https://portal.oxlo.ai
)
print("Client initialized. Ready to call llama-3.3-70b.")
Step 2: Write the system prompt
The system prompt is the contract that tells the model how to behave. I keep it strict about output format so the results stay consistent across runs. Add this constant to your file.
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY"
)
SYSTEM_PROMPT = """You are a meeting assistant. Read the raw meeting notes below and produce a structured summary.
Use this exact format:
1. Summary: 2-3 sentence overview.
2. Key Decisions: Bullet list of decisions made.
3. Action Items: Bullet list of tasks, owners, and due dates.
4. Open Questions: Unresolved items.
If a category has no data, write "None identified". Keep the tone neutral and concise."""
Step 3: Build the summarizer function
Now wire the client and prompt together. This function accepts a raw string of notes and returns the formatted summary. I use llama-3.3-70b here because it handles instruction following reliably for this kind of text transformation.
import sys
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY"
)
SYSTEM_PROMPT = """You are a meeting assistant. Read the raw meeting notes below and produce a structured summary.
Use this exact format:
1. Summary: 2-3 sentence overview.
2. Key Decisions: Bullet list of decisions made.
3. Action Items: Bullet list of tasks, owners, and due dates.
4. Open Questions: Unresolved items.
If a category has no data, write "None identified". Keep the tone neutral and concise."""
def summarize_notes(notes: str) -> str:
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": notes},
],
)
return response.choices[0].message.content
if __name__ == "__main__":
sample = (
"Sprint retro - June 10. "
"Alice: deployment pipeline is still flaky. "
"Bob will migrate us to GitHub Actions by Friday. "
"We agreed to drop support for Python 3.8. "
"Carol asked whether we need a staging environment, no decision made."
)
print(summarize_notes(sample))
Step 4: Add a CLI wrapper
Replace the hardcoded sample with a small CLI that reads multiline input from stdin. This lets you paste notes directly from your email or notes app.
import sys
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY"
)
SYSTEM_PROMPT = """You are a meeting assistant. Read the raw meeting notes below and produce a structured summary.
Use this exact format:
1. Summary: 2-3 sentence overview.
2. Key Decisions: Bullet list of decisions made.
3. Action Items: Bullet list of tasks, owners, and due dates.
4. Open Questions: Unresolved items.
If a category has no data, write "None identified". Keep the tone neutral and concise."""
def summarize_notes(notes: str) -> str:
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": notes},
],
)
return response.choices[0].message.content
if __name__ == "__main__":
print("Paste meeting notes. Press Ctrl+D (Unix) or Ctrl+Z then Enter (Windows) when done:")
notes = sys.stdin.read()
if not notes.strip():
print("No input received.")
sys.exit(1)
print("\n--- Structured Output ---\n")
print(summarize_notes(notes))
Run it
Save the file and run it from your terminal. Paste a block of messy notes and send the EOF signal.
$ python meeting_bot.py
Paste meeting notes. Press Ctrl+D (Unix) or Ctrl+Z then Enter (Windows) when done:
Weekly growth sync - attendees: Dana, Eli, Frank
Dana said paid acquisition ROAS dropped 15% last week. Eli thinks it is creative fatigue, will refresh ad sets by Wednesday. Frank to pull cohort LTV numbers for the board deck due Monday. We still have not picked a new attribution vendor. Discussed raising test budget, decided to wait until next quarter.
--- Structured Output ---
1. Summary: The growth team reviewed a drop in paid acquisition performance, assigned creative refreshes and data pulls, and deferred a budget increase until next quarter.
2. Key Decisions:
- Defer raising test budget until next quarter.
3. Action Items:
- Eli: Refresh ad creative sets by Wednesday.
- Frank: Pull cohort LTV numbers for board deck due Monday.
4. Open Questions:
- New attribution vendor selection (not decided).
Next steps
Because Oxlo.ai charges a flat rate per request rather than by token count, you can paste a ten-thousand-word transcript into this script without the cost scaling with length. That makes it practical to upgrade this tool to ingest entire call recordings. If you need more room, swap llama-3.3-70b for kimi-k2.6, which gives you a 131K context window on the same request-based pricing. Another practical upgrade is enabling JSON mode so the action items feed directly into your task tracker via API.
Top comments (0)