חיפוש עבודה בעזרת סוכנים חכמים – חלק 5

בחלק הקודם ראינו כיצד הסוכן החכם יכול להשתמש בכלים שאנחנו מעמידים לרשותו. לפתרון הזה מספר בעיות:.

  • לכל כלי יש ממשק משלו שדורש קידוד ספציפי המותאם לאותו כלי.
  • כלים שונים שמבצעים את אותה משימה עלולים לחשוף ממשק שונה שהסוכן חייב לממש.
  • יש הרבה כלים שנוצרו בקהילות קוד פתוח, אבל לכל פרוייקט כזה ממשק משלו. אין אחידות, ולכן קשה להשתמש בכלים אחרים מבלי לבצע התאמות בקוד לכל כלי.

הבעיות הללו מגדילות את סיבוכיות פיתוח פרוייקטי AI שלא לצורך (בעיית ה M כפול N). אם יש לנו M יישומי AI ו-N כלים, כמות ההתאמות בקוד שמתטרך לבצע כדי להשתמש בכלים הללו תהיה M*N.

כדי לפתור את הביות הללו, נוצר פרוטוקול ה-MCP (Model Context Protocol). זהו תקן פתוח שנוצר ע"י חברת אנתרופיק ב-2024 ונועד לתקנן את הדרך שבה סוכנים מתקשרים עם כלים חיצוניים.

התקן מפחית את סיבוכיות הפיתוח ל N + M:

How MCP solves the MxN integration problem. Source: SalesforceDevops

התקן מאפשר גישה סטנדרטית לכלים, משאבים חיצוניים ופרומפטים. היישום מורכב משרת (יכול להיות מקומי או מרוחק) החושף פונקציות, מקורות מידע אן כלים בממשק סטנדרטי. אליו מתחבר הלקוח המשמש כמתווך בין יישום ה-AI (המכונה גם "מארח" – IDE, שרת AI מרוחק, סוכן AU או כלי מקומי) לשרת ה-MCP. הלקוח מטפל בתקשורת לפי הגדרות הפרוטוקול ובהעברת המידע והפקודות. הסבר נרחב ניתן למצוא בתיעוד של אנתרופיק.

לצרכי לימוד ננסה לבנות בפרוייקט שלנו שרת MCP שיבצע את הפעולות הבאות:

  • יחזיר רשימה של כל המשרות הפתוחות.
  • יספק מידע על משרה מסויימת.

הקוד המלא מופיע כאן.

והוא מבוסס בעיקר על הפונקציות הבאות:

בכדי להריץ את שרת ה-MCP, הורידו את הקוד, עברו לספריית part-05:

uv sync
uv run jobs.py

בכדי לבדוק אם השרת עובד כהלכה יש לגשת אליו מלקוח MCP. אפשר לעשות זאת באמצעות סביבות פיתוח מקומיות כמו: Claude Desktop, Cursor וכו'. אני אשתמש ב- Gemini CLI.

נוסיף את שרת ה-MCP שלנו להגדרות של ה-Gemini CLI:

File: ~/.gemini/settings.json

{
  ...
  "mcpServers": {
    ...
    "jobs": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTR_PATH_TO_PROJECT/linkedin_jobs_ai/part-05",
        "run",
        "jobs.py"
      ]
    }

  },
}

ואם נריץ את פקודת:

/mcp tools

נקבל את שרת ה-MCP שלנו:

ועם פקודת:

/mcp desc

נקבל תיאור של הפעולות הנתמכות (הכלים) בשרת שלנו:

בפוסט הבא נראה כיצד הסוכנים יכולים להשתמש בשרת ה-MCP שלנו.

לצורך הפשטות, הכלים של השרת שלנו מחזירים את התשובה כמחרוזת טקסט. ניתן להחזיר גם תשובה מובנית (לדוגמה JSON), אך על כך בהמשך.

תמונת השער יוצרה באמצעות AI באתר tensor.art

חיפוש עבודה בעזרת סוכנים חכמים – חלק 4

בחלקים הקודמים (חלק 1חלק 2חלק 3) נתקל סוכן המשרות החכם שלנו בבעיה של כמות הטוקנים הגדולה בפרומפט, בגלל גודלו של קובץ המשרות. רצינו לראות האם הטמעות וקטוריות יפתרו את הבעיה ואכן חיפוש משרה לפי ההטמעות (בכותרת המשרה או בכל התיאור) נותן התאמות טובות.

בחלק הזה ננסה ליישם את ההטמעות הווקטוריות בתהליך העבודה של הסוכנים החכמים.
שלחנו את סוכן החיפוש החכם לחופשה ארוכה בבית וגייסנו במקומו סוכן חכם זוטר שידע להפעיל כלים שיטענו את כל קבצי תיאור המשרות ויכינו את ההטמעות הווקטוריות שלהם. בחלק זה נתמקד בטעינת הקבצים ע"י הסוכן החכם.

לצורך טעינת קבצי המשרות, נכין כלי עבודה (Tools) שהסוכן יוכל להפעיל כדי לבצע את משימותיו.

וזה הסוכן החדש שלנו:

שקיבל משימה אחת ויחידה – לטעון את הקבצים ולהחזיר אותם בפורמט מובנה של רשימת משרות:

וכמובן הצוות שלנו כולל כרגע רק את הסוכן הבודד הזה:

כאשר מריצים את הצוות הזה, ניתן לראות בשורות הלוג כי הסוכן מפעיל את כלי אעינת המשרות, שמחזיר את רשימת כל המשרות. לאחר מכן נותן הסוכן את התפוקה הבאה:

