A KYC (Know Your Customer) compliance workflow powered by AI agents with human-in-the-loop review, running on Azure Durable Functions and the Microsoft Agent Framework.
Many real-world agent workflows, compliance reviews, document approvals, fraud investigations, etc. spend most of their time waiting for a human decision. A traditional always-on service would keep compute resources allocated during those idle periods, burning cost for nothing.
This solution uses the Durable Task Scheduler to suspend the workflow while it awaits external input, scaling server-side resources to near zero. When the human responds, the workflow resumes exactly where it left off, with no lost state and no perceptible delay. The result is a pay-for-what-you-use model that fits naturally with tasks that are inherently asynchronous and human-gated.
Equally important, the durable execution layer handles persistence, checkpointing, and replay transparently. The developer focuses entirely on defining the workflow graph and the agent logic , not on building infrastructure for state management, retries, or crash recovery.
- KYC Analyst Agent reads customer data and produces a risk assessment (LLM call)
- A compliance officer reviews and approves or rejects the assessment
- Profile Writer Agent drafts a formal KYC profile document (LLM call)
- The officer reviews the profile; on approval it is saved to disk
Rejections loop back to the agent with feedback for revision (up to a configurable number of attempts).
Workflow state is persisted in the Durable Task Scheduler, so the process survives restarts of both the Function App and the web UI.
- Docker Desktop (runs the dev container, DTS emulator, and Azurite)
- VS Code with the Dev Containers extension
- An Azure OpenAI resource with a deployed chat model (e.g.
gpt-4o) - An Azure account for
az loginauthentication
Open the repo in VS Code and select Reopen in Container when prompted. The dev container spins up three services via Docker Compose:
| Service | Purpose |
|---|---|
app |
Python 3.12 dev environment with Azure Functions Core Tools and uv |
dts-emulator |
Durable Task Scheduler emulator (gRPC on port 8080, dashboard on port 8082) |
azurite |
Azure Storage emulator (ports 10000–10002) |
On first create the container installs uv, Azure Functions Core Tools v4, and runs uv sync to set up the Python virtual environment.
Copy the sample settings file and fill in your Azure OpenAI values:
cp local.settings.json.sample local.settings.jsonEdit local.settings.json and replace the placeholders:
{
"AZURE_OPENAI_ENDPOINT": "https://<your-resource>.openai.azure.com",
"AZURE_OPENAI_DEPLOYMENT_NAME": "<your-deployment-name>"
}The dev container prompts az login on attach. If it doesn't, run it manually:
az loginThis is required for the Azure OpenAI SDK to authenticate via AzureCliCredential.
func startThe app starts on http://localhost:7071. Verify with:
curl http://localhost:7071/api/healthIn a separate terminal:
python webapp.pyOpen http://localhost:5050 in your browser, select a customer, and walk through the two-stage review.
| File | Purpose |
|---|---|
function_app.py |
Azure Functions app: agents, executors, workflow definition |
webapp.py |
Flask web UI for the compliance officer |
test.py |
Pseudo-code illustrating workflow mechanics without Durable Functions |
host.json |
Azure Functions host configuration |
demo.http |
REST Client file for testing the API directly |
data/ |
Sample customer JSON files |
output/ |
Saved KYC profile documents (generated at runtime) |
local.settings.json.sample |
Template for local settings |
For a deep dive into the full request flow, and how this architecture compares to a traditional hosted API, see details.md.
| Method | URL | Description |
|---|---|---|
POST |
/api/workflow/run |
Start a new KYC workflow |
GET |
/api/workflow/status/{instanceId} |
Check workflow status and pending reviews |
POST |
/api/workflow/respond/{instanceId}/{requestId} |
Submit approve/reject decision |
GET |
/api/health |
Health check |
