сырой текст задания → плоская карточка: task.py

This commit is contained in:
2026-05-27 08:19:27 +00:00
parent ab1cec0dfe
commit 31582dcc9f
@@ -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()