import os from typing import List from pydantic import BaseModel, Field from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI from langchain_core.output_parsers import PydanticOutputParser class AssignmentCard(BaseModel): """Структурированная карточка учебного задания.""" title: str = Field(..., description="Название задания одной фразой") subject: str = Field(..., description="Учебная дисциплина или тема") deadline_hint: str | None = Field( None, description="Срок выполнения в произвольной форме, если упомянут", ) deliverable_type: str = Field( ..., description="Что нужно сдать: отчёт, код, презентация и т.п.", ) grading_hints: List[str] | None = Field( default_factory=list, description="Критерии оценки, которые явно названы в тексте", ) def run(raw_text: str) -> None: output_parser = PydanticOutputParser(pydantic_object=AssignmentCard) template = PromptTemplate( template=( "Прочитай описание учебного задания и заполни все поля карточки.\n\n" "Описание:\n{raw_text}\n\n" "Верни ответ строго в JSON без лишних пояснений.\n" "{format_instructions}" ), input_variables=["raw_text"], partial_variables={ "format_instructions": output_parser.get_format_instructions() }, ) model = ChatOpenAI(model="gpt-4o-mini", temperature=0) chain = template | model | output_parser card: AssignmentCard = chain.invoke({"raw_text": raw_text}) print("Валидированный объект:") print(card.model_dump()) print("\nСводка:") print( f"Задание «{card.title}» по теме «{card.subject}». " f"Сдать: {card.deliverable_type}. " f"Дедлайн: {card.deadline_hint or 'не указан'}. " f"Оценивается: {', '.join(card.grading_hints) if card.grading_hints else 'критерии не указаны'}." ) if __name__ == "__main__": sample = ( "Сдайте к пятнице мини-отчёт по LangChain: 2 страницы, упор на агентов. " "Оценка: за полноту и за пример кода." ) run(sample)