In the first example below we construct a survey of questions and then add a rule to skip one question based on the response to another question. In the second example we add some complexity. We first create different “scenarios” (versions) of questions and combine them in a survey. Then we add multiple rules to skip specific versions of the questions based on responses to a particular version of a question. EDSL is an open-source library for simulating surveys, experiments and other research with AI agents and large language models. Before running the code below, please ensure that you have installed the EDSL library and either activated remote inference from your Expected Parrot account or stored API keys for the language models that you want to use with EDSL. Please also see our documentation page for tips and tutorials on getting started using EDSL.Documentation Index
Fetch the complete documentation index at: https://docs.expectedparrot.com/llms.txt
Use this file to discover all available pages before exploring further.
Example 1
In the first example below we construct questions, combine them in a survey, and add a rule to skip the second question based on the response to the first question. Then we createScenario objects for contents that will be added to the questions when the survey is run. The effect of this is that the second question will be skipped based on the response to the first question for each individual scenario.
We start by constructing questions:
| question_options | question_name | question_type | question_text | |
|---|---|---|---|---|
| 0 | [‘No’, ‘Yes’] | recent_purchase | yes_no | In the last year have you or anyone in your household purchased any {{ scenario.item }}? |
| 1 | nan | amount | numerical | In the last year, how much did your household spend on {{ scenario.item }} (in USD)? |
| 2 | [‘Never’, ‘Within the next month’, ‘Within the next year’, ‘I do not know’] | next_purchase | multiple_choice | When do you next expect to purchase {{ scenario.item }}? |
Note:Note that we could also use a method for the data type that we are using–this is equivalent:
| item | |
|---|---|
| 0 | electronics |
| 1 | phones |

| annual_income | age | |
|---|---|---|
| 0 | under $100,000 | 30 |
| 1 | under $100,000 | 50 |
| 2 | under $100,000 | 70 |
| 3 | $100,000-250,000 | 30 |
| 4 | $100,000-250,000 | 50 |
| 5 | $100,000-250,000 | 70 |
| 6 | above $250,000 | 30 |
| 7 | above $250,000 | 50 |
| 8 | above $250,000 | 70 |
| key | value | |
|---|---|---|
| 0 | model | gemini-1.5-flash |
| 1 | parameters:temperature | 0.500000 |
| 2 | parameters:topP | 1 |
| 3 | parameters:topK | 1 |
| 4 | parameters:maxOutputTokens | 2048 |
| 5 | parameters:stopSequences | [] |
| 6 | inference_service |
run:
| 0 | |
|---|---|
| 0 | agent.age |
| 1 | agent.agent_index |
| 2 | agent.agent_instruction |
| 3 | agent.agent_name |
| 4 | agent.annual_income |
| 5 | answer.amount |
| 6 | answer.next_purchase |
| 7 | answer.recent_purchase |
| 8 | cache_keys.amount_cache_key |
| 9 | cache_keys.next_purchase_cache_key |
| 10 | cache_keys.recent_purchase_cache_key |
| 11 | cache_used.amount_cache_used |
| 12 | cache_used.next_purchase_cache_used |
| 13 | cache_used.recent_purchase_cache_used |
| 14 | comment.amount_comment |
| 15 | comment.next_purchase_comment |
| 16 | comment.recent_purchase_comment |
| 17 | generated_tokens.amount_generated_tokens |
| 18 | generated_tokens.next_purchase_generated_tokens |
| 19 | generated_tokens.recent_purchase_generated_tokens |
| 20 | iteration.iteration |
| 21 | model.inference_service |
| 22 | model.maxOutputTokens |
| 23 | model.model |
| 24 | model.model_index |
| 25 | model.stopSequences |
| 26 | model.temperature |
| 27 | model.topK |
| 28 | model.topP |
| 29 | prompt.amount_system_prompt |
| 30 | prompt.amount_user_prompt |
| 31 | prompt.next_purchase_system_prompt |
| 32 | prompt.next_purchase_user_prompt |
| 33 | prompt.recent_purchase_system_prompt |
| 34 | prompt.recent_purchase_user_prompt |
| 35 | question_options.amount_question_options |
| 36 | question_options.next_purchase_question_options |
| 37 | question_options.recent_purchase_question_options |
| 38 | question_text.amount_question_text |
| 39 | question_text.next_purchase_question_text |
| 40 | question_text.recent_purchase_question_text |
| 41 | question_type.amount_question_type |
| 42 | question_type.next_purchase_question_type |
| 43 | question_type.recent_purchase_question_type |
| 44 | raw_model_response.amount_cost |
| 45 | raw_model_response.amount_input_price_per_million_tokens |
| 46 | raw_model_response.amount_input_tokens |
| 47 | raw_model_response.amount_one_usd_buys |
| 48 | raw_model_response.amount_output_price_per_million_tokens |
| 49 | raw_model_response.amount_output_tokens |
| 50 | raw_model_response.amount_raw_model_response |
| 51 | raw_model_response.next_purchase_cost |
| 52 | raw_model_response.next_purchase_input_price_per_million_tokens |
| 53 | raw_model_response.next_purchase_input_tokens |
| 54 | raw_model_response.next_purchase_one_usd_buys |
| 55 | raw_model_response.next_purchase_output_price_per_million_tokens |
| 56 | raw_model_response.next_purchase_output_tokens |
| 57 | raw_model_response.next_purchase_raw_model_response |
| 58 | raw_model_response.recent_purchase_cost |
| 59 | raw_model_response.recent_purchase_input_price_per_million_tokens |
| 60 | raw_model_response.recent_purchase_input_tokens |
| 61 | raw_model_response.recent_purchase_one_usd_buys |
| 62 | raw_model_response.recent_purchase_output_price_per_million_tokens |
| 63 | raw_model_response.recent_purchase_output_tokens |
| 64 | raw_model_response.recent_purchase_raw_model_response |
| 65 | reasoning_summary.amount_reasoning_summary |
| 66 | reasoning_summary.next_purchase_reasoning_summary |
| 67 | reasoning_summary.recent_purchase_reasoning_summary |
| 68 | scenario.item |
| 69 | scenario.scenario_index |
| model.model | agent.annual_income | agent.age | scenario.item | answer.recent_purchase | answer.amount | answer.next_purchase | |
|---|---|---|---|---|---|---|---|
| 0 | gemini-1.5-flash | $100,000-250,000 | 30 | electronics | Yes | 2500.000000 | Within the next year |
| 1 | gemini-1.5-flash | $100,000-250,000 | 30 | phones | Yes | 1200.000000 | Within the next year |
| 2 | gemini-1.5-flash | $100,000-250,000 | 50 | electronics | Yes | 2500.000000 | Within the next year |
| 3 | gemini-1.5-flash | $100,000-250,000 | 50 | phones | Yes | 1200.000000 | Within the next year |
| 4 | gemini-1.5-flash | $100,000-250,000 | 70 | electronics | Yes | 500.000000 | Within the next year |
| 5 | gemini-1.5-flash | $100,000-250,000 | 70 | phones | No | nan | Within the next year |
| 6 | gemini-1.5-flash | above $250,000 | 30 | electronics | Yes | 5000.000000 | Within the next year |
| 7 | gemini-1.5-flash | above $250,000 | 30 | phones | Yes | 0.000000 | Within the next year |
| 8 | gemini-1.5-flash | above $250,000 | 50 | electronics | Yes | 5000.000000 | Within the next year |
| 9 | gemini-1.5-flash | above $250,000 | 50 | phones | Yes | 0.000000 | Within the next year |
| 10 | gemini-1.5-flash | above $250,000 | 70 | electronics | Yes | 5000.000000 | Within the next year |
| 11 | gemini-1.5-flash | above $250,000 | 70 | phones | No | nan | Never |
| 12 | gemini-1.5-flash | under $100,000 | 30 | electronics | Yes | 250.000000 | Within the next year |
| 13 | gemini-1.5-flash | under $100,000 | 30 | phones | No | nan | Within the next year |
| 14 | gemini-1.5-flash | under $100,000 | 50 | electronics | No | nan | Within the next year |
| 15 | gemini-1.5-flash | under $100,000 | 50 | phones | No | nan | Within the next year |
| 16 | gemini-1.5-flash | under $100,000 | 70 | electronics | No | nan | Within the next year |
| 17 | gemini-1.5-flash | under $100,000 | 70 | phones | No | nan | Never |
Example 2
In the next example, we use the same scenarios to create versions of the questions before we combine them in a survey. This allows us to add a skip rule based on a question/scenario combination, as opposed to skipping a question for all scenarios:loop method creates new versions of questions with scenarios already inserted:

| model.model | agent.annual_income | agent.age | answer.recent_purchase_electronics | answer.amount_electronics | answer.next_purchase_electronics | answer.recent_purchase_phones | answer.amount_phones | answer.next_purchase_phones | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | gemini-1.5-flash | $100,000-250,000 | 30 | Yes | 2500 | Within the next year | Yes | 1200.000000 | Within the next year |
| 1 | gemini-1.5-flash | $100,000-250,000 | 50 | Yes | 2500 | Within the next year | Yes | 1200.000000 | Within the next year |
| 2 | gemini-1.5-flash | $100,000-250,000 | 70 | Yes | 500 | Within the next year | No | 0.000000 | Within the next year |
| 3 | gemini-1.5-flash | above $250,000 | 30 | Yes | 5000 | Within the next year | Yes | 0.000000 | Within the next year |
| 4 | gemini-1.5-flash | above $250,000 | 50 | Yes | 5000 | Within the next year | Yes | 0.000000 | Within the next year |
| 5 | gemini-1.5-flash | above $250,000 | 70 | Yes | 5000 | Within the next year | No | 0.000000 | Never |
| 6 | gemini-1.5-flash | under $100,000 | 30 | Yes | 250 | Within the next year | No | 300.000000 | Within the next year |
| 7 | gemini-1.5-flash | under $100,000 | 50 | No | 250 | Within the next year | nan | nan | nan |
| 8 | gemini-1.5-flash | under $100,000 | 70 | No | 0 | Within the next year | nan | nan | nan |
