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