Integrating KirokuForms with LangGraph
Leverage KirokuForms for seamless human-in-the-loop (HITL) workflows within your LangGraph applications. This guide covers the best practices for pausing your graphs to wait for human input.
How it Works: The HITL Flow
Integrating human feedback into an AI agent's workflow is critical for tasks requiring verification, correction, or creative input. The KirokuForms-LangGraph integration allows you to seamlessly pause a graph's execution, request input from a human via a web form, and then resume the graph with the collected data.
A typical Human-in-the-Loop workflow within LangGraph.
Installation & Setup
First, install the necessary packages and have your KirokuForms API key ready.
pip install langgraph git+https://github.com/ChelseaAIVentures/langgraph-kirokuforms.git
Get Your API Key
Choosing Your Integration Method
There are two primary methods for integrating KirokuForms HITL into LangGraph. The best choice depends on your application's complexity and your preference for control versus convenience.
Method | Best For | How it Works |
---|---|---|
Interrupt Handler (Recommended) | Most use cases. It's the most integrated and idiomatic LangGraph approach. | You configure the graph to pause automatically before a specific node. A KirokuForms handler creates the HITL task for you. |
Direct Node Integration | Complex workflows where you need fine-grained, conditional control over when a review is requested. | You explicitly call the KirokuForms client from within a graph node to create tasks and fetch results. |
Recommended: Using LangGraph Interrupts
LangGraph's interrupt capability is the cleanest way to handle HITL. You configure your graph to pause before a specific node runs, and our handler automatically creates the KirokuForm task.
What is Checkpointing?
Step 1: Create the Interrupt Handler
The `create_kiroku_interrupt_handler` function from our SDK creates a ready-to-use handler for LangGraph.
from kirokuforms import create_kiroku_interrupt_handler
# This factory creates a handler that will be called by LangGraph.
# It automatically creates a KirokuForms task when the interrupt is triggered.
interrupt_handler = create_kiroku_interrupt_handler(
api_key="YOUR_KIROKU_API_KEY"
)
Step 2: Compile the Graph with the Interrupt
When compiling your graph, tell it to `interrupt_before` a specific node and provide a checkpointer.
from langgraph.graph import StateGraph, END
from langgraph.checkpoint import MemorySaver
# Define a simple graph
workflow_builder = StateGraph(State)
workflow_builder.add_node("agent", agent_node) # Your main agent logic
workflow_builder.set_entry_point("agent")
workflow_builder.add_edge("agent", END)
# Compile the graph with checkpointing and the interrupt
# The graph will pause BEFORE the "agent" node executes.
memory = MemorySaver()
app = workflow_builder.compile(
checkpointer=memory,
interrupt_before=["agent"]
)
Step 3: Invoke and Resume
When you invoke the graph, it will now automatically pause. After the human provides input, you invoke it again with `None` to resume from where it left off.
# This config is essential for checkpointing to work
thread_config = {"configurable": {"thread_id": "user-123-thread-1"}}
# Invoke the graph. It will run up to the interrupt and pause.
# The KirokuForms interrupt_handler is called automatically.
app.invoke({"messages": ["Initial user prompt"]}, thread_config)
# At this point, a HITL task is active in KirokuForms.
# After the human submits the form, you can resume the graph.
# Passing None for the input tells LangGraph to continue from the saved state.
final_result = app.invoke(None, thread_config)
print(final_result)
Alternative: Direct Node Integration
For more control, you can call the `KirokuFormsHITL` client directly inside your graph nodes. This approach requires you to manage the state and the polling/resumption logic more explicitly.
from kirokuforms import KirokuFormsHITL
kiroku_client = KirokuFormsHITL(api_key="YOUR_KIROKU_API_KEY")
# 1. Define the node that creates the HITL task
def request_verification_node(state: State):
data_to_verify = state['data_to_verify']
task = kiroku_client.create_verification_task(
title="Verify Transaction",
data=data_to_verify
)
print(f"Human review requested. Task ID: {task['taskId']}")
print(f"Please complete the form at: {task['reviewUrl']}")
return {"task_id": task['taskId'], "status": "PENDING_REVIEW"}
# 2. Define the node that processes the result
def process_feedback_node(state: State):
task_id = state['task_id']
# In a real app, you would poll or use a webhook.
# Here, we poll for the result.
print("Polling for task result...")
result = kiroku_client.get_task_result(task_id, wait=True, timeout=300)
print("Review complete!")
return {"human_response": result, "status": "REVIEW_COMPLETE"}
In this pattern, you would typically use conditional edges in your graph to route to the `request_verification_node`. After the task is created, the workflow would end. A separate process (e.g., a webhook trigger or a scheduled job) would then re-invoke the graph to run the `process_feedback_node`.
Advanced Configuration
Building Custom Forms
You can define a rich set of form fields to capture precisely the information you need from humans, including text inputs, selections, file uploads, and more.
task_fields = [
{"type": "text", "label": "Company Name", "name": "company", "required": True},
{"type": "number", "label": "Revenue (USD)", "name": "revenue"},
{"type": "textarea", "label": "Additional Notes", "name": "notes"},
{
"type": "select",
"label": "Industry",
"name": "industry",
"options": [
{"label": "Technology", "value": "tech"},
{"label": "Healthcare", "value": "health"},
]
},
{
"type": "radio",
"label": "Verification Status",
"name": "status",
"required": True,
"options": [
{"label": "Verified", "value": "verified"},
{"label": "Rejected", "value": "rejected"}
]
},
{"type": "file", "label": "Upload Supporting Document", "name": "support_doc"}
]
# Pass these fields when creating a task
# kiroku_client.create_task(title="Data Entry", fields=task_fields, ...)
Asynchronous Resumption with Webhooks
Instead of polling for results, you can provide a `webhook_url` when creating a task. KirokuForms will send a POST request to your URL when the task is complete, allowing you to resume the correct LangGraph workflow immediately. See our Webhook Security Guide for more details.
Next Steps
Now that you've seen how to integrate KirokuForms with LangGraph, explore these resources:
- Review practical HITL Examples with LangGraph to see these concepts in action for various use cases.
- Dive deeper into KirokuForms HITL API documentation for detailed information on task creation and management.
- Explore the official LangGraph documentation for more on checkpointing, interrupts, and graph construction.