AutoGen Tutorial (Python): adding audit logs for beginners

By Cyprian AaronsUpdated 2026-04-21
autogenadding-audit-logs-for-beginnerspython

This tutorial shows you how to add audit logging to an AutoGen Python app so every agent message, tool call, and final answer is written to a file. You need this when you want traceability for compliance, debugging, incident review, or just to understand why an agent made a specific decision.

What You'll Need

  • Python 3.10+
  • pyautogen installed
  • An OpenAI API key
  • Basic familiarity with AssistantAgent and UserProxyAgent
  • A writable folder for log files

Install the package:

pip install pyautogen

Set your API key in the environment:

export OPENAI_API_KEY="your-key-here"

Step-by-Step

  1. Start with a small AutoGen setup.
    We’ll create one assistant and one user proxy, then attach a shared audit logger that writes JSON lines to disk.
import json
import time
from pathlib import Path

from autogen import AssistantAgent, UserProxyAgent

LOG_FILE = Path("audit-log.jsonl")

def audit(event_type: str, payload: dict) -> None:
    record = {
        "ts": time.time(),
        "event_type": event_type,
        "payload": payload,
    }
    with LOG_FILE.open("a", encoding="utf-8") as f:
        f.write(json.dumps(record) + "\n")
  1. Add a wrapper around the assistant reply path.
    This logs the incoming prompt and the outgoing response without changing how AutoGen generates the answer.
llm_config = {
    "model": "gpt-4o-mini",
    "api_key": os.environ["OPENAI_API_KEY"],
}

assistant = AssistantAgent(
    name="assistant",
    llm_config=llm_config,
)

user = UserProxyAgent(
    name="user",
    human_input_mode="NEVER",
)

def audited_assistant_reply(message: str) -> str:
    audit("assistant_input", {"agent": assistant.name, "message": message})
    response = assistant.generate_reply(messages=[{"role": "user", "content": message}])
    audit("assistant_output", {"agent": assistant.name, "response": response})
    return response
  1. Log user requests before they hit the agent.
    In real systems, this is where you capture request IDs, user IDs, and any policy-relevant metadata.
import os

def run_chat(prompt: str) -> str:
    audit(
        "user_request",
        {
            "agent": user.name,
            "prompt": prompt,
            "request_id": "req-001",
        },
    )
    result = audited_assistant_reply(prompt)
    audit(
        "final_result",
        {
            "request_id": "req-001",
            "result": result,
        },
    )
    return result
  1. If you use tools, log every tool invocation separately.
    This matters because tool calls are often where sensitive actions happen: database reads, ticket creation, or file access.
def get_account_balance(account_id: str) -> str:
    audit("tool_call", {"tool": "get_account_balance", "account_id": account_id})
    balance = f"Account {account_id} balance is $1,250.00"
    audit("tool_result", {"tool": "get_account_balance", "result": balance})
    return balance

if __name__ == "__main__":
    answer = run_chat("What is the balance for account 12345?")
    print(answer)
  1. Make the logs readable and reviewable.
    JSONL is a good default because each event is one line, easy to ship to SIEMs or parse later with Python.
def read_audit_log() -> list[dict]:
    if not LOG_FILE.exists():
        return []

    events = []
    with LOG_FILE.open("r", encoding="utf-8") as f:
        for line in f:
            events.append(json.loads(line))
    return events

events = read_audit_log()
for event in events[-5:]:
    print(event["event_type"], event["payload"])

Testing It

Run the script and confirm it prints an assistant response. Then open audit-log.jsonl and verify that you see user_request, assistant_input, assistant_output, and final_result entries in order.

If you added tools, trigger a prompt that uses the tool and confirm tool_call and tool_result are recorded too. The important check is that every meaningful action has a timestamped record you can trace later.

For production use, make sure log writes do not fail silently. If the file system is unavailable or permissions change, you want that failure visible immediately.

Next Steps

  • Add request IDs and correlation IDs across multiple agents
  • Send JSONL audit events to OpenTelemetry or your SIEM instead of local files
  • Redact sensitive fields before writing logs to disk

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides