> For the complete documentation index, see [llms.txt](https://docs.myshell.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.myshell.ai/create/pro-config-mode/example/function-calling-example.md).

# Function Calling Example

> ### [&#xD;](<https://www.promptingguide.ai/applications/function_calling&#xD;&#xA;&#xD;&#xA;https://platform.openai.com/docs/api-reference/chat/create>)Reference
>
> <https://www.promptingguide.ai/applications/function_calling>
>
> <https://platform.openai.com/docs/api-reference/chat/create>

In this section, we will provide an example of advanced usage of function calling, and we hope this can serve as a good starting point for you to write your own Pro Config.

````json
{
  "type": "automata",
  "id": "studymate_bot",
  "initial": "home_page_state",
  "inputs": {},
  "outputs": {},
  "context": {
      "general_purpose_widget_id":"",
      "advanced_task_widget_id":"",
      "memory":"{{[]}}",
      "note_topic":"",
      "user_given_note_topic":null,
      "number_of_questions":"",
      "difficulty_level":"",
      "questions_string_sample": "{\"question\": \"Which of the following statements is not correct? \\n A. The execution of an Automata starts from the `initial` state. \\n B. An Automata can contain multiple AtomicStates. \\n C. Each AtomicState must define both inputs and outputs. \\n D. We can define transitions in either Automata or AtomicState.\", \"answer\": \"C\", \"explanation\": \"Both inputs and outputs in an AtomicState are optional.\"}",
      "questions_string_sample_another": "{\"question\": \"You are building an AutomicState, please choose the correct order of execution: \\n A. inputs -> tasks -> outputs -> render \\n B. render -> inputs -> tasks -> outputs. \\n C. tasks -> inputs -> outputs -> render.  \\n D. render -> tasks -> inputs -> outputs\", \"answer\": \"A\", \"explanation\": \"The correct order is `inputs -> tasks -> outputs -> render`. Please refer to `Expressions and Variables`\"}, {\"question\": \"Which of the following expressions is not correct (assume all the variables exist)? \\n A. context.variable \\n B. variable \\n C. variable1 + variable2 \\n D. np.array(variable)\", \"answer\": \"D\", \"explanation\": \"Our expression supports JavaScript grammar.\"}",
      "questions": "",
      "question_idx": "",
      "chosen_answer": "",
      "correct_answer": "",
      "correct_count": "",
      "google_search_raw_result":"",
      "json_regex":"{{\"\\[.*?\\]\"}}",
      "json_flags":"s",
      "json_match":""
  },
  "transitions": {
      "go_home": "home_page_state",
      "submit_note":"submit_note_state",
      "prequiz":"pre_quiz_page",
      "get_quiz":"quiz_page_state",
      "continue": "continue_state"
  },
  "states": {
      "home_page_state": {
          "inputs": {
            "intro_message": {
              "type": "text",
              "user_input": false,
              "default_value": "Hi, this is your studymate chatbot"
            },
            "general_purpose_widget_id": {
              "type": "text",
              "user_input": false,
              "default_value": "1744214024104448000",
              "description": "widget id for the main widget(LLM)"
            },
            "advanced_task_widget_id": {
              "type": "text",
              "user_input": false,
              "default_value": "1744214047475109888",
              "description": "widget id for the advanced tasks widget(LLM)"
            },
            "topic":{
              "type": "text",
              "user_input": true,
              "default_value": "{{context.note_topic}}"
            }
          },
          "outputs": {
            "context.general_purpose_widget_id": "{{general_purpose_widget_id}}",
            "context.advanced_task_widget_id": "{{advanced_task_widget_id}}",
            "context.user_given_note_topic":"{{topic}}",
            "context.note_topic":"{{topic}}",
            "context.question_idx": "{{0}}",
            "context.correct_count": "{{0}}",
            "context.json_match":"{{new RegExp(context.json_regex, context.json_flags)}}"
          },
          "render": {
            "text": "Welcome to the Study Mate Chatbot, continue by pasting your note",
            "buttons": [
              {
                "content":  "🏠Home",
                "description": "Go to back to 🏠Home",
                "on_click": "go_home"
              },
              {
                "content": "Take Quiz",
                "description": "Skip submitting note and take quiz on {{topic}}",
                "on_click": "prequiz"
              }
            ]
          },
          "transitions": {
              "CHAT": "submit_note_state"
            }
        },
        "submit_note_state":{
          "inputs": {
              "user_note":{
                  "type": "IM",
                  "user_input": true
              }
          },
          "tasks": [
              {
                  "name": "generate_reply",
                  "module_type": "AnyWidgetModule",
                  "module_config": {
                      "widget_id": "{{context.general_purpose_widget_id}}",
                      "system_prompt": "You are a summary-giving machine, summarising notes given and also giving main key points.",
                      "user_prompt": "{{user_note}}",
                      "output_name": "reply"
                  }
              },
              {
                  "name": "generate_topic",
                  "module_type": "AnyWidgetModule",
                  "module_config": {
                      "widget_id": "{{context.general_purpose_widget_id}}",
                      "system_prompt": "You are a summary-giving encyclopedia, identify the topic of the given note.",
                      "user_prompt": "{{user_note}}",
                      "output_name": "note_topic"
                  }
              },
              {
                  "name": "generate_voice",
                  "module_type": "AnyWidgetModule",
                  "module_config": {
                      "content": "{{reply}}",
                      "widget_id": "1743159010695057408",
                      "output_name": "reply_voice"
                  }
              }
          ],
          "outputs": {
              "context.note_topic":"{{note_topic}}",
              "context.google_search_raw_result":"{{google_search_raw_result}}"
          },
          "render": {
              "text": "{{reply}}",
              "audio": "{{reply_voice}}",
              "buttons": [
                  {
                    "content": "Quiz",
                    "description": "Attempt quiz on {{context.note_topic??note_topic}}",
                    "on_click": "prequiz"
                  }
                ]
          }
          
        },
        "pre_quiz_page":{
          "inputs": {
              "difficulty_level":{
                  "type": "text",
                  "choices": ["easy","medium","hard"],
                  "default_value": "medium",
                  "description": "Choose the difficulty level for your quiz",
                  "user_input": true
              },
              "number_of_questions":{
                  "type": "text",
                  "default_value": "10",
                  "description": "Enter the number of questions you want to attempt in this quiz",
                  "user_input": true
              }
          },
          "tasks": [
              {
                  "name": "generate_multiple_choice_question",
                  "module_type": "AnyWidgetModule",
                  "module_config": {
                      "widget_id": "{{context.advanced_task_widget_id}}",
                      "system_prompt": "You are my question bank, generating dynamic {{difficulty_level}} level questions based on the topic provided, you will generate a question with several choices (as mcq test) and output it in JSON format. the format is `{'question': 'here is the question', 'choices': ['A. xxxxxxxxxxxx', 'B. xxxxxxxxx', 'C. xxxxxxxxxxx', 'D. xxxxxxxxxx'], 'answer': '? (from ABCD)', 'explanation': 'why we choose ? (from ABCD) as answer, explain it.'}`",
                      "user_prompt": "generate a four choice questions under the topic:{{context.user_given_note_topic??context.note_topic}}. The output should be a JSON format.",
                      "function_description": "Generate a multiple-choice question. Output: JSON format question. containing question, choices, answer and explanation",
                      "function_name": "GenerateMCQ",
                      "function_parameters": [
                          {
                            "type": "string",
                            "name":"question",
                            "description": "the question"
                          },
                          {
                            "type": "array",
                            "name":"choices",
                            "items": {
                              "type": "string"
                            },
                            "description": "the choices, must contain 4 choices, format should be A. xxx, B. xxx, C. xxx, D.xxx"
                          },
                          {
                            "type": "string",
                            "name":"answer",
                            "description": "the answer, must chosen from A/B/C/D"
                          },
                          {
                            "type": "string",
                            "name":"explanation",
                            "description": "the explanation"
                          }
                    ],
                    "output_name": "llm_generated_question"
                  }
              }
          ],
          "outputs": {
              "context.number_of_questions":"{{number_of_questions}}",
              "context.difficulty_level":"{{difficulty_level}}",
              "context.questions":"{{llm_generated_question.mcqtest}}"
          },
          "render": {
              "text": "```json\n{{JSON.stringify(context.questions, null, 2)}}\n```",
              "buttons": [
                  {
                      "content": "Start Quiz",
                      "description": "Start untimed quiz {{context.questions}}",
                      "on_click":"get_quiz"
                  }
              ]
          }
        },
        "quiz_page_state": {
          "outputs": {
            "context.correct_answer": "{{context.questions[context.question_idx]['answer']}}"
          },
          "render": {
            "text": "{{context.question_idx + 1}}. {{context.questions[context.question_idx]['question']}}",
            "buttons": [
              {
                "content": "A.",
                "description": "Choose A.",
                "on_click": {
                  "event": "check_answer",
                  "payload": {
                    "button_id": "A"
                  }
                }
              },
              {
                "content": "B.",
                "description": "Choose B.",
                "on_click": {
                  "event": "check_answer",
                  "payload": {
                    "button_id": "B"
                  }
                }
              },
              {
                "content": "C.",
                "description": "Choose C.",
                "on_click": {
                  "event": "check_answer",
                  "payload": {
                    "button_id": "C"
                  }
                }
              },
              {
                "content": "D.",
                "description": "Choose D.",
                "on_click": {
                  "event": "check_answer",
                  "payload": {
                    "button_id": "D"
                  }
                }
              }
            ],
          }
          "transitions": {
            "check_answer": {
              "target": "analyze_answer_state",
              "target_inputs":{
                  "button_id":"{{button_id}}"
              }
            }
          }
        },
        "analyze_answer_state": {
          "inputs": {
            "button_id": {
              "type": "text",
              "user_input": false
            }
          },
          "outputs": {
            "context.chosen_answer": "{{button_id}}",
            "context.is_correct": "{{button_id == context.correct_answer}}"
          },
          "render": {
            "text": "Check answer state."
          },
          "transitions": {
            "ALWAYS": [
              {
                "target": "correct_answer_state",
                "condition": "{{context.is_correct}}"
              },
              {
                "target": "wrong_answer_state",
                "condition": "{{true}}"
              }
            ]
          }
        },
        "correct_answer_state": {
          "outputs": {
            "context.question_idx": "{{(context.question_idx + 1) % context.questions.length}}",
            "context.correct_count": "{{context.correct_count + 1}}"
          },
          "render": {
            "text": "Congratulations! You have chosen the correct answer {{context.correct_answer}}",
            "buttons": [
              {
                "content": "Continue",
                "description": "continue",
                "on_click": "continue"
              }
            ]
          }
        },
        "wrong_answer_state": {
          "outputs": {
            "context.question_idx": "{{(context.question_idx + 1) % context.questions.length}}"
          },
          "render": {
            "text": "Oh No! The chosen answer is {{context.chosen_answer}}, while the correct one is {{context.correct_answer}}.",
            "buttons": [
              {
                "content": "Continue",
                "description": "continue",
                "on_click": "continue"
              }
            ]
          }
        },
        "continue_state": {
          "render": {
            "text": "Click to Next Question"
          },
          "transitions": {
            "ALWAYS": [
              {
                "target": "quiz_page_state",
                "condition": "{{context.question_idx > 0}}"
              },
              {
                "target": "finish_state",
                "condition": "{{context.correct_count == context.questions.length}}"
              },
              {
                "target": "review_state",
                "condition": "{{true}}"
              }
            ]
          }
        },
        "finish_state": {
          "render": {
            "text": "Congratulations  you scored {{context.correct_count}}/{{context.questions.length}}",
            "buttons": [
              {
                "content": "🏠Home",
                "description": "Back to Home",
                "on_click": "go_home"
              }
            ]
          }
        },
        "review_state": {
          "outputs": {
            "context.memory": "{{[]}}"
          },
          "render": {
            "text": "{{context.intro_message}}"
          }
        }
  }
}
````

The above example is from a bot called StudyMate made by a participant of Pro Config Learning Lab. In this app, the user can input any topic and choose a difficulty level, and some quizzes can be dynamically generated accordingly. The core to parse the results into structured quizes are achieved using function-calling as:

```json
        "tasks": [
              {
                  "name": "generate_multiple_choice_question",
                  "module_type": "AnyWidgetModule",
                  "module_config": {
                      "widget_id": "{{context.advanced_task_widget_id}}",
                      "system_prompt": "You are my question bank, generating dynamic {{difficulty_level}} level questions based on the topic provided, you will generate a question with several choices (as mcq test) and output it in JSON format. the format is `{'question': 'here is the question', 'choices': ['A. xxxxxxxxxxxx', 'B. xxxxxxxxx', 'C. xxxxxxxxxxx', 'D. xxxxxxxxxx'], 'answer': '? (from ABCD)', 'explanation': 'why we choose ? (from ABCD) as answer, explain it.'}`",
                      "user_prompt": "generate a four choice questions under the topic:{{context.user_given_note_topic??context.note_topic}}. The output should be a JSON format.",
                      "function_description": "Generate a multiple-choice question. Output: JSON format question. containing question, choices, answer and explanation",
                      "function_name": "GenerateMCQ",
                      "function_parameters": [
                          {
                            "type": "string",
                            "name":"question",
                            "description": "the question"
                          },
                          {
                            "type": "array",
                            "name":"choices",
                            "items": {
                              "type": "string"
                            },
                            "description": "the choices, must contain 4 choices, format should be A. xxx, B. xxx, C. xxx, D.xxx"
                          },
                          {
                            "type": "string",
                            "name":"answer",
                            "description": "the answer, must chosen from A/B/C/D"
                          },
                          {
                            "type": "string",
                            "name":"explanation",
                            "description": "the explanation"
                          }
                    ],
                    "output_name": "llm_generated_question"
                  }
              }
          ],
```

In the above example, we aim to generate the question, choices, answer and explanation, and the type of them are `string` `array` `string` `string` accordingly. We can adopt the OpenAI schema like above to define the desired structure recursively.&#x20;
