1 419
订阅者
无数据24 小时
+27 天
-630 天
帖子存档
1 419
📌 למה עדיין קשה לקבל Code Review מסוכני קוד
יש לי פרומפט קבוע ל Code Review שנראה ככה:
---
description: Review attached code
---
Review the provided code change.
Explain:
- What the code does
- Is the implementation complete
- What other alternatives can solve the same problem? Why was the current alternative chosen?
Then Code Review, focus on:
- Correctness - Bugs and logic errors
- Performance - are there newly introduced regressions? how will the feature work with production data?
- Scale
- Code architecture
- Coding best practices
- Security issues
- Error handling gaps
- Handled and unhandled edge cases
Test Coverage
- Examine existing tests
- Search for untested paths or incomplete tests, specifically tests that only verify the happy path
- Find if the untested code could break in ways we didn't consider
Multi Threaded or Concurrency
- We're writing a web application whose code runs from both user facing web frontend and background workers
- Evaluate code for multi threaded and concurrency anti patterns or possible hidden bugs, deadlocks, duplicate execution, starvation
- Evaluate the need for transactions only where absolutely needed due to the performance penalty of locking.
Security
- We're writing a web application performing in possible hostile environment
- Verify authorization is checked on every route
- Verify user input is sanitized before used
Finally look for AI anti patterns:
- Dead code
- Duplicated code or logic
** DO NOT RUN ANY CODE NOR DO NOT INTERACT WITH THE SYSTEM IN ANY WAY **
This is a static analysis code review running on an isolated machine.
כן זה ארוך אבל מעניין. תנו אותו למודל חכם (אופוס או דיפסיק פרו) ותמיד הוא ימצא על מה להתלונן. תקנו דבר אחד ותפעילו שוב ואתם תראו שתקבלו רשימה קצת שונה של בעיות. ככל שממשיכים לתקן רשימת הבעיות משתנה. הפעלה עם מודל אחר מחזירה רשימת בעיות קצת אחרת.
אפשר גם לשנות את הפרומפט ולייצר כמה סוכנים, אחד עבור ביצועים, עוד אחד לאבטחת מידע ושלישי לאיכות הקוד. אבל זה לא משנה את הבעיה המהותית:
1. אי אפשר לקבל רשימה מקיפה של כל הבעיות - כל הפעלה וכל תיקון חושפים בעיות נוספות.
2. בעיות מסוימות מדורגות "חשובות" אבל למעשה הן לא חשובות בכלל. לפעמים המודל נטפל לדברים שאנחנו יודעים שהם בסדר אבל בגלל שהם שם הוא לא מצליח לראות בעיות אמיתיות. "תיקון" אותם דברים שהם לגמרי בסדר פתאום גורם למודל להציף בעיות אחרות כן חשובות.
3. הבעיות שהסוכן מוצא עשויות לתת תחושה שקרית של בטחון - "וואו הוא מצא דברים כל כך מתוחכמים בטוח הוא היה רואה את הדברים הבסיסיים והפשוטים ששבורים בקוד" זו לא תמיד מסקנה נכונה כשמדובר בסוכני קידוד.
סך הכל קחו את הפרומפט תהנו ממנו ואני מקווה שהוא יעזור גם לכם לשפר את הקוד לפני שממזגים PR. אבל שימו לב שאנחנו עדיין רחוקים מתהליך Code Review אמין.1 419
📌 עצה גרועה שעובדת
עצה גרועה שעובדת היא הרבה יותר גרועה מעצה גרועה שלא עובדת.
לא מזמן העברתי את ה DNS של האתר לקלאודפלייר ועל הדרך נכנסתי לפרוקסי שלהם כך שעכשיו אנחנו מוגנים ממתקפות DDoS. לא יודע כמה זה אפקטיבי הפעם האחרונה שהיתה מתקפה על האתר זה היה מילדים בטורקיה באזור שנת 2015 בעקבותיה שמתי את fail2ban וזה די פתר את כל הבעיות האלה, אבל לא משנה נותנים לך תיקח וממילא זה בחינם אז נרשמתי.
כשבאתי להעלות גרסה חדשה של התוכנה דרך ה Github Action שהגדרתי ההעלאה נכשלה בגלל Network Error. ברור מה הבעיה - הקונטיינר שמעלה גרסה נתקע בפרוקסי של קלאודפלייר ולא יכול להגיע לשרת. בשביל להגיע לשרת הוא יצטרך את כתובת ה IP האמיתית שלו, שהיא כאמור מוסתרת מאחורי קלאודפלייר בשביל להגן ממתקפות DDoS.
גיטהאב, שכמובן דוחפים את כולנו לדבר עם AI-ים כל היום הוסיפו כפתור Explain שאפשר ללחוץ עליו כש Action נכשל כדי לראות מה קרה. אז לחצתי. קלוד הסביר שהבעיה היא שהוא מנסה להתחבר ל IP6 של השרת אז נתתי לו רמז שזה התחיל רק מאז שנרשמתי לקלאודפלייר ואז הוא התאפס:
That's the key insight. When Cloudflare proxy (orange cloud 🟠) is enabled, SSH traffic breaks entirelyאין לך מה לעבור ל IP4 אתה צריך את התיקון האמיתי. ומה התיקון האמיתי? תוסיף רשומת DNS חדשה בשם לדוגמה deploy.tocode.co.il בה תפרסם את כתובת ה IP האמיתית של השרת כדי שהקונטיינר של גיטהאב ידע מה הכתובת ויוכל להעלות גרסה. רואים כבר את הבעיה? אני משלם* לקלאודפלייר כדי שיסתירו את כתובת ה IP שלי ובשורה הבאה ב DNS חושף לעולם את אותה כתובת שרציתי להסתיר. ומי יגן עליי מ DDoS-ים ? קלוד? שיהיה בהצלחה עם זה. (משלם זו מילה גדולה בהתחשב בזה שהפרוקסי של קלאודפלייר הוא בחינם, אבל נשים את זה בצד). עכשיו קלוד יודע את זה. וכן גם "יודע" זו מילה גדולה פה. כשאני ממשיך את השיחה לקלוד אין בעיה להסביר שההצעה שלו מטופשת. אבל זה יקרה רק אחרי שאני אכוון אותו לשם. בלי לדעת לאן אנחנו הולכים שום מכונה לא תיקח אותנו לשם.
1 419
📌 חשוב לא שווה מעניין
בתקופה שאנטרופיק לא הפסיקו לדבר על MCP זה היה המושג שעלה הכי הרבה בשיחות עם לקוחות. איך בונים MCP? האם אני צריך MCP? איך בדיוק זה עובד? מה ההבדל בין Resource ל Tool? היו שם הרבה כפתורים, כולם התלהבו מהטכנולוגיה וזה היה נראה כאילו אם רק תבין MCP תצליח לקבל תוצאות הרבה יותר טובות מסוכנים חכמים.
אבל זה היה רק מסך עשן.
רוב מה שצריך לדעת על MCP מסתכם במשפט "ואפשר לכתוב Tools בעצמנו כדי להרחיב את VS Code". משפט כזה שם את ה MCP במקום שלו, אחרי ו החיבור. שימוש בכלים הוא המבנה הבסיסי של סוכנים חכמים. מרגע שהבנו מה זה שימוש בכלים ואיך זה עובד, התחביר של איך לבנות כלים נוספים הוא בסך הכל עוד תחביר לא חשוב. ממילא AI יכול לבנות שרת MCP יותר מהר מאיתנו.
חשוב - דברים שיישארו איתנו לאורך זמן, עקרונות, שיטות עבודה, פריימוורק איך להבין את העולם. דברים שלוקח הרבה זמן ללמוד ואחרי שהבנת אי אפשר לשכוח.
מעניין - כלי חדש, טיפ שישנה לכם את החיים, שלושה שרתי MCP שאי אפשר לחיות בלעדיהם, מודל חדש, כפתור שאף אחד לא מכיר, זכרון אוטומטי.
כשלא בטוחים חפשו את החשוב.
1 419
📌 כפול עשר
המושג 10x programmer הומצא הרבה לפני ש AI כתב את כל הקוד. הוא בא לתאר את התופעה שיש מפתחים הרבה יותר יעילים שמקפיצים את הארגון קדימה ולפעמים מפתח או מפתחת כאלה יכולים להיות שווים לארגון אפילו יותר מעשרה אחרים. אותם מפתחי 10x כמובן לא מצטיינים בגלל שהם מקלידים מהר יותר (יש גבול כמה מהר אפשר להקליד, וממילא מהירות הקלדה אף פעם לא היתה הבעיה). התכונות שהפכו אותם ליעילים היו חדות חשיבה, יכולת לראות דברים שאחרים לא ראו, יכולת קבלת החלטות, בחירת הטכנולוגיה הנכונה, בניית מערכת כך שבאגים יקרו פחות או יהיו קלים יותר לאיתור.
מדידת ביצועי 10x היתה חייבת להתבצע לאורך זמן. הרבה אנשים יכלו להיות כפול עשר יותר מהירים מאחרים במשימה ספציפית או באמצעות קיצורי דרך אבל בתוכנה סופם של באגים נסתרים להתגלות ולאורך זמן קיצורי דרך רק מאריכים את המסלול. בתוך הדיון הזה אפשר היה לאפיין 4 סוגים של מפתחים שנראים מאוד פרודוקטיביים אבל בעצם הם לא:
1. מעיין הקוד - אלה שכותבים עוד ועוד קוד. אם היית מודד אותם לפי שורות קוד הם בקלות כותבים כפול עשר שורות מכל האחרים, אבל שורות קוד אינן המדד לתוכנה טובה.
2. סוגרי הטיקטים - אלה שתמיד ימצאו עוד משימה קלה לפתור ומסיימים את תקופת המדידה עם כפול 10 טיקטים שנפתרו מכל השאר, כל זה בלי לעשות דבר אחד חשוב.
3. הארכיטקטים - שכל היום כותבים ומוחקים ועושים Refactor ובונים ארכיטקטורות שיוכלו להתמודד עם כל צרה שלא תבוא אבל אף פעם לא מגיעים לפרודקשן, או שמגיעים רק כדי לגלות שכל המבנה עמד על יסודות רעועים. אם המדד להצלחה הוא כמה שינויים עשית בפרויקט כל שבוע הארכיטקטים לוקחים את גביע הכפול עשר בלי להתבלבל.
4. הכמעט עובד - הם מתקתקים פיצ'רים וזה באמת נראה עובד אבל יש רק מקרה קצה אחד שעדיין לא הגיעו אליו או כמה בעיות פרודקשן קטנות. האמת היא שקיצורי הדרך שהם לוקחים לא מאפשרים להם להגיע ל 100%. הם אולי בונים כפול עשר יותר פיצ'רים אבל מכניסים כפול 100 יותר באגים.
היום מפתחי הכפול עשר האלה נעזרים ב AI כדי להיות כפול 100 יותר ״פרודוקטיביים״. הם כותבים יותר קוד ממה שאפשר לקרוא, פותחים וסוגרים יותר טיקטים ממה שאפשר לעקוב, משנים את הפרויקט מקצה לקצה כל שבוע ומציפים אותנו בפיצ'רים שכמעט עובדים חוץ מכמה בעיות קטנות. ואיכות המוצר? שביעות רצון המשתמשים? תוכנות שעובדות? זה יחכה לאחרי הריליס.
1 419
📌 דברים שעדיין קשים
ההתמכרות ל AI נותנת למפתחים ומנהלים הרגשה כאילו Coding Is Solved. זאת מחשבה נחמדה שלא מתחברת עם המציאות. כל המשימות האלה של פיתוח תוכנה עדיין קשות ואולי אפילו קשות יותר ממה שהיו בעבר:
1. להבין איך מערכת עובדת ואיך היא יכולה להישבר.
2. לראות איזה שינויים צפויים בדרישות הלקוח ואיך הקוד יסתגל לאותם שינויים.
3. לראות איזה מימוש מתאים לדרישות הלקוח, ואיזה רק נראה נכון אבל בעצם מפספס נקודות חשובות.
4. לבחור מבין מספר פתרונות את הפתרון הכי יעיל, פשוט ומתאים למשימה.
5. לשאול את השאלות הנכונות.
6. לבחור סביבת Deployment ולבנות תהליך עבודה שמביא מוצר מרעיון למשתמשים.
7. לבנות תהליכי עבודה שיוצרים חיכוך איפה שצריך ומצמצמים אותו איפה שאפשר.
8. לראות את האבסטרקציה שמאפשרת לבנות את כל המערכת.
9. לבצע פשרות כואבות גם כשכולם רוצים את הכל.
זה מצוין שאנחנו כותבים HTML-ים הרבה יותר מהר מאי פעם. לא בגלל שזה פתר לנו את ה Coding, אלא פשוט בגלל שזה מאפשר לנו למצוא את הזמן להתרכז בדברים הקשים.
1 419
📌 כשהשיווק מחליף שיקול דעת
שיווק יתר מתחיל להיות בעיה כשהוא מחליף שיקול דעת. ובעולם התוכנה זה קורה כל הזמן.
כשכל התעשייה רצה אחרי Angular זה היה הפריימוורק שבחרנו לקוד חדש.
כשכל התעשייה רצה לכתוב XML-ים בילינו עשור בכתיבת מערכות ששולחות ומקבלות XML.
כשכל התעשייה התחילה לכתוב Micro Services עברנו בלי להתבלבל לכתוב Micro Services בענן.
מה שמשותף לכל הטרנדים שאני חוויתי הוא גרעין של אמת שפותר בעיה אמיתית שמתגלגל והופך להכרח ולאימוץ עיוור. השטן הוא בפרטים ולכן אסור לוותר על השאלות הקשות. אני לא יכול לקחת שיטת עבודה שעובדת בחברה אחרת ולאמץ אותה אחד לאחד כי המוצר שלי שונה, האנשים שלי שונים, התהליכים אצלי שונים, גודל החברה שונה. רק כשהבנו את זה הצלחנו להשתמש נכון ב JavaScript Frameworks, הפכנו את ה XML ל JSON והוספנו פרוטוקולי תקשורת מגוונים למערכות ואנחנו מאמצים Micro Services בצורה זהירה לפי מאפייני החברה.
קידוד בעזרת AI נמכר היום בתור Silver Bullet, בתור מוצר אחד שמתאים לכולם ופותר את כל הבעיות. ולא סתם AI אנחנו ממש מדייקים - קלוד קוד עם אופוס 4.7. אבל לקחת מוצר מדף מהפרסומת ולקוות שהוא יעבוד כמו בפרסומת זו לא אסטרטגיה טובה בעולם הפיתוח.
בואו נלמד מהעבר. כן אתם הולכים לעשות קידוד עם AI בשנים הקרובות אבל לא בטוח שזה יהיה קלוד קוד ולא בטוח שזה בכלל יהיה מודל של אנטרופיק. למעשה אף אחד לא יודע איך קידוד בסיוע AI הולך לעבוד ובטח שאין שום מוצר מדף שאפשר לשים שיתאים בדיוק לצוות שלכם.
עזבו את הפרסומת. קחו צעד אחורה והשקיעו את הזמן והמאמץ בבניית תהליך עבודה בסיוע AI שרלוונטי עבורכם. נסו:
1. לגוון במודלים ובסוכני הקידוד. שימו לב אם אפשר לעבור ביניהם ואיך.
2. לגוון בתהליכי העבודה, יום אחד לעבוד רק דרך הפרומפט, יום אחר מתוך ה IDE, לפעמים לשלב סוכן בענן.
3. לגוון בפיצ'רים, לבנות פיצ'ר ידנית ואז לשים בענף נפרד ואז לתת ל AI לממש אותו. לראות את ההבדלים. לשים לב לבחירות של ה AI ולמה זה קרה.
קלוד קוד זה לא פרסומת לג'ינס. הדרך להטמעה מוצלחת היא התאמה אישית של התהליך לארגון שלכם ולתהליכים שלכם.
1 419
📌 להתראות TypeVar
אם יש תחביר שאני שמח להיפרד ממנו בעולם זה TypeVar של פייתון. בסך הכל רציתי להגדיר פונקציה שמחזירה את מה שהיא קיבלה אבל פייתון עד גרסה 3.12 החליט שאני צריך להגדיר איתה גם משתנה גלובאלי. זה נראה ככה:
from typing import TypeVar
T = TypeVar("T")
def same(x: T) -> T:
return x
וכל זה רק בשביל שיהיה מה לכתוב אחרי הנקודותיים בתור הטיפוס של x.
החל מפייתון 3.12 אפשר לשכוח מכל הכאב ראש הזה ולאמץ תחביר שמזכיר את כתיב ה Generics של שפות אחרות:
def same[T](x: T) -> T:
return x
ולקבל את אותה תוצאה בדיוק.
וכן זה עובד גם עם יותר ממשתנה גנרי אחד:
def swap[T, S](x: T, y: S) -> tuple[S, T]:
return y, x
עדיין אולי תרצו את הכתיב הישן בשביל להגביל את הטיפוסים האפשריים של T בעזרת הפרמטרים של TypeVar או bound, אבל ל 90% מהמקרים הכתיב החדש נקי וקל יותר.1 419
📌 להתראות TypeVar
אם יש תחביר שאני שמח להיפרד ממנו בעולם זה TypeVar של פייתון. בסך הכל רציתי להגדיר פונקציה שמחזירה את מה שהיא קיבלה אבל פייתון עד גרסה 3.12 החליט שאני צריך להגדיר איתה גם משתנה גלובאלי. זה נראה ככה:
from typing import TypeVar
T = TypeVar("T")
def same(x: T) -> T:
return x
וכל זה רק בשביל שיהיה מה לכתוב אחרי הנקודותיים בתור הטיפוס של x.
החל מפייתון 3.12 אפשר לשכוח מכל הכאב ראש הזה ולאמץ תחביר שמזכיר את כתיב ה Generics של שפות אחרות:
def same[T](x: T) -> T:
return x
ולקבל את אותה תוצאה בדיוק.
וכן זה עובד גם עם יותר ממשתנה גנרי אחד:
def swap[T, S](x: T, y: S) -> tuple[S, T]:
return y, x
עדיין אולי תרצו את הכתיב הישן בשביל להגביל את הטיפוסים האפשריים של T בעזרת הפרמטרים של TypeVar או bound, אבל ל 90% מהמקרים הכתיב החדש נקי וקל יותר.1 419
else:
# Try skipping SRT words
found = False
for sahead in range(1, MAX_SKIPS + 1):
if sp + sahead < len(srt_flat):
if words_match(srt_flat[sp + sahead][0], ts_norms[tp]):
sp += sahead
found = True
break
if not found:
sp += 1
tp += 1
# Compute timestamps per entry
results = []
for entry in srt_entries:
ts_indices = entry_ts_map.get(entry["index"], [])
if ts_indices:
new_start = ts_words[ts_indices[0]]["ms"]
last_idx = ts_indices[-1]
if last_idx + 1 < len(ts_words):
new_end = ts_words[last_idx + 1]["ms"]
else:
new_end = ts_words[last_idx]["ms"] + 500
else:
new_start = None
new_end = None
results.append((entry["index"], new_start, new_end))
# Interpolate gaps
for i, (idx, start, end) in enumerate(results):
if start is None:
prev_match = next(
(results[j] for j in range(i - 1, -1, -1) if results[j][1] is not None),
None,
)
next_match = next(
(results[j] for j in range(i + 1, len(results)) if results[j][1] is not None),
None,
)
if prev_match and next_match:
old_prev = srt_entries[prev_match[0] - 1]["old_start_ms"]
old_next = srt_entries[next_match[0] - 1]["old_start_ms"]
old_curr = srt_entries[idx - 1]["old_start_ms"]
if old_next != old_prev:
frac = (old_curr - old_prev) / (old_next - old_prev)
else:
frac = 0.5
interp_start = int(prev_match[1] + frac * (next_match[1] - prev_match[1]))
interp_end = int(prev_match[2] + frac * (next_match[2] - prev_match[2]))
results[i] = (idx, interp_start, interp_end)
elif prev_match:
results[i] = (idx, prev_match[1], prev_match[2])
elif next_match:
results[i] = (idx, next_match[1], next_match[2])
return results
עכשיו אני מודה, לא קראתי את הקוד ואני לא מתכנן לקרוא אותו. לא בטוח שאוכל גם אם ארצה. זה לא קוד טוב. וזה בסדר, כי הקוד הלא טוב הזה מתאים לדרישות בשביל סקריפט חד פעמי.
הרבה פעמים בעולם האמיתי אנחנו כן רוצים קוד טוב כי קוד טוב ניתן להרחבה ואפשר להמשיך לתחזק אותו, זה אומר שנצטרך להיות יותר ספציפיים בהוראות ל AI - איזה קלאסים ליצור, איך לסדר את הקוד בקבצים, באיזה מקרי קצה רוצים לטפל, במה לא רוצים לטפל ומעדיפים לרסק את הסקריפט, מה השמות והאבסטרקציות שיגרמו לקוד להיות קריא.
בעולם האמיתי בעבודה עם AI הדיכוטומיה בין "עומק פיתוח וחשיבה הנדסית" לבין "קידוד עם AI" היא פשוט לא נכונה. ה AI פשוט לקח את רמת המימוש ומסוגל לבצע אותה מהר יותר בצורה אוטומטית. וזה כיף כי עכשיו אני יכול להתמקד באותה חשיבה הנדסית שממילא היתה הדבר החשוב.1 419
📌 שתי הרמות של הקוד
חברה שואלת - האם לדעתך עומק פיתוח וחשיבה הנדסית עדיין יהיו הבסיס המרכזי גם בשנים הקרובות?
אנשים אוהבים לדבר על AI כאילו הוא מבטל את החשיבה של המפתחים והופך אותנו לרובוטים שרק מאשרים קוד שאנחנו אפילו לא מבינים. אין ספק שיש אנשים שבוחרים בגישה זו אבל היא לא פרודוקטיבית ולאורך זמן לא תחזיק מעמד.
מה שאנחנו רואים היום הוא שינוי טקטוני בתפקיד המפתחים. בעבר מפתחים ביצעו שני תפקידים בו זמנית: גם תכננו איך מנגנון מסוים ישתלב בקוד המערכת וגם כתבו את הקוד הספציפי עבור אותו מנגנון. יש חברות שניסו להפריד את התפקיד כך שארכיטקטים יסבירו איך המנגנונים משתלבים במערכת ומפתחים רק יכתבו את הקוד, אבל במציאות זה לא עבד. מפתחים היו צריכים לקבל אינסוף החלטות טכניות על המימושים והרבה פעמים תוך כדי מימוש גילו שהארכיטקטורה לא תואמת. בסופו של דבר ארכיטקטים נדחפו למעלה להחליט איך תתי מערכות שונות יתחברו אבל התרחקו מהקוד. המפתחים היו אלה שהחליטו איפה עושים Code Reuse ואיפה משכפלים מנגנון, איפה יוצרים קלאס חדש ואיפה מוסיפים רק פונקציה, איפה מגדירים Builder נפרד במקום להעביר עוד פרמטרים לבנאי, מה לשמור ב Cache ולכמה זמן. כשמפתחים לא הבינו מה הם מחליטים מערכות התדרדרו.
היום תפקיד המימוש ברובו מבוצע על ידי AI, כך שמפתחים יכולים לתכנן ו AI מיישם מהר יותר מאיתנו. דוגמה? בטח. היה לי קובץ SRT עם כתוביות וזמנים לא מדויקים וקובץ נפרד של timestamps של מילים בו המילים עצמן לא היו מדויקות אבל ה timestamps כן, כלומר חלק מהמילים הופיעו עם שגיאות כתיב, חלק מהמילים לא הופיעו, חלק הופיעה מילה אחרת, אבל בגדול הזמנים שליד כל מילה היו מדויקים. עכשיו צריך לשלב בין השניים, לקחת את הטקסט מה SRT ולהתאים לכל תחילת משפט את הזמן האמיתי של תחילת המשפט לפי קובץ הזמנים. כתבתי ל AI:
write a script to fix the SRT timestamps based on transcript.txt assembly ai times. Walk both files in parallel ignoring small differences and fix timestamps in the SRT based on the
transcript.txt word timestamps
הפרומפט הזה הוא ירייה באפילה. אין אפיון, אין הסבר איך לעשות את זה, פשוט צא לדרך ונסה למזג. ה AI הסתבך עם עצמו ובסוף בוחר לנסות להתאים את הטקסטים מילה-מילה. זה כמובן לא הגיוני כי השגיאות בקובץ המילים הן רנדומליות לגמרי. הדרך הנכונה לרוץ על הקבצים היא באמצעות sliding window שמניח שפעם בכמה מילים יש מילה לא מתאימה אבל זה בסדר ורק אם יש יותר מדי מילים לא מתאימות אז מבינים שלגמרי יצאנו מסינכרון ואז צריך לנסות למצוא עוגן אחר.
בנקודה הזאת עצרתי את ה AI והוספתי הודעת הכוונה:
Better -
start with the SRT, first line in the SRT includes N words
take these N words from the list of word-timestamps transcript.txt and use the first timestamp
Then continue iterating SRT lines
when a word doesn't match you can skip it, but if multiple words don't match (maybe 3) you should backtrack to check if a word was just skipped (missing)
if you can't match or backtrack raise an exception as there's a problem with either the script or the data
עכשיו ממשיכים ושואלים - האם הקוד עצמו חשוב? האם אני רוצה להשתמש במנגנון הזה במקומות נוספים או שזה סקריפט חד פעמי? איך אני רוצה לארגן אותו? אלה לא שאלות ש AI יכול לענות עליהן. הן קשורות למבנה המערכת הספציפי שלי.
מה ש AI כן יכול לעשות זה לכתוב את אותה לולאת פייתון לפי ההוראות שכתבתי, בסיפור שלנו הפונקציה נראית כך:
def align_and_fix(
srt_entries: list[dict], ts_words: list[dict]
) -> list[dict]:
"""
Align SRT entries with transcript word timestamps.
Returns the entries list with new_start_ms / new_end_ms set.
"""
# Flatten SRT words with entry tracking
srt_flat = [] # (norm_word, entry_index)
for entry in srt_entries:
for w in entry["norm_words"]:
srt_flat.append((w, entry["index"]))
ts_norms = [w["norm"] for w in ts_words]
sp = 0
tp = 0
entry_ts_map: dict[int, list[int]] = {}
while sp < len(srt_flat) and tp < len(ts_norms):
srt_word, ei = srt_flat[sp]
if words_match(srt_word, ts_norms[tp]):
entry_ts_map.setdefault(ei, []).append(tp)
sp += 1
tp += 1
else:
offset = find_sync(
[w[0] for w in srt_flat], ts_norms, sp, tp
)
if offset is not None:
tp += offset
现已上线!2025 年 Telegram 研究 — 年度关键洞察 
