> ## Documentation Index
> Fetch the complete documentation index at: https://docs.learningcommons.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate practice questions

> Learn how to use Knowledge Graph Learning Progressions to find prerequisite standards and generate practice content with LLMs.

export const EarlyAccessCallout = ({children}) => <div className="eyebrow-callout not-prose rounded-xl border border-gray-200/80 p-5 dark:border-white/10" style={{
  marginBottom: "1rem",
  borderRadius: "4px"
}}>
    <div className="mb-3">
      <Badge color="green" size="md" icon="flask">
        Early access
      </Badge>
    </div>
    <div className="callout-body text-[15px] leading-relaxed text-gray-700 dark:text-gray-300">{children}</div>
    <style>{`.callout-body a { text-decoration: underline; text-decoration-color: #178251; }`}</style>
  </div>;

<EarlyAccessCallout>
  The API is in early access and is actively evolving. We will continue expanding it, and breaking changes may occur as we improve accuracy and reliability. Email [support@learningcommons.org](mailto:support@learningcommons.org) ↗ with your feedback or issues.
</EarlyAccessCallout>

Query Knowledge Graph for the prerequisite standards for a given [Academic Standard](/knowledge-graph/graph-reference/academic-standards).

Generate practice questions using these prerequisite standards' [Learning Components](/knowledge-graph/graph-reference/learning-components).

