יצירת Agent ראשון
ארכיטקטורת Model + Harness ב-LangChain
createAgent, הפונקציה המרכזית ב-LangChainפריימוורק בקוד פתוח לבניית אפליקציות מבוססות LLM ו-agents, שעוטף רכיבים חוזרים בממשק אחיד. מתוך LangChain, מבוא ל-LangChain., מקבלת שני מרכיבים עיקריים: model — איזה מודל שפה מפעיל את ה-agentLLM שמופעל בלולאה, עם מטרה וסט כלים, ובכל סיבוב מחליט אם להפעיל כלי נוסף או לסיים ולהחזיר תשובה. מתוך AI Agents, Agents והלולאה האגנטית., ו-harnessהתוכנה שמריצה את הלולאה: שולחת את הקונטקסט למודל, מבצעת (או מסרבת לבצע) את מה שביקש, ומחזירה את התוצאה. מתוך AI Agents, מבוא לאקוסיסטם: מה יש מסביב ל-LLM. — כל מה שעוטף אותו: system prompt (הוראות), tools (כלים זמינים), ו-middlewareהמנגנון ב-LangChain שמאפשר להתערב בלולאה האגנטית עצמה; המימוש הקונקרטי של ה-harness. מתוך LangChain, Middleware. (הרחבות שמתערבות בלולאה, כמו guardrails או ניהול context).
המבנה הזה שקוף בכוונה: אין "קסם" שמסתתר מאחורי הקריאה — כל agent הוא בפשטות מודל שקורא לכלים בלולאה עד שהמשימה מסתיימת, בדיוק כמו הלולאה האגנטיתהמחזור של סוכן: תצפית, תכנון ופעולה, כשה-harness מבצע את הכלי ומוסיף את התוצאה לקונטקסט לפני הסיבוב הבא. מתוך AI Agents, Agents והלולאה האגנטית. שהוגדרה בנושא AI Agents.
התקנה והגדרה בסיסית
כדי להתחיל צריך את חבילת ה-npm הראשית ומפתח API לספק מודל שבחרתם (למשל Anthropic או OpenAI), שנטען בדרך כלל ממשתנה סביבה.
npm install langchain
# .env
ANTHROPIC_API_KEY=sk-...יצירת Agent עם createAgent
הדוגמה הבאה יוצרת agentLLM שמופעל בלולאה, עם מטרה וסט כלים, ובכל סיבוב מחליט אם להפעיל כלי נוסף או לסיים ולהחזיר תשובה. מתוך AI Agents, Agents והלולאה האגנטית. פשוט עם כלי אחד שמחזיר מזג אוויר: מגדירים את הכלי עם tool ו-schema של zod לאימות הפרמטרים, ואז מעבירים אותו יחד עם המודל וה-system prompt ל-createAgent.
import { createAgent, tool } from "langchain";
import { z } from "zod";
const getWeather = tool(
async ({ city }: { city: string }) => `${city}: שמש, 22 מעלות`,
{
name: "get_weather",
description: "מחזיר את מזג האוויר הנוכחי בעיר נתונה",
schema: z.object({ city: z.string() }),
}
);
const agent = createAgent({
model: "anthropic:claude-sonnet-5",
tools: [getWeather],
systemPrompt: "אתה עוזר שמדווח על מזג אוויר בקצרה ובעברית.",
});הרצת Agent: invoke, היסטוריית הודעות ו-thread persistence
מריצים agentLLM שמופעל בלולאה, עם מטרה וסט כלים, ובכל סיבוב מחליט אם להפעיל כלי נוסף או לסיים ולהחזיר תשובה. מתוך AI Agents, Agents והלולאה האגנטית. עם agent.invoke, ומעבירים מערך messages בדיוק כמו בקריאה ישירה ל-API של מודל שפה — ה-agent דואג בעצמו להריץ את לולאת ה-tool callingמנגנון שבו המודל מחליט בעצמו אם ומתי להפעיל פונקציה בקוד שלכם, מקבל את התוצאה כ-context ועונה על בסיסה. מתוך LLM, יסודות ה-AI. עד שיש תשובה סופית.
כדי לשמר היסטוריית שיחה בין קריאות (למשל בצ'אט רב-שלבי), מעבירים thread_id קבוע דרך configurable — LangChainפריימוורק בקוד פתוח לבניית אפליקציות מבוססות LLM ו-agents, שעוטף רכיבים חוזרים בממשק אחיד. מתוך LangChain, מבוא ל-LangChain. שומר את ההיסטוריה משויכת ל-thread הזה, כך שבקריאה הבאה ה-agent "זוכר" מה נאמר קודם, בלי שתצטרכו לנהל את זה ידנית.
const result = await agent.invoke(
{ messages: [{ role: "user", content: "מה מזג האוויר בתל אביב?" }] },
{ configurable: { thread_id: "chat-1" } }
);
console.log(result.messages.at(-1)?.content);
// → "תל אביב: שמש, 22 מעלות"דוגמה מלאה: שיחה רב-שלבית עם אותו agent
כשקוראים שוב ל-agent.invoke עם אותו thread_id, ה-agentLLM שמופעל בלולאה, עם מטרה וסט כלים, ובכל סיבוב מחליט אם להפעיל כלי נוסף או לסיים ולהחזיר תשובה. מתוך AI Agents, Agents והלולאה האגנטית. רואה את כל ההודעות הקודמות בשיחה, ולכן יכול לענות על שאלת המשך בלי שנחזור ונציין את ההקשר במפורש.
זה בדיוק ה-thread persistence שהוזכר למעלה: ה-state (כל ה-messages) משויך ל-thread_id ברקע, כך שקוד הצריכה שלכם נשאר פשוט — אתם רק שולחים את ההודעה החדשה, לא את כל ההיסטוריה בכל פעם.
const followUp = await agent.invoke(
{ messages: [{ role: "user", content: "ומה לגבי מחר?" }] },
{ configurable: { thread_id: "chat-1" } }
);
console.log(followUp.messages.at(-1)?.content);שאלות נפוצות
איפה בפועל נשמרת ההיסטוריה של thread_id?
כדי שההיסטוריה תישמר, ה-agent צריך מנגנון שמירה מוגדר (ב-LangGraph הוא נקרא checkpointer). שמירה בזיכרון התהליך מתאימה לפיתוח, אבל ההיסטוריה נעלמת כשהשרת עולה מחדש, ולכן ב-production מגדירים אחסון קבוע כמו בסיס נתונים. האופן המדויק להגדרה משתנה בין גרסאות, אז כדאי לבדוק בתיעוד הרשמי.
מה קורה אם שני משתמשים מקבלים את אותו thread_id?
הם חולקים את אותה היסטוריה, כלומר כל אחד מהם רואה את ההקשר של השני. thread_id צריך להיות ייחודי לכל שיחה, וכדאי לייצר אותו בשרת (למשל UUID שמשויך למשתמש המחובר) ולא לקבל אותו כמו שהוא מהלקוח, כדי שאף משתמש לא יוכל לנחש thread של מישהו אחר.
מה מונע מ-agent להיתקע בלולאה אינסופית של קריאות לכלים?
LangChain מגביל את מספר הצעדים בכל הרצה, וכשהמגבלה נחצית ההרצה נעצרת עם שגיאה. אפשר לשנות את המגבלה בהגדרות ההרצה (השם המדויק משתנה בין גרסאות — בדקו בתיעוד), וב-middleware (פרק 8) אפשר להוסיף מגבלות משלכם, למשל על מספר הקריאות לכלי מסוים.