From 2f1e0927c272da9f91f52efe739c53d235bc36a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B8=D1=8F=20=D0=91=D0=B5=D1=80=D0=B4?= =?UTF-8?q?=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Wed, 27 May 2026 06:16:27 +0000 Subject: [PATCH] =?UTF-8?q?=D1=81=D1=8B=D1=80=D0=BE=D0=B9=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BA=D1=81=D1=82=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=E2=86=92=20=D0=BF=D0=BB=D0=BE=D1=81=D0=BA=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BA=D0=B0=D1=80=D1=82=D0=BE=D1=87=D0=BA=D0=B0:=20task=5Fpars?= =?UTF-8?q?er.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task_parser.py | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_parser.py diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_parser.py b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_parser.py new file mode 100644 index 0000000..6a0a0a0 --- /dev/null +++ b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_parser.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import os +from typing import List + +from langchain_core.prompts import PromptTemplate +from langchain_openai import ChatOpenAI +from langchain_core.output_parsers import PydanticOutputParser +from pydantic import BaseModel, Field + + +class AssignmentCard(BaseModel): + """Структурированная карточка задания.""" + + title: str = Field(..., description="Краткое название задачи") + subject: str = Field(..., description="Область знаний или предмет") + deadline_hint: str | None = Field( + None, + description=( + "Указание срока сдачи в свободной форме (например, «к пятнице»). " + "Если не найдено – None" + ), + ) + deliverable_type: str = Field(..., description="Тип сдаваемого материала") + grading_hints: List[str] = Field( + default_factory=list, + description=( + "Ключевые критерии оценки, перечисленные в тексте. " + "Если не найдено – пустой список" + ), + ) + + +def build_chain() -> PromptTemplate: + """Создаёт цепочку Prompt → LLM → Pydantic парсер.""" + parser = PydanticOutputParser(pydantic_object=AssignmentCard) + + prompt_template = ( + "Ниже приведено описание задания от преподавателя. " + "Ваша задача – извлечь из него следующую информацию:\n" + "- title: название задачи\n" + "- subject: предмет/область знаний\n" + "- deadline_hint: указание срока сдачи (если есть)\n" + "- deliverable_type: что сдать (отчёт, код, презентация и т.д.)\n" + "- grading_hints: список критериев оценки\n\n" + "Ответ должен быть строго в формате JSON, соответствующем модели " + f"{AssignmentCard.__name__}.\n" + "{format_instructions}\n\n" + "Текст задания:\n{assignment_text}" + ) + + prompt = PromptTemplate( + template=prompt_template, + input_variables=["assignment_text"], + partial_variables={"format_instructions": parser.get_format_instructions()}, + ) + return prompt + + +def main() -> None: + """Пример использования цепочки.""" + # Получаем ключ API из переменной окружения + api_key = os.getenv("OPENAI_API_KEY") + if not api_key: + raise RuntimeError( + "Переменная окружения OPENAI_API_KEY не установлена. " + "Установите её перед запуском." + ) + + llm = ChatOpenAI(api_key=api_key, temperature=0) + + prompt = build_chain() + parser = PydanticOutputParser(pydantic_object=AssignmentCard) + chain = prompt | llm | parser + + # Пример входного текста + assignment_text = ( + "Сдайте к пятнице мини-отчёт по LangChain: 2 страницы, упор на агентов. " + "Оценка: за полноту и за пример кода." + ) + + result = chain.invoke({"assignment_text": assignment_text}) + + # Выводим валидированный объект + print("=== Валидированная карточка ===") + print(result.model_dump()) + + # Краткая человекочитаемая сводка + summary = ( + f"Задача: {result.title}\n" + f"Предмет: {result.subject}\n" + f"Срок сдачи: {result.deadline_hint or 'не указан'}\n" + f"Тип сдаваемого материала: {result.deliverable_type}\n" + f"Критерии оценки: {', '.join(result.grading_hints) if result.grading_hints else 'нет'}" + ) + print("\n=== Сводка ===") + print(summary) + + +if __name__ == "__main__": + main() \ No newline at end of file