Complete reference for EDSL survey construction: question types, Jinja2 templating, skip/navigation rules, and memory modes.
EDSL Survey Reference
Consolidated reference for building surveys with EDSL: question types, Jinja2 templating, skip/navigation rules, memory modes, helper utilities, and visualization.
Basic Survey Creation
from edsl import Survey, QuestionFreeText, QuestionMultipleChoice
q1 = QuestionFreeText(
question_name="name",
question_text="What is your name?"
)
q2 = QuestionMultipleChoice(
question_name="color",
question_text="What is your favorite color?",
question_options=["Red", "Blue", "Green", "Yellow"]
)
q3 = QuestionFreeText(
question_name="why_color",
question_text="Why do you like that color?"
)
survey = Survey([q1, q2, q3])
Adding Questions Incrementally
Survey is immutable - each operation returns a new Survey instance:
survey = Survey()
survey = survey.add_question(QuestionFreeText(
question_name="q1",
question_text="First question?"
))
survey = survey.add_question(QuestionFreeText(
question_name="q2",
question_text="Second question?"
))
# Add at specific index
survey = survey.add_question(new_question, index=1)
Adding Instructions
Instructions are displayed to respondents between questions:
from edsl import Survey, Instruction
instruction = Instruction(
text="Please answer the following questions honestly.",
name="intro"
)
survey = survey.add_instruction(instruction)
survey = survey.add_instruction(
Instruction(text="Now for some demographic questions...")
)
IMPORTANT: Instruction text is NOT checked for scenario field references. If your scenarios have fields that must be used, reference them in a question's question_text, not in an Instruction. EDSL's JobsCompatibilityError only looks at question text.
Question Types
All questions require question_name (a valid Python identifier) and question_text.
To see the question types available:
from edsl import Question
Question.available()
QuestionFreeText
Open-ended text responses without constraints.
from edsl import QuestionFreeText
q = QuestionFreeText(
question_name="feedback",
question_text="What do you think about our service?"
)
QuestionMultipleChoice
Single selection from a predefined list of options.
from edsl import QuestionMultipleChoice
q = QuestionMultipleChoice(
question_name="color",
question_text="What is your favorite color?",
question_options=["Red", "Blue", "Green", "Yellow"]
)
QuestionCheckBox
Multiple selections from a predefined list (checkbox-style).
from edsl import QuestionCheckBox
q = QuestionCheckBox(
question_name="features",
question_text="Which features do you use? (Select all that apply)",
question_options=["Feature A", "Feature B", "Feature C", "Feature D"],
min_selections=1,
max_selections=3
)
QuestionNumerical
Numeric responses with optional min/max bounds.
from edsl import QuestionNumerical
q = QuestionNumerical(
question_name="age",
question_text="How old are you?",
min_value=0,
max_value=120
)
QuestionYesNo
Simple binary yes/no question (derived from MultipleChoice).
from edsl import QuestionYesNo
q = QuestionYesNo(
question_name="consent",
question_text="Do you agree to participate in this survey?"
)
# Options are automatically ["Yes", "No"]
QuestionLinearScale
Linear scale with customizable range and endpoint labels.
from edsl import QuestionLinearScale
q = QuestionLinearScale(
question_name="satisfaction",
question_text="How satisfied are you with our service?",
question_options=[1, 2, 3, 4, 5],
option_labels={1: "Very Unsatisfied", 5: "Very Satisfied"}
)
QuestionLikertFive
Standard 5-point Likert scale (agree/disagree).
from edsl import QuestionLikertFive
q = QuestionLikertFive(
question_name="statement_agree",
question_text="I find the product easy to use."
)
# Options: Strongly disagree, Disagree, Neutral, Agree, Strongly agree
QuestionList
Response as a list of items.
from edsl import QuestionList
q = QuestionList(
question_name="top_movies",
question_text="List your top 3 favorite movies.",
max_list_items=3
)
QuestionRank
Ranking/ordering items by preference.
from edsl import QuestionRank
q = QuestionRank(
question_name="priority",
question_text="Rank these features by importance (1 = most important):",
question_options=["Speed", "Security", "Price", "Support"],
num_selections=4
)
QuestionMatrix
Grid-based responses with rows (items) and columns (options).
from edsl import QuestionMatrix
q = QuestionMatrix(
question_name="product_ratings",
question_text="Rate each product on the following attributes:",
question_items=["Product A", "Product B", "Product C"],
question_options=["Poor", "Fair", "Good", "Excellent"],
)
QuestionBudget
Allocating a fixed budget across multiple options.
from edsl import QuestionBudget
q = QuestionBudget(
question_name="time_allocation",
question_text="How would you allocate 100 hours across these activities?",
question_options=["Work", "Exercise", "Leisure", "Sleep"],
budget_sum=100
)
QuestionDict
Response as key-value pairs (structured data).
from edsl import QuestionDict
q = QuestionDict(
question_name="contact_info",
question_text="Provide your contact information:",
answer_keys=["name", "email", "phone"]
)
QuestionExtract
Extracting specific information from text.
from edsl import QuestionExtract
q = QuestionExtract(
question_name="entities",
question_text="Extract all company names from the following text: {{ text }}",
answer_template={"companies": "List of company names"}
)
QuestionDropdown
BM25-powered search through large option sets.
from edsl import QuestionDropdown
q = QuestionDropdown(
question_name="country",
question_text="Select your country:",
question_options=["Afghanistan", "Albania", ..., "Zimbabwe"]
)
QuestionMultipleChoiceWithOther
Multiple choice with an "Other" option for custom responses.
from edsl import QuestionMultipleChoiceWithOther
q = QuestionMultipleChoiceWithOther(
question_name="source",
question_text="How did you hear about us?",
question_options=["Google", "Friend", "Advertisement"],
other_option_label="Other (please specify)"
)
QuestionCheckboxWithOther
Checkbox with an "Other" option for custom responses.
from edsl import QuestionCheckboxWithOther
q = QuestionCheckboxWithOther(
question_name="interests",
question_text="What are your interests?",
question_options=["Sports", "Music", "Reading"],
other_option_label="Other"
)
QuestionTopK
Select top K items from a list.
from edsl import QuestionTopK
q = QuestionTopK(
question_name="favorites",
question_text="Select your top 3 favorite items:",
question_options=["A", "B", "C", "D", "E"],
k=3
)
QuestionFunctional
Python function-based question (not sent to LLM - computed locally).
from edsl import QuestionFunctional
defcompute_sum(scenario, agent):
numbers = scenario.get("numbers", [])
returnsum(numbers)
q = QuestionFunctional(
question_name="total",
question_text="Calculate the sum",
func=compute_sum
)
QuestionPydantic
Use custom Pydantic models as response schemas.
from edsl import QuestionPydantic
from pydantic import BaseModel
classPersonInfo(BaseModel):
name: str
age: int
occupation: str
q = QuestionPydantic(
question_name="person",
question_text="Describe a person:",
pydantic_model=PersonInfo
)
QuestionMarkdown
Responses with markdown formatting.
from edsl import QuestionMarkdown
q = QuestionMarkdown(
question_name="formatted_response",
question_text="Write a formatted response with headers and lists."
)
Common Parameters
All questions support these common parameters:
Parameter
Description
question_name
Unique identifier (valid Python identifier)
question_text
The question text (supports Jinja2 templating)
answering_instructions
Optional custom instructions for the LLM
question_presentation
Optional custom presentation template
Question Type Quick Reference
Type
Use Case
Key Parameter
QuestionFreeText
Open-ended responses
-
QuestionMultipleChoice
Single selection
question_options
QuestionCheckBox
Multiple selections
question_options
QuestionNumerical
Numbers
min_value, max_value
QuestionYesNo
Binary yes/no
-
QuestionLinearScale
Numeric scale
question_options, option_labels
QuestionLikertFive
5-point agree/disagree
-
QuestionList
List of items
max_list_items
QuestionRank
Ordering
question_options, num_selections
QuestionMatrix
Grid/table
question_items, question_options
QuestionBudget
Budget allocation
question_options, budget_sum
QuestionDict
Key-value pairs
answer_keys
QuestionExtract
Extract from text
answer_template
QuestionDropdown
Large option sets
question_options
Jinja2 Templating in Questions
EDSL uses Jinja2 templating to create dynamic questions. Template variables are enclosed in {{ }} and are rendered at runtime.
Scenario Templating
from edsl import QuestionFreeText, Scenario
q = QuestionFreeText(
question_name="opinion",
question_text="What do you think about {{ scenario.fruit }}?"
)
scenarios = [
Scenario({"fruit": "apples"}),
Scenario({"fruit": "oranges"}),
]
results = q.by(scenarios).run()
Agent Templating
from edsl import QuestionFreeText, Agent
q = QuestionFreeText(
question_name="perspective",
question_text="As a {{ agent.occupation }}, what do you think about remote work?"
)
agent = Agent(traits={"occupation": "software engineer", "age": 35})
results = q.by(agent).run()
Piping (Answer References)
Reference previous answers within a survey:
q1 = QuestionFreeText(
question_name="name",
question_text="What is your name?"
)
q2 = QuestionFreeText(
question_name="greeting",
question_text="Hello {{ name.answer }}! How are you today?"
)
survey = Survey([q1, q2])