сырой текст задания → плоская карточка: task.py
This commit is contained in:
@@ -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()
|
||||||
Reference in New Issue
Block a user