diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task.py b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task.py new file mode 100644 index 0000000..e4e9662 --- /dev/null +++ b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task.py @@ -0,0 +1,97 @@ +# task.py + +import os +from typing import List, Optional + +from pydantic import BaseModel, Field +from langchain_core.prompts import PromptTemplate +from langchain_openai import ChatOpenAI +from langchain_core.output_parsers import PydanticOutputParser + + +class TaskCard(BaseModel): + """ + Карточка задания, получаемая из неформального описания. + """ + title: str = Field(..., description="Краткое название задачи") + subject: Optional[str] = Field( + None, + description="Предмет/тема, к которой относится задание (если указано)" + ) + deadline_hint: Optional[str] = Field( + None, + description="Указание срока сдачи в свободной форме" + ) + deliverable_type: str = Field(..., description="Тип сдаваемого материала") + grading_hints: List[str] = Field( + default_factory=list, + description="Ключевые критерии оценки (если упомянуты)" + ) + + +# Создаём парсер для Pydantic модели +parser = PydanticOutputParser(pydantic_object=TaskCard) + +# Шаблон промпта. Модель должна вернуть JSON, соответствующий TaskCard. +prompt_template = PromptTemplate( + template=""" +Вы — помощник по анализу учебных заданий. +Вам дано неформальное описание задания от преподавателя. +Нужно извлечь из него следующую информацию и вернуть в формате JSON, +соответствующем модели TaskCard: + +{format_instructions} + +Пример входа: +{input_text} +""", + input_variables=["input_text"], + partial_variables={"format_instructions": parser.get_format_instructions()}, +) + +# Инициализируем LLM. Ключ берётся из переменной окружения OPENAI_API_KEY. +llm = ChatOpenAI( + model="gpt-4o-mini", # можно заменить на нужную модель + temperature=0, + max_retries=2, +) + +# Строим цепочку: промпт → LLM → парсер +chain = prompt_template | llm | parser + + +def main(): + """ + Пример использования. Вводится строка задания, выводятся: + 1) валидированный объект TaskCard (dump) + 2) человекочитаемая сводка + """ + # Для примера берём ввод из переменной окружения или stdin + input_text = os.getenv( + "TASK_TEXT", + "Сдайте к пятнице мини-отчёт по LangChain: 2 страницы, упор на агентов. Оценка: за полноту и за пример кода." + ) + + # Запускаем цепочку + result: TaskCard = chain.invoke({"input_text": input_text}) + + # Выводим результат + print("\n=== Валидированный объект ===") + print(result.model_dump(indent=2)) + + print("\n=== Краткая сводка ===") + summary_parts = [ + f"Задача: {result.title}", + f"Тема: {result.subject or 'не указана'}", + f"Срок сдачи: {result.deadline_hint or 'не указан'}", + f"Тип сдаваемого материала: {result.deliverable_type}", + ] + if result.grading_hints: + summary_parts.append( + "Критерии оценки: " + ", ".join(result.grading_hints) + ) + print("; ".join(summary_parts)) + + +if __name__ == "__main__": + main() \ No newline at end of file