Approval workflows are the backbone of countless business processes—expense reports, HR leave requests, procurement, legal reviews, and more. As we covered in our Ultimate Playbook for AI-Powered Approval Workflow Automation, the impact of AI and LLMs on automating these workflows is transformative. In this deep-dive, you'll learn how to build a practical, end-to-end approval workflow automation app using LangChain, the leading open-source framework for LLM-powered applications.
This tutorial guides you through every step: from project setup, prompt engineering, and workflow logic, to integrating user input and generating approval decisions. Whether you're looking to automate expense approvals, HR requests, or procurement flows, you'll find actionable code and patterns you can adapt to your use case.
For a manager’s perspective, see Automating Expense Report Approvals with AI or dive into Automating HR Leave Request Approvals with AI: Best Practices & Pitfalls for HR-specific workflows.
Prerequisites
- Python 3.10+ (tested with 3.10 and 3.11)
- pip (Python package manager)
- OpenAI API Key (for LLM access)
- Basic Python knowledge (functions, classes, CLI usage)
- Familiarity with prompt engineering for approval workflows is helpful
Tools & Libraries
langchain(v0.1.14 or above)openai(v1.0.0 or above)python-dotenv(for managing environment variables)typer(for a simple CLI, optional)
1. Project Setup
-
Create a new project directory:
mkdir langchain-approval-workflow && cd langchain-approval-workflow
-
Initialize a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
-
Install required packages:
pip install langchain openai python-dotenv typer
-
Create a
.envfile with your OpenAI API key:OPENAI_API_KEY=sk-...Never commit this file to source control. -
Directory structure should look like:
langchain-approval-workflow/ ├── .env ├── main.py ├── .venv/
2. Define the Approval Workflow Logic
- Decide on your approval scenario. For this tutorial, we'll automate an expense report approval process, but you can adapt this to HR, procurement, or contract reviews.
-
Define the workflow steps:
- User submits an expense request (amount, description, category)
- LLM reviews the request based on company policy
- LLM returns:
APPROVED,REJECTED, orESCALATEwith a reason
-
Create
main.pyand define the input schema:import os from dotenv import load_dotenv load_dotenv() def get_expense_request(): print("Submit a new expense request.") employee = input("Employee Name: ") amount = float(input("Amount (USD): ")) category = input("Category (e.g., Travel, Meals): ") description = input("Description: ") return { "employee": employee, "amount": amount, "category": category, "description": description }
3. Configure LangChain and LLM Integration
-
Set up OpenAI and LangChain:
from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.schema import SystemMessage, HumanMessage llm = ChatOpenAI( openai_api_key=os.getenv("OPENAI_API_KEY"), model="gpt-3.5-turbo", # You can use "gpt-4" if available temperature=0.0 ) -
Design a robust prompt template:
SYSTEM_PROMPT = """ You are an Expense Approval Bot. Company policy: - Approve expenses under $500 unless the description is suspicious. - Escalate expenses between $500 and $2000 to a manager. - Reject expenses over $2000. - Always provide a reason for your decision. Respond in the following JSON format: {{ "decision": "APPROVED" | "REJECTED" | "ESCALATE", "reason": "" }} """ def build_prompt(expense): return [ SystemMessage(content=SYSTEM_PROMPT), HumanMessage(content=f""" Expense request: Employee: {expense['employee']} Amount: ${expense['amount']} Category: {expense['category']} Description: {expense['description']} """) ]
4. Run the Approval Workflow End-to-End
-
Combine everything in
main.py:def main(): expense = get_expense_request() messages = build_prompt(expense) response = llm(messages) print("\nLLM Response:\n", response.content) if __name__ == "__main__": main()Screenshot Description: The terminal displays a prompt for user input (employee name, amount, category, description), then outputs the LLM's JSON decision and reason.
-
Run your workflow in the terminal:
python main.py
Example output:
Submit a new expense request. Employee Name: Alice Amount (USD): 250 Category (e.g., Travel, Meals): Meals Description: Team lunch with clients LLM Response: { "decision": "APPROVED", "reason": "Expense is under $500 and appears business-related." }
5. Parse and Display the LLM's Decision
-
Parse the JSON response for automation:
import json def parse_decision(response_content): try: decision_json = json.loads(response_content) print(f"Decision: {decision_json['decision']}") print(f"Reason: {decision_json['reason']}") return decision_json except json.JSONDecodeError: print("Error: Could not parse LLM response. Raw output:") print(response_content) return None -
Update
main()to use the parser:def main(): expense = get_expense_request() messages = build_prompt(expense) response = llm(messages) print("\nLLM Response:\n", response.content) parse_decision(response.content)
6. (Optional) Add a CLI for Batch Processing
-
Enable batch approval from a CSV file using
typer:import typer import csv app = typer.Typer() @app.command() def approve_csv(csv_file: str): with open(csv_file, newline='') as f: reader = csv.DictReader(f) for row in reader: print(f"\nProcessing: {row}") messages = build_prompt(row) response = llm(messages) print("LLM Response:", response.content) parse_decision(response.content) if __name__ == "__main__": app()Run batch approval:
python main.py approve-csv expenses.csv
Screenshot Description: The terminal processes each expense row from the CSV, displaying LLM decisions for each.
7. Next-Level: Customizing Prompts & Multi-Step Workflows
- Experiment with prompt engineering: Adapt company policy, add context, or chain multiple LLM calls. For advanced patterns, see Prompt Engineering for Approval Workflows and Deep Dive: Generative AI Prompt Engineering for Approval Workflow Automation.
- Build multi-level approvals: For complex organizations, chain LLM outputs to trigger manager or director review. See Automating Multi-Level Approval Workflows: Hands-On Guide for Large Enterprises for practical blueprints.
Common Issues & Troubleshooting
-
LLM returns invalid JSON: LLMs sometimes output malformed JSON. Use
json.loads()in atry/exceptblock. If errors persist, reinforce your prompt with "Respond only in JSON format. Do not include any other text." -
OpenAI API errors: Double-check your
OPENAI_API_KEYin.env. Ensure your OpenAI account has quota and correct model access. -
ModuleNotFoundError: Ensure you have activated your virtual environment and installed all dependencies with
pip install langchain openai python-dotenv typer
- Batch CSV issues: Ensure your CSV columns match the expected schema (employee, amount, category, description).
- Performance/cost: For high-volume workflows, consider caching, using lower-cost models, or deploying open-source LLMs locally.
Next Steps
- Integrate with Slack, email, or web forms for real-world input/output.
- Log approvals to a database or audit trail.
- Explore event-driven triggers for automating workflow starts.
- Customize for HR, procurement, or legal—see Streamlining Contract Review Workflows for legal automation ideas.
- For a full strategic overview and more advanced patterns, revisit the Ultimate Playbook for AI-Powered Approval Workflow Automation.
With this hands-on LangChain approval workflow tutorial, you have a tested foundation for building, customizing, and scaling AI-powered approval automations. Adapt the code, refine your prompts, and plug into your business processes—unlocking efficiency and auditability at scale.