AI Edge Function Calling SDK'sı (FC SDK), geliştiricilerin cihaz üzerinde LLM'lerle işlev çağrısı kullanmasını sağlayan bir kitaplıktır. İşlev çağırma, modelleri harici araçlara ve API'lere bağlamanıza olanak tanır. Böylece modeller, gerçek dünyadaki işlemleri gerçekleştirmek için gerekli parametrelerle belirli işlevleri çağırabilir.
FC SDK'sını kullanan bir LLM, yalnızca metin oluşturmak yerine güncel bilgileri arama, alarm ayarlama veya rezervasyon yapma gibi bir işlemi yürüten bir fonksiyona yapılandırılmış bir çağrı oluşturabilir.
Bu rehberde, FC SDK'sı ile LLM Inference API'yi bir Android uygulamasına ekleme konusunda temel bir hızlı başlangıç süreci açıklanmaktadır. Bu kılavuz, cihaz üzerinde çalışan bir LLM'ye işlev çağrısı yapma özellikleri eklemeye odaklanmaktadır. LLM Inference API'yi kullanma hakkında daha fazla bilgi için Android için LLM Inference kılavuzuna bakın.
Hızlı başlangıç kılavuzu
Android uygulamanızda FC SDK'sını kullanmak için aşağıdaki adımları uygulayın. Bu hızlı başlangıçta, Hammer 2.1 (1,5 milyar) ile LLM Inference API kullanılır. LLM Inference API, Pixel 8 ve Samsung S23 veya sonraki modeller gibi üst düzey Android cihazlar için optimize edilmiştir ve cihaz emülatörlerini güvenilir bir şekilde desteklemez.
Bağımlılık ekleme
FC SDK'sı com.google.ai.edge.localagents:localagents-fc kitaplığını, LLM Inference API'si ise com.google.mediapipe:tasks-genai kitaplığını kullanır. Her iki bağımlılığı da Android uygulamanızın build.gradle dosyasına ekleyin:
dependencies {
implementation 'com.google.mediapipe:tasks-genai:0.10.24'
implementation 'com.google.ai.edge.localagents:localagents-fc:0.1.0'
}
Android 12 (API 31) veya sonraki sürümlerin yüklü olduğu cihazlarda yerel OpenCL kitaplığı bağımlılığını ekleyin. Daha fazla bilgi için uses-native-library
etiketiyle ilgili dokümanları inceleyin.
AndroidManifest.xml dosyasına aşağıdaki uses-native-library etiketlerini ekleyin:
<uses-native-library android:name="libOpenCL.so" android:required="false"/>
<uses-native-library android:name="libOpenCL-car.so" android:required="false"/>
<uses-native-library android:name="libOpenCL-pixel.so" android:required="false"/>
Model indirme
Hugging Face'ten Hammer 1B'yi 8 bit nicel biçimde indirin. Kullanılabilir modeller hakkında daha fazla bilgi için Modeller dokümanlarına bakın.
hammer2.1_1.5b_q8_ekv4096.task klasörünün içeriğini Android cihaza aktarın.
$ adb shell rm -r /data/local/tmp/llm/ # Remove any previously loaded models
$ adb shell mkdir -p /data/local/tmp/llm/
$ adb push hammer2.1_1.5b_q8_ekv4096.task /data/local/tmp/llm/hammer2.1_1.5b_q8_ekv4096.task
İşlev tanımlarını bildirme
Modele sunulacak işlevleri tanımlayın. Bu hızlı başlangıçta, süreci göstermek için sabit kodlanmış yanıtlar döndüren statik yöntemler olarak iki işlev yer almaktadır. Daha pratik bir uygulama, bir REST API'yi çağıran veya bir veritabanından bilgi alan işlevler tanımlar.
Aşağıda getWeather ve getTime işlevleri tanımlanmaktadır:
class ToolsForLlm {
public static String getWeather(String location) {
return "Cloudy, 56°F";
}
public static String getTime(String timezone) {
return "7:00 PM " + timezone;
}
private ToolsForLlm() {}
}
Her işlevi açıklamak için FunctionDeclaration kullanın. Her işlev için bir ad ve açıklama girip türleri belirtin. Bu, modele işlevlerin ne yaptığı ve ne zaman işlev çağrıları yapacağı hakkında bilgi verir.
var getWeather = FunctionDeclaration.newBuilder()
.setName("getWeather")
.setDescription("Returns the weather conditions at a location.")
.setParameters(
Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties(
"location",
Schema.newBuilder()
.setType(Type.STRING)
.setDescription("The location for the weather report.")
.build())
.build())
.build();
var getTime = FunctionDeclaration.newBuilder()
.setName("getTime")
.setDescription("Returns the current time in the given timezone.")
.setParameters(
Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties(
"timezone",
Schema.newBuilder()
.setType(Type.STRING)
.setDescription("The timezone to get the time from.")
.build())
.build())
.build();
İşlev tanımlarını bir Tool nesnesine ekleyin:
var tool = Tool.newBuilder()
.addFunctionDeclarations(getWeather)
.addFunctionDeclarations(getTime)
.build();
Çıkarım arka ucunu oluşturma
LLM Inference API'yi kullanarak bir çıkarım arka ucu oluşturun ve modeliniz için biçimlendirici nesnesi iletin. FC SDK Biçimlendiricisi (ModelFormatter) hem biçimlendirici hem de ayrıştırıcı olarak işlev görür. Bu hızlı başlangıç kılavuzunda Gemma-3 1B kullanıldığından GemmaFormatter kullanılacaktır:
var llmInferenceOptions = LlmInferenceOptions.builder()
.setModelPath(modelFile.getAbsolutePath())
.build();
var llmInference = LlmInference.createFromOptions(context, llmInferenceOptions);
var llmInferenceBackend = new llmInferenceBackend(llmInference, new GemmaFormatter());
Daha fazla bilgi için LLM çıkarımı yapılandırma seçenekleri başlıklı makaleyi inceleyin.
Modeli oluşturma
Çıkarım arka ucunu, sistem istemini ve araçları bağlamak için GenerativeModel nesnesini kullanın. Çıkarım arka ucu ve araçlarımız zaten mevcut olduğundan yalnızca sistem istemini oluşturmamız gerekiyor:
var systemInstruction = Content.newBuilder()
.setRole("system")
.addParts(Part.newBuilder().setText("You are a helpful assistant."))
.build();
Modeli GenerativeModel ile başlatın:
var generativeModel = new GenerativeModel(
llmInferenceBackend,
systemInstruction,
List.of(tool),
)
Sohbet oturumu başlatma
Bu hızlı başlangıç kılavuzu, basitlik açısından tek bir sohbet oturumu başlatır. Ayrıca birden fazla bağımsız oturum da oluşturabilirsiniz.
GenerativeModel'ın yeni örneğini kullanarak bir sohbet oturumu başlatın:
var chat = generativeModel.startChat();
sendMessage yöntemini kullanarak sohbet oturumu üzerinden modele istem gönderin:
var response = chat.sendMessage("How's the weather in San Francisco?");
Model yanıtını ayrıştırma
Modele bir istem iletildikten sonra, uygulamanın yanıtı inceleyerek bir işlev çağrısı yapıp yapmayacağına veya doğal dil metni çıkışı verip vermeyeceğine karar vermesi gerekir.
// Extract the model's message from the response.
var message = response.getCandidates(0).getContent().getParts(0);
// If the message contains a function call, execute the function.
if (message.hasFunctionCall()) {
var functionCall = message.getFunctionCall();
var args = functionCall.getArgs().getFieldsMap();
var result = null;
// Call the appropriate function.
switch (functionCall.getName()) {
case "getWeather":
result = ToolsForLlm.getWeather(args.get("location").getStringValue());
break;
case "getTime":
result = ToolsForLlm.getWeather(args.get("timezone").getStringValue());
break;
default:
throw new Exception("Function does not exist:" + functionCall.getName());
}
// Return the result of the function call to the model.
var functionResponse =
FunctionResponse.newBuilder()
.setName(functionCall.getName())
.setResponse(
Struct.newBuilder()
.putFields("result", Value.newBuilder().setStringValue(result).build()))
.build();
var functionResponseContent = Content.newBuilder()
.setRole("user")
.addParts(Part.newBuilder().setFunctionResponse(functionResponse))
.build();
var response = chat.sendMessage(functionResponseContent);
} else if (message.hasText()) {
Log.i(message.getText());
}
Örnek kod, aşırı basitleştirilmiş bir uygulamadır. Bir uygulamanın model yanıtlarını nasıl inceleyebileceği hakkında daha fazla bilgi için Biçimlendirme ve Ayrıştırma başlıklı makaleyi inceleyin.
İşleyiş şekli
Bu bölümde, Android için Function Calling SDK'sının temel kavramları ve bileşenleri hakkında daha ayrıntılı bilgi verilmektedir.
Modeller
Function Calling SDK'sı için biçimlendirici ve ayrıştırıcı içeren bir model gerekir. FC SDK, aşağıdaki modeller için yerleşik bir biçimlendirici ve ayrıştırıcı içerir:
- Gemma:
GemmaFormatterkullanın. - Llama:
LlamaFormatterkullanın. - Çekiç:
HammerFormattersimgesini kullanın.
FC SDK ile farklı bir model kullanmak için LLM Inference API ile uyumlu kendi biçimlendiricinizi ve ayrıştırıcınızı geliştirmeniz gerekir.
Biçimlendirme ve ayrıştırma
İşlev çağrısı desteğinin önemli bir parçası, istemlerin biçimlendirilmesi ve model çıkışının ayrıştırılmasıdır. Bunlar iki ayrı işlem olsa da FC SDK, ModelFormatter arayüzüyle hem biçimlendirmeyi hem de ayrıştırmayı gerçekleştirir.
Biçimlendirici, yapılandırılmış işlev bildirimlerini metne dönüştürmek, işlev yanıtlarını biçimlendirmek ve konuşma dönüşlerinin başlangıcını ve sonunu, ayrıca bu dönüşlerin rollerini (ör. "kullanıcı", "model") belirtmek için jetonlar eklemekten sorumludur.
Ayrıştırıcı, model yanıtının işlev çağrısı içerip içermediğini tespit etmekten sorumludur. Ayrıştırıcı bir işlev çağrısı algılarsa bunu yapılandırılmış bir veri türüne ayrıştırır. Aksi takdirde, metni doğal dil yanıtı olarak ele alır.
Kısıtlanmış kod çözme
Kısıtlanmış kod çözme, LLM'lerin çıkış oluşturma sürecini yönlendirerek JSON nesneleri veya Python işlev çağrıları gibi önceden tanımlanmış yapılandırılmış bir biçime uymasını sağlayan bir tekniktir. Model, bu kısıtlamaları uygulayarak çıkışlarını önceden tanımlanmış işlevler ve bunların karşılık gelen parametre türleriyle uyumlu olacak şekilde biçimlendirir.
Kısıtlı kod çözmeyi etkinleştirmek için kısıtlamaları bir ConstraintOptions nesnesinde tanımlayın ve bir ChatSession örneğinin enableConstraint yöntemini çağırın.
Bu kısıtlama etkinleştirildiğinde yanıt yalnızca GenerativeModel ile ilişkili araçları içerecek şekilde kısıtlanır.
Aşağıdaki örnekte, yanıtı araç çağrılarıyla sınırlamak için kısıtlanmış kod çözme işleminin nasıl yapılandırılacağı gösterilmektedir. Bu parametre, araç çağrısının ```tool_code\n önekiyle başlamasını ve \n``` sonekiyle bitmesini zorunlu kılar.
ConstraintOptions constraintOptions = ConstraintOptions.newBuilder()
.setToolCallOnly( ConstraintOptions.ToolCallOnly.newBuilder()
.setConstraintPrefix("```tool_code\n")
.setConstraintSuffix("\n```"))
.build(); chatSession.enableConstraint(constraintOptions);
Aynı oturumda etkin kısıtlamayı devre dışı bırakmak için disableConstraint yöntemini kullanın:
chatSession.disableConstraint();