فراخوانی ابزار ، که به نام فراخوانی تابع نیز شناخته میشود، روشی ساختاریافته برای دادن توانایی LLM برای بازگرداندن درخواستها به برنامهای است که آن را فراخوانی کرده است. شما ابزارهایی را که میخواهید در دسترس مدل قرار دهید، تعریف میکنید، و مدل درخواستهای ابزاری را در صورت لزوم از برنامه شما برای انجام درخواستهایی که به آن میدهید، ارسال میکند.
موارد استفاده از فراخوانی ابزار به طور کلی در چند موضوع قرار می گیرند:
دادن دسترسی به LLM به اطلاعاتی که با آن آموزش ندیده است
- اطلاعاتی که اغلب در حال تغییر هستند، مانند قیمت سهام یا آب و هوای فعلی.
- اطلاعات خاص دامنه برنامه شما، مانند اطلاعات محصول یا نمایه های کاربر.
به همپوشانی با نسل افزوده بازیابی (RAG) توجه کنید، که همچنین راهی برای ادغام اطلاعات واقعی به LLM در نسلهای خود است. RAG راه حل سنگین تری است که زمانی مناسب تر است که شما حجم زیادی از اطلاعات دارید یا اطلاعاتی که بیشترین ارتباط را با یک اعلان دارد مبهم است. از سوی دیگر، اگر یک فراخوانی تابع یا جستجوی پایگاه داده تمام چیزی است که برای بازیابی اطلاعات مورد نیاز LLM لازم است، فراخوانی ابزار مناسب تر است.
معرفی درجه ای از جبرگرایی در یک گردش کار LLM
- انجام محاسباتی که LLM نمی تواند خود را به طور قابل اعتماد انجام دهد.
- مجبور کردن یک LLM برای تولید متن کلمه به کلمه تحت شرایط خاص، مانند هنگام پاسخ دادن به سؤالی در مورد شرایط خدمات یک برنامه.
انجام یک عمل زمانی که توسط یک LLM آغاز شود
- روشن و خاموش کردن چراغها در دستیار خانگی مجهز به LLM
- رزرو میز رزرو در نمایندگی رستوران با قدرت LLM
قبل از شروع
اگر می خواهید نمونه کدهای موجود در این صفحه را اجرا کنید، ابتدا مراحل راهنمای Get Start را کامل کنید. همه مثالها فرض میکنند که شما قبلاً پروژهای را با وابستگیهای Genkit نصب کردهاید.
این صفحه یکی از ویژگیهای پیشرفته انتزاع مدل Genkit را مورد بحث قرار میدهد، بنابراین قبل از اینکه خیلی عمیق شوید، باید با محتوای صفحه تولید محتوا با مدلهای هوش مصنوعی آشنا شوید. همچنین باید با سیستم Genkit برای تعریف طرحواره های ورودی و خروجی آشنا باشید که در صفحه Flow ها به آن پرداخته شده است.
مروری بر فراخوانی ابزار
در سطح بالا، این چیزی است که یک تعامل معمولی برای فراخوانی ابزار با یک LLM به نظر می رسد:
- برنامه فراخوانی LLM را با یک درخواست درخواست می کند و همچنین فهرستی از ابزارهایی را که LLM می تواند برای ایجاد پاسخ از آنها استفاده کند در آن درخواست می کند.
- LLM یا یک پاسخ کامل ایجاد می کند یا یک درخواست فراخوانی ابزار در قالب خاصی ایجاد می کند.
- اگر تماس گیرنده پاسخ کامل دریافت کند، درخواست برآورده شده و تعامل پایان می یابد. اما اگر تماس گیرنده یک فراخوانی ابزار دریافت کند، هر منطقی را که مناسب است انجام می دهد و درخواست جدیدی را به LLM ارسال می کند که حاوی دستور اصلی یا تغییراتی از آن و همچنین نتیجه فراخوانی ابزار است.
- LLM دستور جدید را مانند مرحله 2 مدیریت می کند.
برای انجام این کار، چندین الزام باید برآورده شود:
- مدل باید آموزش داده شود تا در مواقعی که برای تکمیل یک درخواست نیاز است، درخواست ابزار بدهد. اکثر مدل های بزرگتر ارائه شده از طریق API های وب مانند Gemini می توانند این کار را انجام دهند، اما مدل های کوچکتر و تخصصی تر اغلب نمی توانند این کار را انجام دهند. اگر بخواهید ابزارهایی را برای مدلی که آن را پشتیبانی نمی کند ارائه دهید، Genkit با خطا مواجه می شود.
- برنامه فراخوانی باید تعاریف ابزار را در قالبی که انتظار دارد به مدل ارائه دهد.
- برنامه فراخوانی باید مدل را وادار کند تا درخواست های فراخوانی ابزار را در قالبی که برنامه انتظار دارد ایجاد کند.
تماس ابزار با Genkit
Genkit یک رابط واحد برای فراخوانی ابزار با مدل هایی که از آن پشتیبانی می کنند ارائه می دهد. هر پلاگین مدل تضمین می کند که دو معیار آخر ذکر شده در بخش قبل برآورده می شوند و تابع genkit.Generate()
به طور خودکار حلقه فراخوانی ابزار را که قبلا توضیح داده شد انجام می دهد.
پشتیبانی از مدل
پشتیبانی از فراخوانی ابزار به مدل، API مدل و پلاگین Genkit بستگی دارد. برای تعیین اینکه آیا فراخوانی ابزار احتمالاً پشتیبانی می شود یا خیر، با اسناد مربوطه مشورت کنید. علاوه بر این:
- اگر بخواهید ابزارهایی را برای مدلی که آن را پشتیبانی نمی کند ارائه دهید، Genkit با خطا مواجه می شود.
- اگر افزونه ارجاعات مدل را صادر می کند، ویژگی
ModelInfo.Supports.Tools
نشان می دهد که آیا از فراخوانی ابزار پشتیبانی می کند یا خیر.
تعریف ابزار
از تابع genkit.DefineTool()
برای نوشتن تعاریف ابزار استفاده کنید:
import (
"context"
"log"
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/googlegenai"
)
func main() {
ctx := context.Background()
g, err := genkit.Init(ctx,
genkit.WithPlugins(&googlegenai.GoogleAI{}),
genkit.WithDefaultModel("googleai/gemini-2.0-flash"),
)
if err != nil {
log.Fatal(err)
}
getWeatherTool := genkit.DefineTool(
g, "getWeather", "Gets the current weather in a given location",
func(ctx *ai.ToolContext, location string) (string, error) {
// Here, we would typically make an API call or database query. For this
// example, we just return a fixed value.
return fmt.Sprintf("The current weather in %s is 63°F and sunny.", location);
})
}
نحو در اینجا دقیقاً شبیه نحو genkit.DefineFlow()
است. با این حال، شما باید یک توضیح بنویسید. به عبارت و توصیفی بودن توضیحات دقت ویژه ای داشته باشید زیرا تصمیم گیری برای استفاده مناسب از آن برای LLM حیاتی است.
با استفاده از ابزار
ابزارهای تعریف شده را برای تولید محتوا در اعلانات خود بگنجانید.
ایجاد کنید
resp, err := genkit.Generate(ctx, g,
ai.WithPrompt("What is the weather in San Francisco?"),
ai.WithTools(getWeatherTool),
)
DefinePrompt
weatherPrompt, err := genkit.DefinePrompt(g, "weatherPrompt",
ai.WithPrompt("What is the weather in {{location}}?"),
ai.WithTools(getWeatherTool),
)
if err != nil {
log.Fatal(err)
}
resp, err := weatherPrompt.Execute(ctx,
with.Input(map[string]any{"location": "San Francisco"}),
)
فایل اعلان
---
system: "Answer questions using the tools you have."
tools: [getWeather]
input:
schema:
location: string
---
What is the weather in {{location}}?
سپس می توانید دستور زیر را در کد خود اجرا کنید:
// Assuming prompt file named weatherPrompt.prompt exists in ./prompts dir.
weatherPrompt := genkit.LookupPrompt("weatherPrompt")
if weatherPrompt == nil {
log.Fatal("no prompt named 'weatherPrompt' found")
}
resp, err := weatherPrompt.Execute(ctx,
ai.WithInput(map[string]any{"location": "San Francisco"}),
)
اگر LLM نیاز به استفاده از ابزار getWeather
برای پاسخ دادن به درخواست داشته باشد، Genkit به طور خودکار تماس ابزار را مدیریت می کند.
کنترل صریح تماس های ابزار
اگر می خواهید کنترل کاملی بر این حلقه فراخوانی ابزار داشته باشید، برای مثال برای اعمال منطق پیچیده تر، گزینه WithReturnToolRequests()
را روی true
تنظیم کنید. اکنون این مسئولیت شماست که اطمینان حاصل کنید که تمام درخواستهای ابزار برآورده شدهاند:
getWeatherTool := genkit.DefineTool(
g, "getWeather", "Gets the current weather in a given location",
func(ctx *ai.ToolContext, location string) (string, error) {
// Tool implementation...
})
resp, err := genkit.Generate(ctx, g,
ai.WithPrompt("What is the weather in San Francisco?"),
ai.WithTools(getWeatherTool),
ai.WithReturnToolRequests(true),
)
if err != nil {
log.Fatal(err)
}
parts := []*Part{}
for _, req := range resp.ToolRequests() {
tool := genkit.LookupTool(g, req.Name)
if tool == nil {
log.Fatalf("tool %q not found", req.Name)
}
output, err := tool.RunRaw(ctx, req.Input)
if err != nil {
log.Fatalf("tool %q execution failed: %v", err)
}
parts = append(parts,
ai.NewToolResponsePart(&ai.ToolResponse{
Name: req.Name,
Ref: req.Ref,
Output: output,
}))
}
resp, err = genkit.Generate(ctx, g,
ai.WithMessages(resp.History()..., NewMessage(ai.RoleTool, nil, parts...)),
)
if err != nil {
log.Fatal(err)
}