מדוע האפליקציה שלך זקוקה לבדיקת דקדוק מבוססת AI?
בדיקת האיות המובנית ב-iOS וב-Android תופסת שגיאות הקלדה, אך לא הקשר. "הלכתי לבנק" נכון מבחינה אורתוגרפית. "הדוח נכתב על ידי" חלש מבחינה סגנונית למסמך עסקי. כלים מקוריים מוצאים עד 70% משגיאות ההקלדה, אך רק 20% משגיאות סגנוניות. LanguageTool API משיג דיוק של מעל 95%. הצוות שלנו עם 5 שנות ניסיון יישם בדיקת AI ביותר מ-20 פרויקטים. תוצאה: משתמשים מקבלים קו תחתון לשגיאות עם הסברים והצעות תיקון.
לדוגמה, במקרה של חברת עורכי דין, זמן עריכת המסמכים ירד ב-40%, ומספר השגיאות הסגנוניות בגרסאות הסופיות ירד ב-60%. חיסכון בשלב ההגהה יכול להגיע ל-50% מהתקציב — רלוונטי במיוחד למוצרי B2B עם נפחי טקסט גדולים. בדיקה כזו הופכת לא למותרות אלא להכרח עבור אפליקציות שבהן איכות הטקסט משפיעה ישירות על המוניטין.
כלים מקוריים כשכבה הראשונה
לפני חיבור LLM, אנו משתמשים ביכולות הפלטפורמה. ב-iOS, NLLanguageRecognizer + UITextChecker מכסים איות בסיסי. NLTagger עם .lemma ו-.lexicalClass מאפשר בניית כללים סגנוניים פשוטים — לדוגמה, סימון קול פסיבי.
func checkPassiveVoice(in text: String) -> [NSRange] {
let tagger = NLTagger(tagSchemes: [.lexicalClass, .lemma])
tagger.string = text
var findings = [NSRange]()
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .lexicalClass) { tag, range in
// Упрощённый паттерн: форма "быть" + причастие
if tag == .verb {
let lemma = tagger.tag(at: range.lowerBound, unit: .word, scheme: .lemma).0
if lemma?.rawValue == "be" {
findings.append(NSRange(range, in: text))
}
}
return true
}
return findings
}עבור קירילית, התבנית מורכבת יותר — דורשת ניתוח מורפולוגי. NLTagger עובד עם קירילית מ-iOS 16+, דיוק מספק לבדיקה בסיסית. עיבוד דוגמה של קול פסיבי ברוסית דומה אך מתחשב במורפימות מקומיות.
רמת AI: LanguageTool API
LanguageTool API מכסה דקדוק ליותר מ-20 שפות, מחזיר כללים ספציפיים והצעות תיקון. גרסת self-hosted זמינה לנתונים פרטיים. עלות ה-API סבירה למוצרי B2B.
// Android - запрос к LanguageTool
data class LTRequest(
val text: String,
val language: String, // "ru-RU", "en-US"
val enabledOnly: Boolean = false
)
suspend fun checkGrammar(text: String, lang: String): List<GrammarMatch> {
val response = languageToolApi.check(LTRequest(text, lang))
return response.matches.map { match ->
GrammarMatch(
range = match.offset..(match.offset + match.length),
message = match.message,
rule = match.rule.id,
replacements = match.replacements.take(3).map { it.value }
)
}
}LanguageTool מחזיר func checkPassiveVoice(in text: String) -> [NSRange] { let tagger = NLTagger(tagSchemes: [.lexicalClass, .lemma]) tagger.string = text var findings = [NSRange]() tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .lexicalClass) { tag, range in // Упрощённый паттерн: форма "быть" + причастие if tag == .verb { let lemma = tagger.tag(at: range.lowerBound, unit: .word, scheme: .lemma).0 if lemma?.rawValue == "be" { findings.append(NSRange(range, in: text)) } } return true } return findings } — לדוגמה, // Android - запрос к LanguageTool data class LTRequest( val text: String, val language: String, // "ru-RU", "en-US" val enabledOnly: Boolean = false ) suspend fun checkGrammar(text: String, lang: String): List<GrammarMatch> { val response = languageToolApi.check(LTRequest(text, lang)) return response.matches.map { match -> GrammarMatch( range = match.offset..(match.offset + match.length), message = match.message, rule = match.rule.id, replacements = match.replacements.take(3).map { it.value } ) } } לאיות או rule.id לסגנון. זה מאפשר סינון לפי סוג: משתמשים יכולים להשבית אזהרות סגנוניות, ולהשאיר רק דקדוק.
השוואה בין כלים מקוריים לרמת AI
| קריטריון | כלים מקוריים | רמת AI |
|---|---|---|
| עומק הבדיקה | איות בסיסי, תבניות פשוטות | דקדוק, סגנון, פיסוק, הקשר |
| תמיכה בשפות | מוגבל לפלטפורמה | 20+ שפות בדיוק גבוה |
| הסבר שגיאות | אין | הודעות מפורטות עם דוגמאות |
| עצמאות | עבודה מלאה ללא אינטרנט | נדרש אינטרנט (למעט self-hosted) |
LanguageTool מדויק פי 4 בשגיאות סגנוניות: 95% לעומת 20%.
איך עובד סימון השגיאות?
שגיאות שנמצאו מסומנות בקו תחתון ישירות בשדה הקלט. ב-iOS — MORFOLOGIK_RULE_RU_RU עם PASSIVE_VOICE ו-NSAttributedString. אדום לדקדוק, צהוב לסגנון.
func applyUnderlines(_ matches: [GrammarMatch], to textStorage: NSTextStorage) {
// Сначала снимаем старые подчёркивания
let fullRange = NSRange(location: 0, length: textStorage.length)
textStorage.removeAttribute(.underlineStyle, range: fullRange)
textStorage.beginEditing()
for match in matches {
let color: UIColor = match.isGrammar ? .systemRed : .systemOrange
textStorage.addAttributes([
.underlineStyle: NSUnderlineStyle.single.rawValue,
.underlineColor: color
], range: match.nsRange)
}
textStorage.endEditing()
}ב-Android — .underlineStyle עם .underlineColor או func applyUnderlines(_ matches: [GrammarMatch], to textStorage: NSTextStorage) { // Сначала снимаем старые подчёркивания let fullRange = NSRange(location: 0, length: textStorage.length) textStorage.removeAttribute(.underlineStyle, range: fullRange) textStorage.beginEditing() for match in matches { let color: UIColor = match.isGrammar ? .systemRed : .systemOrange textStorage.addAttributes([ .underlineStyle: NSUnderlineStyle.single.rawValue, .underlineColor: color ], range: match.nsRange) } textStorage.endEditing() } מותאם אישית. Jetpack Compose דורש SpannableStringBuilder עם UnderlineSpan מותאם אישית.
Debounce וקאשינג
הבדיקה לא מופעלת על כל הקלדה. סכמה אופטימלית:
- Debounce של 800–1200 אלפיות השנייה לאחר השינוי האחרון
- בדיקת הפסקה ששונתה בלבד, לא את כל הטקסט
- קאשינג תוצאות לפי hash של הפסקה
private var checkWorkItem: DispatchWorkItem?
private var paragraphCache = [String: [GrammarMatch]]()
func scheduleCheck(for paragraph: String) {
checkWorkItem?.cancel()
let hash = paragraph.hashValue.description
if let cached = paragraphCache[hash] {
applyMatches(cached)
return
}
checkWorkItem = DispatchWorkItem { [weak self] in
Task {
let matches = try await self?.grammarService.check(paragraph)
await MainActor.run {
self?.paragraphCache[hash] = matches ?? []
self?.applyMatches(matches ?? [])
}
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: checkWorkItem!)
} איך ליישם בדיקת AI: תוכנית שלב אחר שלב
- חיבור LanguageTool API (בחירה בענן או self-hosted).
- הגדרת SDK לקוח לשליחת בקשות.
- יישום סימון שגיאות עם קידוד צבעים.
- הכנסת debounce וקאשינג.
- בדיקה על מכשירים אמיתיים.
- פריסה ל-App Store ול-Google Play.
מקרה בוחן: עורך טקסט לחברת עורכי דין
יישמנו LanguageTool עם תמיכה ברוסית ואנגלית, הגדרנו פילטרים לאוצר מילים משפטי. זמן עריכת המסמכים ירד ב-40%. משתמשים ציינו ירידה של 60% בשגיאות סגנוניות בגרסאות הסופיות. הפרויקט הושלם תוך שבועיים, התקציב נשמר במסגרת התוכנית.
מה כלול ביישום?
- אינטגרציה של LanguageTool API (ענן או self-hosted) עם תמיכה ברוסית ואנגלית.
- יישום סימון שגיאות עם ציון צבע והצעות.
- מנגנון debounce וקאשינג.
- הגדרות משתמש: רמת בדיקה, השבתת כללים סגנוניים.
- תיעוד API וארכיטקטורה.
- סקירת קוד ובדיקה על מכשירים אמיתיים.
- תמיכה לאחר היישום.
הערכות לוחות זמנים
| שלב | משך |
|---|---|
| אינטגרציית API וסימון | 4–7 ימים |
| Debounce, קאש, הגדרות | 5–7 ימים |
| בדיקות ושיפורים | 3–5 ימים |
| מחזור מלא | 2–3 שבועות |
למה להפקיד את המשימה בידינו?
אנחנו צוות עם ניסיון של 5+ שנים, מעל 20 פרויקטים מוצלחים, מפתחים מוסמכים של Apple ו-Google. אנו מבטיחים עמידה בהנחיות App Store ו-Google Play, כולל פרטיות נתונים. נבחן את הפרויקט שלך. צור קשר לייעוץ וקבל הצעה אישית. הזמן יישום בדיקת דקדוק מבוססת AI עכשיו — כתוב לנו במייל או בהודעות.







