Реализация AI-извлечения ключевых тезисов из документа в мобильном приложении
Извлечение тезисов отличается от суммаризации: не «перескажи короче», а «вытащи конкретные утверждения, которые автор хочет доказать». Для научной статьи — гипотезы и выводы. Для договора — ключевые обязательства сторон. Для отчёта — рекомендации и метрики.
Это задача на понимание структуры документа, и к ней нужен другой промпт.
Загрузка документа на мобильном клиенте
Источники документов в мобильном приложении — PDF из UIDocumentPickerViewController, фото через PHPickerViewController, текст из буфера обмена или URL.
PDF требует извлечения текста до передачи в LLM. На iOS — PDFKit:
import PDFKit
func extractText(from url: URL) -> String {
guard let document = PDFDocument(url: url) else { return "" }
return (0..<document.pageCount).compactMap { index in
document.page(at: index)?.string
}.joined(separator: "\n\n")
}
PDFKit не распознаёт текст в сканированных PDF (изображения). Для сканов нужен OCR — Vision.VNRecognizeTextRequest или облачный Google Document AI. Это отдельный этап пайплайна.
На Android — PdfRenderer для рендеринга страниц в Bitmap, затем ML Kit Text Recognition для OCR, либо библиотека itextpdf/pdfbox-android для нативного извлечения текста из цифровых PDF.
Промпт для извлечения тезисов
Промпт — самое важное здесь. «Выдели ключевые мысли» даст суммаризацию. Для тезисов нужнее структурированный вывод:
You are an expert document analyst. Extract the key theses from the document.
A thesis is a specific, arguable claim the author makes — not a topic or summary.
Return JSON:
{
"theses": [
{
"text": "exact or closely paraphrased thesis statement",
"location": "section or paragraph reference",
"type": "hypothesis|conclusion|recommendation|fact|argument",
"confidence": 0.0-1.0
}
],
"document_type": "research|contract|report|article|other"
}
Limit: 5-10 most important theses only.
type — важное поле. Для договора интересны только obligation и condition, для научной статьи — hypothesis и conclusion. Фильтрация по type на клиенте позволяет показывать релевантное для конкретного use-case.
struct Thesis: Codable {
let text: String
let location: String
let type: ThesisType
let confidence: Float
}
enum ThesisType: String, Codable {
case hypothesis, conclusion, recommendation, fact, argument, obligation
}
Отображение: аннотации в документе
Тезис ценнее, если привязан к конкретному месту в документе. На iOS — PDFAnnotation для подсветки соответствующего фрагмента.
func highlightThesis(_ thesis: Thesis, in document: PDFDocument) {
guard let page = findPage(for: thesis.location, in: document) else { return }
let annotation = PDFAnnotation(
bounds: findBounds(for: thesis.text, on: page),
forType: .highlight,
withProperties: nil
)
annotation.color = colorForType(thesis.type)
annotation.contents = thesis.text
page.addAnnotation(annotation)
}
func colorForType(_ type: ThesisType) -> UIColor {
switch type {
case .conclusion: return .systemGreen.withAlphaComponent(0.4)
case .hypothesis: return .systemBlue.withAlphaComponent(0.4)
case .recommendation: return .systemOrange.withAlphaComponent(0.4)
default: return .systemYellow.withAlphaComponent(0.4)
}
}
Поиск bounds для текста на PDF-странице — через page.findString(_:withOptions:). Работает для цифровых PDF; для сканов нужны координаты из OCR.
Работа с большими документами
Договор на 50 страниц = ~60k токенов. Это влезает в контекст gpt-4o, но дорого и медленно. Умнее — сначала выделить структуру документа (заголовки, разделы), затем обрабатывать каждый раздел отдельно и агрегировать тезисы.
func extractThesesFromLargeDocument(_ text: String) async throws -> [Thesis] {
let sections = splitBySections(text) // разбивка по паттернам заголовков
var allTheses = [Thesis]()
for section in sections {
guard section.content.count > 200 else { continue } // пропускаем оглавление и пустые разделы
let theses = try await extractTheses(from: section.content, sectionTitle: section.title)
allTheses.append(contentsOf: theses)
}
// Дедупликация похожих тезисов через embeddings similarity
return deduplicate(allTheses)
}
Дедупликация важна: разные разделы документа могут повторять одну мысль. Простая дедупликация — по Jaccard-сходству текста, более точная — по cosine similarity эмбеддингов.
Ориентиры по срокам
Базовое извлечение тезисов из текстового документа — 3–5 дней. Полный пайплайн с PDF-парсингом, OCR для сканов, аннотациями в документе и обработкой больших файлов — 2–3 недели.







