Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Autonomous Document Agent

A FastAPI service that takes a natural-language request, autonomously plans what document it needs to produce, drafts it section by section with an LLM, self-checks its own draft, and returns a polished .docx.

Setup

pip install -r requirements.txt

# Free tier LLM: https://console.groq.com -> create an API key
export GROQ_API_KEY="your_key_here"

uvicorn main:app --reload --port 8000

If GROQ_API_KEY is not set, the app runs in mock mode automatically (LLMClient.mock_mode) — every endpoint still works end-to-end with deterministic canned content, so the pipeline and doc generation can be demoed/tested without any credits or network access.

API

POST /agent

{"request": "Create meeting minutes for our weekly engineering standup covering sprint progress, blockers, and action items"}

Returns the agent's plan, the generated section content, its self-check notes, and a download_url for the .docx.

GET /agent/download/{filename} — fetch the generated document.

GET /health — liveness + whether it's running in mock mode.

Architecture / Agent Workflow

Three explicit LLM stages, each independently retryable and inspectable — deliberately not one giant "do everything" prompt:

  1. Plan (agent.py: DocumentAgent.plan) — the LLM reads the request and decides what kind of document fits (proposal, meeting minutes, project plan, SOP, etc.) and returns a JSON task list of sections. If the request is ambiguous or has conflicting asks, the planner is instructed to make a reasonable assumption rather than stall, and to add an explicit "Assumptions & Risks" section — this is what makes the agent handle the underspecified test case autonomously instead of asking the user for clarification.
  2. Execute (DocumentAgent.execute) — one LLM call per planned section, writing concrete content (with plausible mock data where real data wasn't given).
  3. Reflect / self-check (DocumentAgent.reflect_and_revise) — this is the mandatory engineering improvement. The agent re-reads its own full draft against the original request, using a separate "editor" prompt, and returns {"needs_revision": bool, "notes": "..."}. If revision is flagged, it runs one targeted rewrite pass on the weak section. This is the same reason a human writer reads back their own draft before sending it — it catches thin or off-topic sections that a single-pass generation tends to produce, at the cost of one extra LLM call.

main.py (FastAPI) orchestrates: validate → plan → execute → reflect → render .docx (doc_generator.py, via python-docx) → return JSON + download link.

Why reflection over the other options: conversation memory and RAG don't fit a stateless one-shot document generator; tool calling and multi-step planning are already implicit in the plan/execute split; retry logic is included anyway as basic resilience (see llm_client.py) but doesn't improve output quality, only availability. Reflection is the one lever that visibly improves the actual document for the harder, ambiguous test case.

Resilience (secondary, not the graded improvement)

llm_client.py retries transient failures (timeouts / 429 / 5xx) with exponential backoff, and every stage in agent.py has a fallback so one bad LLM response (unparsable JSON, a dropped section) degrades gracefully instead of crashing the whole request.

Test Inputs

Standard:

{"request": "Create meeting minutes for our weekly engineering standup covering sprint progress, blockers, and action items"}

Complex / ambiguous / conflicting:

{"request": "We need a proposal for a client but I am not fully sure of the budget or timeline yet, they mentioned wanting AI features and also wanting it cheap and delivered fast, figure out something reasonable"}

This one has missing info (budget/timeline) and a direct conflict ("cheap" vs "fast" vs "AI features"). The planner is expected to still produce a full plan, make an assumption about scope, and surface the tension explicitly in an "Assumptions & Risks" section rather than fail or ask a follow-up question.

About

Accepts a natural-language request, plans its own task list, executes each step via an LLM, self-checks the draft, and returns a polished Word document.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages