Assignment: Human-in-the-Loop & Persistence#
Assignment Metadata#
Field |
Description |
|---|---|
Assignment Name |
Human-in-the-Loop & Persistence |
Course |
LangGraph and Agentic AI |
Project Name |
|
Estimated Time |
150 minutes |
Framework |
Python 3.10+, LangGraph, LangChain, SQLite/PostgreSQL, FAISS |
Learning Objectives#
By completing this assignment, you will be able to:
Implement interrupt patterns for human approval workflows
Configure different checkpointer backends (MemorySaver, SQLiteSaver, PostgresSaver)
Design confirmation UIs for critical operations
Build cache tools using vector stores for response caching
Apply state update patterns for manual corrections
Problem Description#
Extend the FPT Customer Chatbot from Assignment 04 with:
Human-in-the-Loop Confirmation: Require user approval before ticket/booking operations
Response Caching: Store RAG/IT support responses in FAISS for follow-up queries
Persistent State: Enable long-running conversations with SQLite checkpointer
Technical Requirements#
Environment Setup#
Python 3.10 or higher
Required packages:
langgraph>= 0.2.0langchain>= 0.1.0faiss-cpu>= 1.7.0sentence-transformers>= 2.2.0
Prerequisite#
Completed Assignment 04 (FPT Multi-Agent Chatbot)
Tasks#
Task 1: Interrupt Before Tool Execution (35 points)#
Configure interrupt_before for sensitive tools:
All ticket creation/update/cancel operations
All booking creation/update/cancel operations
Implement confirmation flow:
Detect pending tool state via
graph.get_state()Generate human-readable confirmation message
Parse user response (โyโ to continue, other to cancel)
Handle user responses:
โyโ: Resume graph execution with
app.invoke(None, config)Other: Update state to cancel and return appropriate message
Create confirmation message generator that:
Extracts tool name and arguments from pending state
Formats readable summary for user review
Includes clear instructions for approval/rejection
Task 2: Cache Tool Implementation (35 points)#
Create cache_tool that:
Stores all RAG and IT Support responses in FAISS vectorstore
Indexes by query embedding for similarity search
Stores metadata: timestamp, query_type, source_agent
Implement cache lookup in orchestrator:
Before calling RAG/IT tools, check cache for similar queries
Use similarity threshold (e.g., 0.85) to determine cache hit
Return cached response if found, otherwise proceed to tool
Add cache management:
TTL-based invalidation (e.g., 24 hours)
Manual cache clear capability
Cache statistics logging
Task 3: Checkpointer Configuration (20 points)#
Replace MemorySaver with SQLiteSaver:
Configure persistent storage in
checkpoints.dbTest conversation resumption after process restart
Implement thread management:
List active threads
View checkpoint history for a thread
Delete old threads (cleanup)
Document migration path to PostgresSaver for production
Task 4: Testing & Validation (10 points)#
Test interrupt workflow:
Create ticket โ Confirm โyโ โ Verify ticket created
Create booking โ Reject with โnโ โ Verify booking NOT created
Test cache functionality:
Query IT support โ Verify cached
Similar follow-up query โ Verify cache hit
After TTL โ Verify cache miss
Test persistence:
Start conversation โ Stop process โ Resume โ Verify context retained
Submission Requirements#
Required Deliverables#
Source code extending Assignment 04
README.mdwith setup instructionsDemo video or screenshots showing:
Interrupt confirmation workflow
Cache hit/miss scenarios
Conversation persistence across restarts
Submission Checklist#
interrupt_before configured for all sensitive tools
Confirmation message clearly shows pending action
Cache tool stores and retrieves responses correctly
SQLiteSaver enables conversation persistence
Code runs without errors
Evaluation Criteria#
Criteria |
Points |
|---|---|
Interrupt workflow implementation |
35 |
Cache tool with FAISS |
35 |
Checkpointer configuration |
20 |
Testing & validation |
5 |
Code quality and documentation |
5 |
Total |
100 |
Hints#
Use
app.get_state(config)to inspect current state including pending tool callsThe
nextfield in state shows which node(s) are pendingFor FAISS caching, use
sentence-transformersfor consistent embeddingsSQLiteSaver requires context manager:
with SqliteSaver.from_conn_string(...) as saver: