сырой текст задания → плоская карточка: README.md
This commit is contained in:
+99
-58
@@ -1,89 +1,130 @@
|
|||||||
# Task Parser – “Raw Text → Flat Card”
|
# Сырой текст задания → плоская карточка
|
||||||
|
|
||||||
## 📖 Описание
|
## Описание проекта
|
||||||
|
|
||||||
`task_parser.py` — это модуль, который принимает **неформальное описание задания** (строку или короткий абзац) и преобразует его в структурированный объект `TaskCard`.
|
В рамках курса по созданию ассистента для учебного процесса данная программа принимает **неформальное описание задачи** (например, сообщение преподавателя в чате или короткий абзац из сайта) и преобразует его в структурированный объект `TaskCard`.
|
||||||
Полученный объект содержит только те поля, которые нужны дальше в пайплайне: название задачи, предмет, подсказки по дедлайну, тип сдачи и указания по оценке. Всё это делается без диалога с моделью – один запрос → один ответ.
|
Полученный объект содержит ключевые поля, которые можно использовать дальше в пайплайне: фильтрацию, хранение, передачу другим модулям.
|
||||||
|
|
||||||
## 🚀 Установка
|
## Стек технологий
|
||||||
|
|
||||||
|
- **Python** 3.10+
|
||||||
|
- **langchain-core**, **langchain-openai** – взаимодействие с LLM
|
||||||
|
- **pydantic** – типизация и валидация выходных данных
|
||||||
|
- **python-dotenv** (необязательно) – загрузка переменных окружения
|
||||||
|
|
||||||
|
## Установка зависимостей
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Создайте виртуальное окружение (рекомендуется)
|
# Создайте виртуальное окружение (рекомендовано)
|
||||||
python -m venv .venv
|
python -m venv .venv
|
||||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||||
|
|
||||||
# Установите зависимости
|
# Установите пакеты
|
||||||
pip install langchain-core langchain-openai pydantic python-dotenv
|
pip install langchain-core langchain-openai pydantic python-dotenv
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Важно**
|
> **Важно**
|
||||||
> * `OPENAI_API_KEY` (или другой ключ для выбранной модели) должен быть в переменных окружения.
|
> Для работы с LLM необходимо задать ключ API. Самый простой способ – создать файл `.env` в корне проекта:
|
||||||
> * Можно хранить его в файле `.env` рядом с проектом:
|
|
||||||
|
|
||||||
```dotenv
|
```dotenv
|
||||||
# .env
|
OPENAI_API_KEY=sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
OPENAI_API_KEY=sk-xxxxxxxxxxxxxx
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📦 Как запустить
|
или экспортировать переменную окружения напрямую:
|
||||||
|
|
||||||
### 1️⃣ Вариант через REPL / Jupyter
|
|
||||||
|
|
||||||
```python
|
|
||||||
from task_parser import parse_task_text
|
|
||||||
|
|
||||||
raw = """
|
|
||||||
Напиши мини‑отчёт по LangChain: проработай пример с ChatOpenAI, покажи выводы и сделай выводы о производительности. Срок сдачи – 3 дня после получения задания. Оценка будет по качеству кода и полноте отчёта.
|
|
||||||
"""
|
|
||||||
|
|
||||||
card = parse_task_text(raw)
|
|
||||||
print(card.json(indent=2))
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2️⃣ Через командную строку
|
|
||||||
|
|
||||||
Добавьте в `task_parser.py` (или создайте отдельный скрипт) функцию `main()`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
raw = " ".join(sys.argv[1:])
|
|
||||||
card = parse_task_text(raw)
|
|
||||||
print(card.json(indent=2))
|
|
||||||
```
|
|
||||||
|
|
||||||
Тогда можно вызвать так:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python task_parser.py "Напиши мини‑отчёт по LangChain: проработай пример с ChatOpenAI, покажи выводы и сделай выводы о производительности. Срок сдачи – 3 дня после получения задания."
|
export OPENAI_API_KEY="sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📄 Пример использования
|
## Как запустить
|
||||||
|
|
||||||
|
Файл `task.py` содержит всю логику.
|
||||||
|
Пример использования в интерактивном режиме:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from task_parser import parse_task_text
|
# task_demo.py
|
||||||
|
from task import TaskCard, parser, llm # импортируем готовый LLM и парсер
|
||||||
|
|
||||||
raw = """
|
raw_text = """
|
||||||
Создать презентацию по теме «Введение в LangChain». Включить примеры кода, графики и выводы.
|
Нужно написать отчёт по теме «Алгоритмы сортировки». Сдача до следующей недели. Оценка будет по структуре и корректности кода.
|
||||||
Срок: до пятницы. Оценка будет зависеть от оригинальности идей и качества оформления слайдов.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
card = parse_task_text(raw)
|
# Формируем запрос к модели
|
||||||
|
prompt_template = parser.get_prompt()
|
||||||
|
prompt = prompt_template.format(input=raw_text)
|
||||||
|
|
||||||
# card – это объект TaskCard
|
# Получаем ответ от LLM
|
||||||
print(card.title) # "Создать презентацию по теме «Введение в LangChain»"
|
response = llm.invoke(prompt)
|
||||||
print(card.subject) # "LangChain"
|
|
||||||
print(card.deadline_hint) # "до пятницы"
|
# Парсим в объект TaskCard
|
||||||
print(card.deliverable_type) # "презентация"
|
task_card = parser.parse(response)
|
||||||
print(card.grading_hints) # ["оригинальность идей", "качество оформления слайдов"]
|
print(task_card.json(indent=2))
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📚 Что дальше
|
Запуск:
|
||||||
|
|
||||||
- **Фильтрация**: можно отфильтровать задачи по предмету или типу сдачи.
|
```bash
|
||||||
- **Сохранение**: сериализовать в JSON и хранить в базе данных.
|
python task_demo.py
|
||||||
- **Пайплайн**: передать `TaskCard` следующему шагу, например, генератору чек‑листов.
|
```
|
||||||
|
|
||||||
---
|
Вывод будет примерно таким:
|
||||||
|
|
||||||
*Если возникнут вопросы – откройте issue или свяжитесь с автором проекта.*
|
```json
|
||||||
|
{
|
||||||
|
"title": "Отчёт по алгоритмам сортировки",
|
||||||
|
"subject": "Алгоритмы сортировки",
|
||||||
|
"deadline_hint": "до следующей недели",
|
||||||
|
"deliverable_type": "отчёт",
|
||||||
|
"grading_hints": [
|
||||||
|
"структура",
|
||||||
|
"корректность кода"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Пример использования в пайплайне
|
||||||
|
|
||||||
|
```python
|
||||||
|
# pipeline.py
|
||||||
|
from task import TaskCard, parser, llm
|
||||||
|
|
||||||
|
def process_task(raw_description: str) -> TaskCard:
|
||||||
|
prompt = parser.get_prompt().format(input=raw_description)
|
||||||
|
response = llm.invoke(prompt)
|
||||||
|
return parser.parse(response)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raw = "Написать презентацию по теме «Машинное обучение» до 15.09."
|
||||||
|
card = process_task(raw)
|
||||||
|
print(card.title) # Презентация по теме «Машинное обучение»
|
||||||
|
```
|
||||||
|
|
||||||
|
## Что делает код
|
||||||
|
|
||||||
|
1. **`TaskCard`** – Pydantic‑модель, описывающая структуру карточки задания.
|
||||||
|
2. **`PydanticOutputParser`** – обёртка, которая формирует запрос к LLM и парсит JSON‑ответ в `TaskCard`.
|
||||||
|
3. Внутри `task.py` создаётся объект LLM (`ChatOpenAI`) с использованием ключа из переменных окружения.
|
||||||
|
4. При вызове `parser.parse()` модель генерирует ответ в формате, совместимом с Pydantic, и парсер преобразует его в экземпляр `TaskCard`.
|
||||||
|
|
||||||
|
## Тесты
|
||||||
|
|
||||||
|
Для быстрой проверки можно написать простые unit‑тесты:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install pytest
|
||||||
|
pytest tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
(В проекте пока нет тестов – их добавьте по необходимости.)
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
| Вопрос | Ответ |
|
||||||
|
|--------|-------|
|
||||||
|
| Как изменить модель? | Измените параметры `ChatOpenAI` в `task.py`. |
|
||||||
|
| Что делать, если LLM не возвращает валидный JSON? | Попробуйте добавить в шаблон более строгие инструкции или использовать `parser.get_prompt()` с параметром `strict=True`. |
|
||||||
|
| Можно ли использовать другую LLM (например, Gemini)? | Да – замените импорт и объект `ChatOpenAI` на соответствующий клиент. |
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
MIT © 2026
|
||||||
Reference in New Issue
Block a user