Обновить solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/solution.py
This commit is contained in:
+45
-78
@@ -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)
|
||||||
Reference in New Issue
Block a user