Skip to content

Commit bb2eaed

Browse files
Merge pull request #1226 from yaron2/aw-1
Add agentic workflow quickstart
2 parents 1005f86 + 9a63671 commit bb2eaed

File tree

12 files changed

+1017
-1
lines changed

12 files changed

+1017
-1
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.nox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
*.py,cover
50+
.hypothesis/
51+
.pytest_cache/
52+
cover/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
## 🧠 Agentic Human-In-The-Loop — Durable Workflows with Dapr (+ OpenAI, Gemini, Anthropic)
2+
3+
This repo demonstrates a durable, agentic AI workflow for contract review built on Dapr Workflows and a simple FastAPI service. It ships three interchangeable implementations using different LLM providers:
4+
5+
* `./anthropic/` — Anthropic Claude–based contract analyst
6+
* `./gemini/` — Google Gemini–based contract analyst
7+
* `./openai/` — OpenAI-based contract analyst
8+
9+
Each example uses the same workflow shape: **analyze → decide → (optionally) wait for human approval → finalize → report**. The only difference is the LLM client and prompts used under the hood.
10+
11+
Start in the provider folder you want (e.g., cd gemini) and follow that README.
12+
13+
### ✨ What the Agentic Workflow Does
14+
15+
* **LLM analysis**: Extract risks and summarize the contract.
16+
* **Decision**: If risk > threshold, propose amendments and pause for human approval.
17+
* **Durability**: The workflow persists state and can survive restarts and timeouts.
18+
* **Output**: Emit a structured JSON report for downstream systems.
19+
20+
21+
All three implementations share these semantics; you can swap providers without changing orchestration logic.
22+
23+
### 🧩 Tech Highlights
24+
25+
* **Dapr Workflows**: Durable execution, timers, retries, external event waiting.
26+
* **FastAPI**: Minimal HTTP surface for starting workflows and posting approvals.
27+
28+
### 🛠 Prerequisites (All Providers)
29+
30+
* Python 3.10+
31+
* [Dapr and Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
32+
* Docker (for local Dapr dependencies)
33+
* Provider API key (one of):
34+
* **OpenAI**: OPENAI\_API\_KEY
35+
* **Gemini**: GEMINI\_API\_KEY
36+
* **Anthropic**: ANTHROPIC\_API\_KEY
37+
38+
Each subfolder has its own requirements.txt and provider-specific notes.
39+
40+
### 🚀 Quickstart
41+
42+
Pick a provider folder and follow its README. The flow is generally:
43+
44+
```bash
45+
# 1) Choose a provider implementation
46+
cd openai # or gemini / anthropic
47+
48+
# 2) Install deps
49+
pip install -r requirements.txt
50+
51+
# 3) Export your provider API key
52+
export OPENAI_API_KEY=... // or GEMINI_API_KEY or ANTHROPIC_API_KEY
53+
54+
# 4) Run the FastAPI app with Dapr
55+
dapr run --app-id contract-review --app-port 8000 -- uvicorn app:app --reload
56+
57+
# 5) Kick off a contract review (example payloads in each README)
58+
curl -X POST http://localhost:8000/review -H "Content-Type: application/json" -d '{ "...": "..." }'
59+
60+
# 6) If required, approve later by posting to /approve/{instanceId}
61+
62+
curl -X POST http://localhost:8000/approve/workflow-<CONTRACT-ID> -H "Content-Type: application/json" -d '{
63+
"approved": true,
64+
"reviewer": "Alice",
65+
"notes": "Reviewed and approved."
66+
}'
67+
```
68+
69+
### 🔄 Choosing a Provider
70+
71+
Start with the provider you already use in production or prefer for pricing/latency.
72+
73+
The workflow contract (endpoints, payloads, and output JSON) is held constant across implementations to make A/B comparisons trivial.
74+
75+
#### 🧪 Example Endpoints (common shape)
76+
77+
* POST /review — Start a new workflow instance with a contract payload
78+
* POST /approve/{instanceId} — Resume a paused workflow with human approval
79+
80+
See each provider's README for exact payloads and sample cURL commands.
81+
82+
#### 🧱 Architecture (High-Level)
83+
84+
```yaml
85+
[Client] ──HTTP──> [FastAPI + Dapr Workflow]
86+
87+
├─ Activity: LLM Analysis (OpenAI/Gemini/Anthropic)
88+
├─ Timer/Wait: Human Approval (external event)
89+
└─ Activity: Finalize Report → JSON
90+
```
91+
92+
* **Durability**: Dapr Workflow state persists in the configured state store.
93+
* **Resilience**: Retries and timers are handled by the workflow runtime.
94+
* **Extensibility**: Add tools (RAG, DB lookups, signature checks) as new activities.
95+
96+
### 🧯 Troubleshooting
97+
98+
* Run dapr status to confirm the sidecar and default components are healthy.
99+
* If workflow doesn't resume, verify you're posting approval to the correct instance ID.
100+
* If the workflow doesn't kick off, make sure you're using a new instance ID in the /review request.
101+
* Check provider-specific rate limits or key scopes.
102+
* Inspect app logs (and Dapr sidecar logs) for activity failures and retries.
103+
104+
### 📚 Related Docs
105+
--------------------------------
106+
107+
* **Dapr Workflows**: [https://docs.dapr.io/developing-applications/building-blocks/workflow/](https://docs.dapr.io/developing-applications/building-blocks/workflow/)
108+
* **OpenAI Python SDK**: [https://platform.openai.com/docs/](https://platform.openai.com/docs/)
109+
* **Google Gemini**: [https://aistudio.google.com/](https://aistudio.google.com/)
110+
* **Anthropic Claude**: [https://docs.anthropic.com/](https://docs.anthropic.com/)
111+
112+
<br>
113+
Built with ❤️ using Dapr Workflows. Swap the model, keep the durability.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# 🧠 Agentic Contract Review Workflow (Dapr + Claude + FastAPI)
2+
3+
This project demonstrates how to build a **durable, agentic AI workflow** using [Dapr Workflows](https://docs.dapr.io/developing-applications/building-blocks/workflow/) and [Anthropic Claude](https://www.anthropic.com/claude). It showcases how to mix the intelligence of a large language model with the resilience and statefulness of a distributed workflow engine.
4+
5+
---
6+
7+
## ✨ What It Does
8+
9+
Claude plays the role of a contract analyst, and Dapr Workflows orchestrates the process across time:
10+
11+
1. Claude reviews each contract and identifies risky clauses.
12+
2. If the contract is risky, Claude drafts amendments.
13+
3. The workflow **waits for human approval** — with timeout and persistence.
14+
4. The results are compiled into a final structured report.
15+
16+
Everything runs in a clean FastAPI service using Dapr's durable execution engine underneath.
17+
18+
Even though this example is using Claude, you can replace the Anthropic SDK with any other LLM provider.
19+
20+
---
21+
22+
## 🛠 Prerequisites
23+
24+
- Python 3.10+
25+
- [Dapr and Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
26+
- Docker (for Redis state backend via `dapr init`)
27+
- Anthropic Claude API Key (sign up at [Anthropic](https://www.anthropic.com/))
28+
29+
Install dependencies:
30+
31+
```bash
32+
pip install -r requirements.txt
33+
```
34+
35+
---
36+
37+
## 🚀 Running the App
38+
39+
### 1. Start the Dapr-enabled FastAPI server
40+
41+
```bash
42+
dapr run --app-id contract-review --app-port 8000 -- uvicorn app:app --reload
43+
```
44+
45+
This launches the FastAPI app with Dapr Workflow runtime. You’ll see:
46+
47+
```
48+
== Dapr Workflow Runtime started ==
49+
```
50+
51+
---
52+
53+
### 2. Submit a contract for review
54+
55+
For subsequent runs, make sure to use a new `id`.
56+
57+
```bash
58+
curl -X POST http://localhost:8000/review \
59+
-H "Content-Type: application/json" \
60+
-d '{
61+
"id": "C100",
62+
"text": "SERVICE AGREEMENT\n\nThis Service Agreement (\"Agreement\") is entered into between ACME Data Solutions, Inc. (\"Provider\") and ClientCo LLC (\"Client\") effective as of August 1, 2025.\n\n1. SERVICES\nProvider agrees to deliver cloud data analytics services to Client as described in Exhibit A.\n\n2. PAYMENT TERMS\nClient shall pay Provider $50,000 per month, due within 15 days of invoice date. Failure to pay within 30 days may result in suspension of services.\n\n3. DATA OWNERSHIP\nAll data processed shall become the property of Provider, including any derivative works, without limitation.\n\n4. LIABILITY LIMITATION\nProvider shall not be liable for any damages, including loss of revenue, indirect, incidental, or consequential damages, even if advised of the possibility thereof.\n\n5. TERMINATION\nEither party may terminate this Agreement at any time with 5 days’ written notice. Client shall remain responsible for payment for all services rendered up to the termination date.\n\n6. CONFIDENTIALITY\nBoth parties agree to maintain confidentiality of proprietary information for a period of 12 months following termination.\n\nIN WITNESS WHEREOF, the parties have executed this Agreement as of the date first written above."
63+
}'
64+
```
65+
66+
This creates a new durable workflow instance: `workflow-C100`.
67+
68+
When starting future contract approval workflows, use a new workflow instance id for every call.
69+
70+
---
71+
72+
### 3. (Optional) Approve the contract if required
73+
74+
If Claude flags the contract as high risk, the workflow pauses and waits for this:
75+
76+
```bash
77+
curl -X POST http://localhost:8000/approve/workflow-C100 -H "Content-Type: application/json" -d '{
78+
"approved": true,
79+
"reviewer": "Alice",
80+
"notes": "Reviewed and approved as-is."
81+
}'
82+
```
83+
84+
If approval is not received in 24 hours, the workflow times out and continues gracefully.
85+
86+
---
87+
88+
## 🧠 Why Use Dapr Workflows?
89+
90+
Traditional LLM apps forget things, fail silently, and can’t wait.
91+
92+
Dapr Workflows gives your agent:
93+
94+
- **Durability** — survives restarts and crashes
95+
- **Event waiting** — pauses for human input or external triggers
96+
- **Retries & orchestration** — handles timeouts, branches, parallel execution
97+
- **Composability** — plug in tools, APIs, databases, and humans
98+
99+
---
100+
101+
## 🧪 Example Output
102+
103+
```json
104+
{
105+
"id": "C100",
106+
"analysis": {
107+
"summary": "The contract includes broad data ownership and limited liability.",
108+
"risk_score": 82,
109+
"risky_clauses": ["3. Data Ownership", "4. Liability Limitation"]
110+
},
111+
"approved": true,
112+
"approver": "Alice",
113+
"notes": "Reviewed and approved as-is."
114+
}
115+
```
116+
117+
---
118+
119+
## 📚 Resources
120+
121+
- [🧭 Dapr Workflow Documentation](https://docs.dapr.io/developing-applications/building-blocks/workflow/workflow-overview/)

0 commit comments

Comments
 (0)