Beta Program - 3 Months Free Business!

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:

  1. Analyze a user request using a large language model
  2. Generate appropriate form fields based on the analysis
  3. Create a HITL task with those dynamically generated fields
  4. 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.

Dynamic Form Generation with LangGraph
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.

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 orchestration
  • langchain-openai - For LLM integration
  • langgraph-kirokuforms - KirokuForms Python SDK
  • A KirokuForms API key
  • An OpenAI API key

Next Steps & Related Examples

Explore these additional examples and resources: