NexusLearnAI / llm_chain.py
ChaseHan's picture
Upload 15 files
833dac3 verified
"""
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)