<Note>
  Our current [Learning
  Progressions](/knowledge-graph/graph-reference/learning-progressions) dataset
  from [Student Achievement Partners](https://learnwithsap.org/) ↗ (SAP)
  maps Common Core State Standards for Mathematics into logical sequences. These
  sequences do not name definitive prerequisites – their relationships simply
  indicate what might be helpful in a given circumstance.
</Note>

## What you'll do

* Find prerequisite standards for a target CCSS standard using [Learning
  Progressions](/knowledge-graph/graph-reference/learning-progressions)
* Unpack prerequisite standards into supporting [Learning Components](/knowledge-graph/graph-reference/learning-components)
* Package Knowledge Graph data for an LLM to generate practice questions

## What you'll need

* API key and base URL in the [Learning Commons Platform](https://platform.learningcommons.org/?utm_source=docs\&utm_medium=knowledge-graph) ↗
* OpenAI API key and SDK (`pip install openai` for Python or `npm install openai` for JavaScript)
* [`curl`](https://github.com/curl/curl) ↗, Python, or Node

## Steps

<Steps>
  <Step title="Set up environment variables">
    ```text .env theme={null}
    API_KEY=your_api_key_here
    BASE_URL=https://api.learningcommons.org/knowledge-graph/v0
    OPENAI_API_KEY=your_openai_api_key_here
    ```
  </Step>

  <Step title="Get the prerequisite standards for 6.NS.B.4">
    Use the [`GET /academic-standards/search`](/api-reference/academic-standards/search-academic-standards) endpoint to find the 6.NS.B.4 standard.

    Then, use [`GET /academic-standards/{uuid}/prerequisites`](/api-reference/academic-standards/prerequisites-for-a-standard) to get its prerequisites:

    <CodeGroup>
      ```shell cURL theme={null}
      # Step 1: Find the target standard by statement code
      curl -X GET \
        -H "x-api-key: YOUR_API_KEY" \
        "https://api.learningcommons.org/knowledge-graph/v0/academic-standards/search?statementCode=6.NS.B.4&jurisdiction=Multi-State"

      # Step 2: Get prerequisites using the caseIdentifierUUID from Step 1
      curl -X GET \
        -H "x-api-key: YOUR_API_KEY" \
        "https://api.learningcommons.org/knowledge-graph/v0/academic-standards/YOUR_UUID/prerequisites"
      ```

      ```python Python theme={null}
      import os
      import requests

      api_key = os.getenv("API_KEY")
      base_url = os.getenv("BASE_URL")
      TARGET_CODE = "6.NS.B.4"

      headers = {"x-api-key": api_key}

      # Find the target standard by statement code
      search_response = requests.get(
          f"{base_url}/academic-standards/search",
          headers=headers,
          params={
              "statementCode": TARGET_CODE,
              "jurisdiction": "Multi-State"
          }
      )

      search_result = search_response.json()
      target_standard = search_result[0] if search_result else None

      if not target_standard:
          print(f'❌ No standard found for {TARGET_CODE}')
      else:
          print(f'✅ Found standard {TARGET_CODE}:')
          print(f'  UUID: {target_standard["caseIdentifierUUID"]}')
          print(f'  Description: {target_standard["description"]}')

          # Get prerequisites
          prereq_response = requests.get(
              f"{base_url}/academic-standards/{target_standard['caseIdentifierUUID']}/prerequisites",
              headers=headers
          )

          prereq_result = prereq_response.json()
          prerequisite_standards = prereq_result["data"]
          print(f'✅ Found {len(prerequisite_standards)} prerequisite(s):')
          for prereq in prerequisite_standards:
              print(f'  {prereq["statementCode"]}: {prereq["description"][:80]}...')
      ```

      ```javascript JavaScript theme={null}
      const apiKey = process.env.API_KEY;
      const baseUrl = process.env.BASE_URL;
      const TARGET_CODE = "6.NS.B.4";

      // Find the target standard by statement code
      const searchResponse = await fetch(
        `${baseUrl}/academic-standards/search?statementCode=${TARGET_CODE}&jurisdiction=Multi-State`,
        {
          method: "GET",
          headers: { "x-api-key": apiKey },
        },
      );

      const searchResult = await searchResponse.json();
      const targetStandard = searchResult[0] || null;

      if (!targetStandard) {
        console.error(`❌ No standard found for ${TARGET_CODE}`);
      } else {
        console.log(`✅ Found standard ${TARGET_CODE}:`);
        console.log(`  UUID: ${targetStandard.caseIdentifierUUID}`);
        console.log(`  Description: ${targetStandard.description}`);

        // Get prerequisites
        const prereqResponse = await fetch(
          `${baseUrl}/academic-standards/${targetStandard.caseIdentifierUUID}/prerequisites`,
          {
            method: "GET",
            headers: { "x-api-key": apiKey },
          },
        );

        const prereqResult = await prereqResponse.json();
        const prerequisiteStandards = prereqResult.data;
        console.log(`✅ Found ${prerequisiteStandards.length} prerequisite(s):`);
        prerequisiteStandards.forEach((prereq) => {
          console.log(
            `  ${prereq.statementCode}: ${prereq.description.substring(0, 80)}...`,
          );
        });
      }
      ```
    </CodeGroup>

    ```json Response theme={null}
    [
      {
        "caseIdentifierUUID": "6b9ed00e-d7cc-11e8-824f-0242ac160002",
        "statementCode": "4.OA.B.4",
        "standardDescription": "A buildsTowards relationship indicates that proficiency in one entity supports the likelihood of success in another, capturing a directional progression without requiring strict prerequisite order."
      }
      // ...
    ]
    ```
  </Step>

  <Step title="Get Learning Components for the prerequisite standards">
    Use the [`GET /academic-standards/{uuid}/learning-components`](/api-reference/learning-components/learning-components-for-a-standard) endpoint for each prerequisite standard:

    <CodeGroup>
      ```shell cURL theme={null}
      # Get Learning Components for a prerequisite standard
      # Replace PREREQ_UUID with each prerequisite's caseIdentifierUUID
      curl -X GET \
        -H "x-api-key: YOUR_API_KEY" \
        "https://api.learningcommons.org/knowledge-graph/v0/academic-standards/PREREQ_UUID/learning-components"
      ```

      ```python Python theme={null}
      import os
      import requests

      api_key = os.getenv("API_KEY")
      base_url = os.getenv("BASE_URL")

      headers = {"x-api-key": api_key}

      # prerequisite_standards from previous step
      prerequisite_learning_components = []

      for prereq in prerequisite_standards:
          lc_response = requests.get(
              f"{base_url}/academic-standards/{prereq['caseIdentifierUUID']}/learning-components",
              headers=headers
          )

          lc_result = lc_response.json()
          for lc in lc_result["data"]:
              prerequisite_learning_components.append({
                  "caseIdentifierUUID": prereq["caseIdentifierUUID"],
                  "statementCode": prereq["statementCode"],
                  "standardDescription": prereq["description"],
                  "learningComponentDescription": lc["description"]
              })

      print(f'✅ Found {len(prerequisite_learning_components)} supporting Learning Components for prerequisites:')
      for lc in prerequisite_learning_components[:5]:
          print(f'  {lc["learningComponentDescription"][:80]}...')
      ```

      ```javascript JavaScript theme={null}
      const apiKey = process.env.API_KEY;
      const baseUrl = process.env.BASE_URL;

      // prerequisiteStandards from previous step
      const prerequisiteLearningComponents = [];

      for (const prereq of prerequisiteStandards) {
        const lcResponse = await fetch(
          `${baseUrl}/academic-standards/${prereq.caseIdentifierUUID}/learning-components`,
          {
            method: "GET",
            headers: { "x-api-key": apiKey },
          },
        );

        const lcResult = await lcResponse.json();
        for (const lc of lcResult.data) {
          prerequisiteLearningComponents.push({
            caseIdentifierUUID: prereq.caseIdentifierUUID,
            statementCode: prereq.statementCode,
            standardDescription: prereq.description,
            learningComponentDescription: lc.description,
          });
        }
      }

      console.log(
        `✅ Found ${prerequisiteLearningComponents.length} supporting Learning Components for prerequisites:`,
      );
      prerequisiteLearningComponents.slice(0, 5).forEach((lc) => {
        console.log(`  ${lc.learningComponentDescription.substring(0, 80)}...`);
      });
      ```
    </CodeGroup>

    ```json Response theme={null}
    [
      {
        "caseIdentifierUUID": "6b9d5f43-d7cc-11e8-824f-0242ac160002",
        "statementCode": "5.OA.A.2",
        "standardDescription": "A buildsTowards relationship indicates that proficiency in one entity supports the likelihood of success in another, capturing a directional progression without requiring strict prerequisite order.",
        "learningComponentDescription": "Write simple expressions of two or more steps and with grouping symbols that record calculations with numbers"
      }
      // ...
    ]
    ```

    You will use the `prerequisiteLearningComponents` array to generate practice questions in the next step.
  </Step>

  <Step title="Generate practice problems">
    Package the Academic Standards and Learning Components data to generate practice questions.

    <CodeGroup>
      ```javascript Javascript theme={null}
      function packageContextData(targetStandard, prerequisiteLearningComponents) {
        // Package the Academic Standards and Learning Components data for text generation
        const standardsMap = new Map();

        // Group Learning Components by Academic Standard for context
        for (const row of prerequisiteLearningComponents) {
          if (!standardsMap.has(row.caseIdentifierUUID)) {
            standardsMap.set(row.caseIdentifierUUID, {
              statementCode: row.statementCode,
              description: row.standardDescription || "(no statement)",
              supportingLearningComponents: [],
            });
          }

          standardsMap.get(row.caseIdentifierUUID).supportingLearningComponents.push({
            description: row.learningComponentDescription || "(no description)",
          });
        }

        const fullStandardsContext = {
          targetStandard: {
            statementCode: targetStandard.statementCode,
            description: targetStandard.description || "(no statement)",
          },
          prereqStandards: Array.from(standardsMap.values()),
        };

        return fullStandardsContext;
      }
      ```

      ```python Python theme={null}
      def package_context_data(target_standard, prerequisite_learning_components):
          # Package the Academic Standards and Learning Components data for text generation
          standards_map = {}

          # Group Learning Components by Academic Standard for context
          for row in prerequisite_learning_components:
              case_id = row['caseIdentifierUUID']
              if case_id not in standards_map:
                  standards_map[case_id] = {
                      'statementCode': row['statementCode'],
                      'description': row['standardDescription'] or '(no statement)',
                      'supportingLearningComponents': []
                  }

              standards_map[case_id]['supportingLearningComponents'].append({
                  'description': row['learningComponentDescription'] or '(no description)'
              })

          full_standards_context = {
              'targetStandard': {
                  'statementCode': target_standard['statementCode'],
                  'description': target_standard['description'] or '(no statement)'
              },
              'prereqStandards': list(standards_map.values())
          }

          print('✅ Packaged full standards context for text generation')
          return full_standards_context
      ```
    </CodeGroup>

    Use that JSON in a prompt so the LLM has full context when creating practice questions:

    <CodeGroup>
      ```javascript Javascript theme={null}
      const OpenAI = require("openai");

      const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

      const OPENAI_MODEL = "gpt-4";
      const OPENAI_TEMPERATURE = 0.7;

      async function generatePractice(fullStandardsContext) {
        console.log(
          `🔄 Generating practice questions for ${fullStandardsContext.targetStandard.statementCode}...`,
        );

        try {
          // Build prompt inline
          let prerequisiteText = "";
          for (const prereq of fullStandardsContext.prereqStandards) {
            prerequisiteText += `- ${prereq.statementCode}: ${prereq.description}\n`;
            prerequisiteText += "  Supporting Learning Components:\n";
            for (const lc of prereq.supportingLearningComponents) {
              prerequisiteText += `    • ${lc.description}\n`;
            }
          }

          const prompt = `You are a math tutor helping middle school students. Based on the following information, generate 3 practice questions for the target standard. Questions should help reinforce the key concept and build on prerequisite knowledge.

      Target Standard:
      - ${fullStandardsContext.targetStandard.statementCode}: ${fullStandardsContext.targetStandard.description}

      Prerequisite Standards & Supporting Learning Components:
      ${prerequisiteText}`;

          const response = await openai.chat.completions.create({
            model: OPENAI_MODEL,
            messages: [
              {
                role: "system",
                content: "You are an expert middle school math tutor.",
              },
              { role: "user", content: prompt },
            ],
            temperature: OPENAI_TEMPERATURE,
          });

          const practiceQuestions = response.choices[0].message.content.trim();

          console.log(`✅ Generated practice questions:\n`);
          console.log(practiceQuestions);

          return {
            aiGenerated: practiceQuestions,
            targetStandard: fullStandardsContext.targetStandard.statementCode,
            prerequisiteCount: fullStandardsContext.prereqStandards.length,
          };
        } catch (err) {
          console.error("❌ Error generating practice questions:", err.message);
          throw err;
        }
      }
      ```

      ```python Python theme={null}
      from openai import OpenAI

      openai_client = OpenAI(
          api_key=os.getenv('OPENAI_API_KEY')
      )

      OPENAI_MODEL = 'gpt-4'
      OPENAI_TEMPERATURE = 0.7

      def generate_practice(full_standards_context):
          print(f'🔄 Generating practice questions for {full_standards_context["targetStandard"]["statementCode"]}...')

          try:
              # Build prompt inline
              prerequisite_text = ''
              for prereq in full_standards_context['prereqStandards']:
                  prerequisite_text += f'- {prereq["statementCode"]}: {prereq["description"]}\n'
                  prerequisite_text += '  Supporting Learning Components:\n'
                  for lc in prereq['supportingLearningComponents']:
                      prerequisite_text += f'    • {lc["description"]}\n'

              prompt = f"""You are a math tutor helping middle school students. Based on the following information, generate 3 practice questions for the target standard. Questions should help reinforce the key concept and build on prerequisite knowledge.

      Target Standard:
      - {full_standards_context["targetStandard"]["statementCode"]}: {full_standards_context["targetStandard"]["description"]}

      Prerequisite Standards & Supporting Learning Components:
      {prerequisite_text}"""

              response = openai_client.chat.completions.create(
                  model=OPENAI_MODEL,
                  messages=[
                      {'role': 'system', 'content': 'You are an expert middle school math tutor.'},
                      {'role': 'user', 'content': prompt}
                  ],
                  temperature=OPENAI_TEMPERATURE
              )

              practice_questions = response.choices[0].message.content.strip()

              print('✅ Generated practice questions:\n')
              print(practice_questions)

              return {
                  'aiGenerated': practice_questions,
                  'targetStandard': full_standards_context['targetStandard']['statementCode'],
                  'prerequisiteCount': len(full_standards_context['prereqStandards'])
              }
          except Exception as err:
              print(f'❌ Error generating practice questions: {str(err)}')
              raise err
      ```
    </CodeGroup>

    ```text Example response theme={null}
    Question 1:
    Find the greatest common factor of 36 and 90. Then use the distributive property to express the sum of these two numbers as a multiple of a sum of two whole numbers with no common factor.

    Question 2:
    Write the expression "add 12 and 15, then multiply by 3" as an algebraic expression. After that, recognize that this expression is three times as large as 12 + 15, without having to calculate the indicated sum or product.

    Question 3:
    Determine whether the number 72 is a multiple of the digit 8. Find all factor pairs of 72. Recognize that 72 is a multiple of each of its factors and determine whether 72 is a prime or a composite number.
    ```

    You can now integrate these practice questions into your product workflow!
  </Step>

  <Step title="Keep exploring">
    We scoped to a single standard for clarity, but you can also extend prerequisite chains across grade levels or explore other target standards and subject areas.

    For more comprehensive learning experiences, extend your queries to include lessons, assessments, or instructional routines.
  </Step>
</Steps>
