Обновить solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/solution.py

This commit is contained in:
2026-05-27 07:12:27 +00:00
parent 25ae2bd0e8
commit dc3012773d
@@ -1,101 +1,68 @@
from __future__ import annotations
import os import os
from typing import List from typing import List
from pydantic import BaseModel, Field
from langchain_core.prompts import PromptTemplate from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import PydanticOutputParser from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
class AssignmentCard(BaseModel): class AssignmentCard(BaseModel):
"""Структурированная карточка задания.""" """Структурированная карточка учебного задания."""
title: str = Field(..., description="Краткое название задачи") title: str = Field(..., description="Название задания одной фразой")
subject: str = Field(..., description="Область знаний или предмет") subject: str = Field(..., description="Учебная дисциплина или тема")
deadline_hint: str | None = Field( deadline_hint: str | None = Field(
None, None,
description=( description="Срок выполнения в произвольной форме, если упомянут",
"Указание срока сдачи в свободной форме (например, «к пятнице»). "
"Если не найдено – None"
),
) )
deliverable_type: str = Field(..., description="Тип сдаваемого материала") deliverable_type: str = Field(
grading_hints: List[str] = Field( ...,
description="Что нужно сдать: отчёт, код, презентация и т.п.",
)
grading_hints: List[str] | None = Field(
default_factory=list, default_factory=list,
description=( description="Критерии оценки, которые явно названы в тексте",
"Ключевые критерии оценки, перечисленные в тексте. " )
"Если не найдено – пустой список"
def run(raw_text: str) -> None:
output_parser = PydanticOutputParser(pydantic_object=AssignmentCard)
template = PromptTemplate(
template=(
"Прочитай описание учебного задания и заполни все поля карточки.\n\n"
"Описание:\n{raw_text}\n\n"
"Верни ответ строго в JSON без лишних пояснений.\n"
"{format_instructions}"
), ),
input_variables=["raw_text"],
partial_variables={
"format_instructions": output_parser.get_format_instructions()
},
) )
model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
def build_chain() -> PromptTemplate: chain = template | model | output_parser
"""Создаёт цепочку Prompt → LLM → Pydantic парсер."""
parser = PydanticOutputParser(pydantic_object=AssignmentCard)
prompt_template = ( card: AssignmentCard = chain.invoke({"raw_text": raw_text})
"Ниже приведено описание задания от преподавателя. "
"Ваша задача – извлечь из него следующую информацию:\n" print("Валидированный объект:")
"- title: название задачи\n" print(card.model_dump())
"- subject: предмет/область знаний\n"
"- deadline_hint: указание срока сдачи (если есть)\n" print("\nСводка:")
"- deliverable_type: что сдать (отчёт, код, презентация и т.д.)\n" print(
"- grading_hints: список критериев оценки\n\n" f"Задание «{card.title}» по теме «{card.subject}». "
"Ответ должен быть строго в формате JSON, соответствующем модели " f"Сдать: {card.deliverable_type}. "
f"{AssignmentCard.__name__}.\n" f"Дедлайн: {card.deadline_hint or 'не указан'}. "
"{format_instructions}\n\n" f"Оценивается: {', '.join(card.grading_hints) if card.grading_hints else 'критерии не указаны'}."
"Текст задания:\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__": if __name__ == "__main__":
main() sample = (
"Сдайте к пятнице мини-отчёт по LangChain: 2 страницы, упор на агентов. "
"Оценка: за полноту и за пример кода."
)
run(sample)