How to Log Prompts and Completions as JSONL Audit Files in Python
Read a JSONL file of LLM prompt–completion pairs, compute totals and averages, then write an audit summary with timestamps.
Python code
51 linesimport json
from pathlib import Path
from datetime import datetime
def audit_jsonl(filepath):
logs = []
with open(filepath, encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
entry = json.loads(line)
logs.append(entry)
total_prompts = len(logs)
completions = [e.get("completions", 0) for e in logs]
total_completions = sum(completions)
avg_completions = total_completions / total_prompts if total_prompts else 0
with open("audit_summary.json", "w", encoding="utf-8") as out:
json.dump(
{
"generated_at": datetime.now().isoformat(),
"total_prompts": total_prompts,
"total_completions": total_completions,
"avg_completions_per_prompt": round(avg_completions, 2),
"entries": logs,
},
out,
indent=2,
)
return {
"total_prompts": total_prompts,
"total_completions": total_completions,
"avg_completions_per_prompt": round(avg_completions, 2),
}
if __name__ == "__main__":
sample = [
{"id": 1, "prompt": "What is Python?", "completions": 3},
{"id": 2, "prompt": "How to sort a list?", "completions": 5},
{"id": 3, "prompt": "Explain decorators", "completions": 2},
]
Path("sample_prompts.jsonl").write_text(
"\n".join(json.dumps(e) for e in sample), encoding="utf-8"
)
result = audit_jsonl("sample_prompts.jsonl")
print(result)
Output
{'total_prompts': 3, 'total_completions': 10, 'avg_completions_per_prompt': 3.33}
How it works
The script reads a JSONL file line by line, skipping blank lines, and parses each entry with the stdlib json module. It collects all entries into a list, then computes total prompts and total completions using a list comprehension and sum(). The average is calculated defensively to avoid division by zero. A new JSON file audit_summary.json is written with the current timestamp and the full entry list, making it easy to audit LLM usage over time. Returning the summary dict lets you reuse the function programmatically.
Common mistakes
- Using `json.load()` on a JSONL file instead of iterating lines with `json.loads()`
- Stripping whitespace incorrectly and treating empty lines as valid entries
- Not guarding against division by zero when the file is empty
- Forgetting to encode output files with `utf-8` for cross-platform portability
Variations
- Use `pathlib.Path.read_text` and `splitlines()` to load all lines at once, then filter blanks
- Extend to write CSV or append each entry to a single log file instead of a summary JSON
Real-world use cases
- Track LLM API usage across a team to monitor prompt counts and token consumption for cost analysis.
- Maintain an audit trail of AI interactions in a support chatbot for regulatory compliance.
- Analyze prompt–completion patterns in production to identify quality issues and common user intents.
Sponsored
More from AI & LLM integration patterns
- Cache LLM Completions by Hashing the Prompt in Python easy
- Chain of Thought Prompting in Python: Step-by-Step Reasoning Demo easy
- Circuit Breaker Pattern in Python for LLM API Calls medium
- Cosine Similarity to Retrieve Top K Chunks in Python easy
- Demonstrate Prompt Injection Bypass in Python easy
- How to Accumulate Streamed Tokens into a Final String in Python easy
Keep learning
Related tutorials and quizzes for this topic.