Dynamic Form Generation Example
This example demonstrates how to dynamically generate form fields based on context analysis in LangGraph workflows.
What is Dynamic Form Generation?
One of the most powerful features of KirokuForms is the ability to dynamically generate form fields based on the context of a conversation or the specific data being processed. Instead of using static, predefined forms, this approach creates custom interfaces tailored to each unique situation.
This is particularly powerful when combined with LangGraph workflows where the AI can analyze context and determine exactly what information needs to be collected from humans.
Overview
AI-Powered Form Adaptation
Traditional form systems require developers to predefine every possible field and configuration. KirokuForms' dynamic generation allows AI systems to create contextually appropriate forms on-demand, adapting to user needs in real-time without requiring predefined templates for every scenario.
Dynamic Form Generation Workflow
The workflow below uses LangChain and KirokuForms to:
- Analyze a user request using a large language model
- Generate appropriate form fields based on the analysis
- Create a HITL task with those dynamically generated fields
- Process the submission once the user completes the form
Implementation Example
The following example shows a complete implementation of dynamic form generation integrated with a LangGraph workflow. This demonstrates how AI can analyze context and create appropriate data collection interfaces automatically.
from langgraph.graph import StateGraph
from langchain_openai import ChatOpenAI
from langgraph_kirokuforms import KirokuFormsHITL
import json
# Initialize the LLM and KirokuForms client
llm = ChatOpenAI(model="gpt-4")
kiroku_client = KirokuFormsHITL(api_key="your_api_key")
# Function to analyze user request and generate appropriate form fields
def analyze_and_generate_form(state):
user_request = state["user_request"]
# Use LLM to analyze the request and determine needed information
analysis_prompt = f"""
Analyze this user request: '{user_request}'
What information do we need to collect from the user? Generate a JSON array of form fields
with these properties: type, label, name, required, and placeholder.
Appropriate field types include: text, textarea, number, select, radio, checkbox, date.
For select/radio/checkbox fields, include an 'options' array with label/value pairs.
"""
analysis_result = llm.invoke(analysis_prompt)
try:
# Extract JSON array from the response
fields_text = analysis_result.content
# Find JSON array in the text (may be surrounded by explanation)
json_start = fields_text.find('[')
json_end = fields_text.rfind(']') + 1
if json_start >= 0 and json_end > json_start:
fields_json = fields_text[json_start:json_end]
fields = json.loads(fields_json)
else:
# Fallback fields if parsing fails
fields = [
{"type": "text", "label": "Name", "name": "name", "required": True},
{"type": "textarea", "label": "Details", "name": "details", "required": True}
]
except Exception as e:
print(f"Error parsing fields: {e}")
# Fallback fields
fields = [
{"type": "text", "label": "Name", "name": "name", "required": True},
{"type": "textarea", "label": "Details", "name": "details", "required": True}
]
# Create a HITL task with dynamically generated fields
task = kiroku_client.create_task(
title=f"Response to: {user_request[:50]}...",
description=f"Please provide the following information to help with your request: '{user_request}'",
fields=fields
)
# Return updated state with task information
return {
**state,
"form_url": task["formUrl"],
"task_id": task["taskId"],
"fields": fields
}
# Function to process form submission
def process_form_submission(state):
task_id = state["task_id"]
# Wait for form submission
form_data = kiroku_client.get_task_result(task_id)
# Use data to generate a response
return {
**state,
"form_data": form_data,
"response": f"Thank you for providing the information. We'll process your request based on your inputs."
}
# Build the workflow
workflow = StateGraph()
workflow.add_node("analyze_and_generate", analyze_and_generate_form)
workflow.add_node("process_submission", process_form_submission)
# Add edges
workflow.add_edge("analyze_and_generate", "process_submission")
# Example user request
example_request = "I need to schedule a service appointment for my car"
# Run the workflow
result = workflow.invoke({"user_request": example_request})
print(f"Form URL: {result['form_url']}")
print(f"Fields dynamically generated: {len(result['fields'])}")
print(f"Response: {result['response']}")
Key Concepts
Contextual Form Generation
Instead of using predefined forms, this approach adapts the form interface to each unique situation. The LLM determines what information needs to be collected based on the context, making the system incredibly flexible and user-friendly.
Error Handling Best Practices
The example includes robust error handling for cases where the LLM output cannot be parsed as valid form field definitions. Always implement fallback forms to ensure your workflow continues even when AI generation fails.
Consider implementing validation of generated field configurations before creating HITL tasks to catch potential issues early.
Dynamic Field Types
The LLM can generate a variety of field types (text, textarea, select, radio, checkbox, date, etc.) based on what's most appropriate for each piece of information being collected. This ensures the best user experience for data entry.
Prerequisites
Required Dependencies
To run this example, you'll need:
langgraph
- For workflow orchestrationlangchain-openai
- For LLM integrationlanggraph-kirokuforms
- KirokuForms Python SDK- A KirokuForms API key
- An OpenAI API key
Next Steps & Related Examples
Explore these additional examples and resources:
- Main Examples Page - Overview of all LangGraph integration examples
- HITL API Reference - Complete API documentation
- LangGraph Integration Guide - Comprehensive integration documentation
- Developer Dashboard - Get your API keys and manage integrations