יש עדיין בעיה של כמות הטוקנים שהסוכן יכול לחפש בה ולכן המשרות המוחזרות לא רלוונטיות לחיפוש שלנו. בחלק הבא נוסיף לסוכן משימות של יצירת ההטמעות הווקטוריות כהכנה למסירת המשך הטיפול בחיפוש לסוכן חדש.

אחדים מקוראי יעירו, אולי בצדק, שלא צריך בכלל סוכן למשימה הזאת – אפשר פשוט להריץ קוד פייתוני שיטען את קבצי המשרות ויחזיר רשימה של משרות. זה נכון – אבל המטרה בחלק הזה היתה בעיקר להדגים איך ניתן לייצר Tool שמקבל קלט מובנה ומייצר פלט מובנה לשימושו של הסוכן החכם.

הקוד כולו מופיע כאן. לצורך הפשטות כללתי את כל הקוד בקובץ בודד וכן עברתי לייצור הסוכנים/משימות/כלים בקוד ולא באמצעות קונפיגורציות yaml.

תמונת השער יוצרה באמצעות AI באתר tensor.art

האם ה-LLM שלי יודע שנאסראללה חוסל?

מבוא קצר לשימוש בכלים עבור RAG

נסיונות לשאול את מודל ה LLM שלכם שאלות על מידע שהוא לא אומן עליו, יסתיימו בד"כ בתשובות "אינני יודע" למיניהן.

לדוגמה הקוד הזה:

אם נריץ את הקוד הזה נקבל תשובות כגון:

"I'm unable to tell you what the IDF (Israel Defense Forces) did on September 28, 2024."
"I cannot provide real-time information or specifics regarding future events. Is there anything else I can help you with?"

כדי לאפשר למודל ה LLM שלנו (llama3.1 בדוגמה שלנו) לענות על השאלה בהצלחה, ניתן להוסיף כלים – כגון כלי שאילתה וחיפוש באינטרנט, שה RAG יוכל להשתמש בהם.

נוסיף לדוגמה כלי חיפוש באינטרנט באמצעות DuckDuckGo.

pip install duckduckgo-search

והקוד שמגדיר את כלי החיפוש:

ואם נריץ את זה נקבל:

Smoke rises from the rubble of a building that was levelled in overnight Israeli strike on Beirut's southern suburbs, on September 28, 2024. (Photo by ANWAR AMRO / AFP) The Times of Israel is … His death marks a devastating blow to Hezbollah as it reels from Israeli attacks. It is also a huge blow to Iran. … [1/17] Beirut's southern suburbs, Lebanon September 28, 2024. Smoke rises from Israeli airstrikes in Beirut's southern suburbs, on Saturday, September 28. Hassan Ammar/AP The Israel Defense Forces is currently striking buildings in Beirut that it alleges are … Hezbollah has confirmed the death of its leader Hassan Nasrallah, after Israel said he was killed in an airstrike in Beirut, Lebanon on Friday. Retired Colonel Cedric Leighton joins CNN to discuss. A man stands near damaged buildings in the aftermath of Israeli air strikes on Beirut's southern suburbs, Lebanon September 28, 2024. REUTERS/Ali Alloush Purchase Licensing Rights, opens new tab

נגדיר עוד כלי שיספק את התשובה הסופית, ונריץ הכל יחדיו:

בשורה 51 אנו מייצרים את הפרומפט שמורה למודל להשתמש בכלים:

You can use the following tools:
1. `tool_browser`: Search on DuckDuckGo browser by passing the input `q`
2. `final_answer`: Returns a natural language response to the user by passing the input `text`.
    You should provide as much context as possible and specify the source of the information.

משורה 54 מריצים שיחה עם המודל שמתחילה ב"הלו" ומסתיימת באותה שאלה ששאלנו בתחילת הפוסט.

התשובה:

According to the provided information, on September 28, 2024, the Israeli army (IDF) carried out an airstrike on Hezbollah's central command in southern Beirut, killing Hassan Nasrallah, the longtime leader of Hezbollah, along with approximately 300 people, including other members of the group.

איך קראתי עשרות אלפי אימיילים בשניות?

ניסוי ב-RAG

יוצר בעזרת Leonardo.ai

כמקצוען ותיק בתעשיית ההיי-טק, נרשמתי להרבה רשימות תפוצה לפיתוח תוכנה וניוזלטרים טכניים אחרים במהלך השנים. אני מקבל הרבה מיילים הקשורים לטכנולוגיה/תוכנה – שברוב הפעמים אין לי זמן לקרוא והם פשוט מצטברים בתיקיית הפיתוח ב-Outlook שלי.

כשה-Outlook הנאמן והוותיק החל להיסדק ידעתי שעלי לעזור לו להתאושש ולהחזיר לו את נעוריו. חשבתי שאמחק כמה הודעות דוא"ל שמורות וחסרות תועלת ואפנה קצת זיכרון מקובץ ה-.pst (שם Outlook שומר את הפריטים שלו) כדי לעזור לו להיטען מהר יותר ולשפר את ביצועיו. סריקה מהירה של תיקיות פריטי Outlook חשפה עשרות אלפי מיילים בתיקיית Dev – שהצטברו במהלך יותר משני עשורים של ניוזלטרים נכנסים. התכוונתי למחוק אותם – אבל לפני שלחצתי על הפקודה "רוקן תיקיה" – הרגשתי צורך נוסטלגי לעיין בכמה מהמיילים האלה. גיבשתי תוכנית לעיין בהם במהירות לפני שאמחק אותם לתמיד.

להמשיך לקרוא