Spaces:
Running
Running
File size: 6,997 Bytes
833dac3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
"""
LLM Chain implementation using Langchain for educational concept analysis
"""
from typing import Dict, Any, List
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import PydanticOutputParser
from langchain.chains import LLMChain
from pydantic import BaseModel, Field
from config import OPENAI_API_KEY, OPENAI_MODEL
# Define Pydantic models for structured output
class Concept(BaseModel):
"""Model for a single concept"""
id: str = Field(description="Unique identifier for the concept")
name: str = Field(description="Name of the concept")
description: str = Field(description="Brief description of the concept")
difficulty: str = Field(description="Difficulty level: basic, intermediate, or advanced")
class Relationship(BaseModel):
"""Model for relationship between concepts"""
source: str = Field(description="Source concept ID")
target: str = Field(description="Target concept ID")
type: str = Field(description="Type of relationship: prerequisite or related")
explanation: str = Field(description="Explanation of why this relationship exists")
class ConceptMap(BaseModel):
"""Model for complete concept map"""
main_concept: str = Field(description="Main concept being analyzed")
sub_concepts: List[Concept] = Field(description="List of sub-concepts")
relationships: List[Relationship] = Field(description="List of relationships between concepts")
class Example(BaseModel):
"""Model for concept examples"""
problem: str = Field(description="Example problem")
solution: str = Field(description="Step-by-step solution")
difficulty: str = Field(description="Difficulty level: Easy, Medium, or Hard")
class Resource(BaseModel):
"""Model for learning resources"""
type: str = Field(description="Type of resource (Video/Article/Interactive/Book)")
title: str = Field(description="Resource title")
description: str = Field(description="Resource description")
link: str = Field(description="Optional resource link")
class ConceptExplanation(BaseModel):
"""Model for detailed concept explanation"""
explanation: str = Field(description="Detailed concept explanation")
examples: List[Example] = Field(description="List of example problems and solutions")
resources: List[Resource] = Field(description="List of learning resources")
practice_questions: List[Example] = Field(description="List of practice questions")
class EducationalLLMChain:
"""
Chain for processing educational concepts using LLM
"""
def __init__(self):
"""Initialize the LLM and parsers"""
self.llm = ChatOpenAI(
model=OPENAI_MODEL,
temperature=0.1,
openai_api_key=OPENAI_API_KEY
)
# Initialize output parsers
self.concept_parser = PydanticOutputParser(pydantic_object=ConceptMap)
self.explanation_parser = PydanticOutputParser(pydantic_object=ConceptExplanation)
# Create decomposition chain
self.decomposition_chain = self._create_decomposition_chain()
# Create explanation chain
self.explanation_chain = self._create_explanation_chain()
def _create_decomposition_chain(self) -> LLMChain:
"""
Create chain for concept decomposition
Returns:
LLMChain for decomposing concepts
"""
template = """You are an expert educational AI tutor.
Analyze this question for a {grade} level student studying {subject}.
Question: {question}
Student Background:
- Grade Level: {grade}
- Subject: {subject}
- Learning Needs: {learning_needs}
Break down the concepts needed to understand this question into a knowledge graph.
Consider the student's grade level and background knowledge.
{format_instructions}
"""
prompt = ChatPromptTemplate.from_template(
template=template,
partial_variables={
"format_instructions": self.concept_parser.get_format_instructions()
}
)
return LLMChain(llm=self.llm, prompt=prompt)
def _create_explanation_chain(self) -> LLMChain:
"""
Create chain for concept explanation
Returns:
LLMChain for explaining concepts
"""
template = """You are an expert educational tutor.
Explain this concept for a {grade} level student studying {subject}:
Concept: {concept_name}
Description: {concept_description}
Student Background:
- Grade Level: {grade}
- Subject: {subject}
- Learning Needs: {learning_needs}
Provide a detailed explanation, examples, resources, and practice questions.
{format_instructions}
"""
prompt = ChatPromptTemplate.from_template(
template=template,
partial_variables={
"format_instructions": self.explanation_parser.get_format_instructions()
}
)
return LLMChain(llm=self.llm, prompt=prompt)
async def decompose_concepts(
self,
question: str,
grade: str,
subject: str,
learning_needs: str
) -> ConceptMap:
"""
Decompose a question into concepts
Args:
question: User's question
grade: Educational grade level
subject: Subject area
learning_needs: Learning needs/goals
Returns:
Structured concept map
"""
response = await self.decomposition_chain.arun({
"question": question,
"grade": grade,
"subject": subject,
"learning_needs": learning_needs
})
return self.concept_parser.parse(response)
async def explain_concept(
self,
concept_name: str,
concept_description: str,
grade: str,
subject: str,
learning_needs: str
) -> ConceptExplanation:
"""
Generate detailed concept explanation
Args:
concept_name: Name of concept to explain
concept_description: Brief concept description
grade: Educational grade level
subject: Subject area
learning_needs: Learning needs/goals
Returns:
Structured concept explanation
"""
response = await self.explanation_chain.arun({
"concept_name": concept_name,
"concept_description": concept_description,
"grade": grade,
"subject": subject,
"learning_needs": learning_needs
})
return self.explanation_parser.parse(response) |