AI Edge Function Calling SDK (FC SDK) adalah library yang memungkinkan developer menggunakan panggilan fungsi dengan LLM di perangkat. Panggilan fungsi memungkinkan Anda menghubungkan model ke alat dan API eksternal, sehingga model dapat memanggil fungsi tertentu dengan parameter yang diperlukan untuk menjalankan tindakan dunia nyata.
Daripada hanya menghasilkan teks, LLM yang menggunakan FC SDK dapat menghasilkan panggilan terstruktur ke fungsi yang menjalankan tindakan, seperti menelusuri informasi terbaru, menyetel alarm, atau membuat reservasi.
Panduan ini akan memandu Anda melalui panduan memulai dasar untuk menambahkan LLM Inference API dengan FC SDK ke aplikasi Android. Panduan ini berfokus pada penambahan kemampuan panggilan fungsi ke LLM di perangkat. Untuk informasi selengkapnya tentang penggunaan LLM Inference API, lihat panduan LLM Inference untuk Android.
Panduan memulai
Gunakan langkah-langkah berikut untuk menggunakan FC SDK di aplikasi Android Anda. Panduan memulai ini menggunakan LLM Inference API dengan Hammer 2.1 (1,5 miliar). LLM Inference API dioptimalkan untuk perangkat Android kelas atas, seperti Pixel 8 dan Samsung S23 atau yang lebih baru, dan tidak mendukung emulator perangkat dengan andal.
Menambahkan dependensi
FC SDK menggunakan library com.google.ai.edge.localagents:localagents-fc
dan
LLM Inference API menggunakan library com.google.mediapipe:tasks-genai
. Tambahkan
kedua dependensi ke file build.gradle
aplikasi Android Anda:
dependencies {
implementation 'com.google.mediapipe:tasks-genai:0.10.24'
implementation 'com.google.ai.edge.localagents:localagents-fc:0.1.0'
}
Untuk perangkat dengan Android 12 (API 31) atau yang lebih tinggi, tambahkan dependensi library
OpenCL native. Untuk mengetahui informasi selengkapnya, lihat dokumentasi tentang tag
uses-native-library
.
Tambahkan tag uses-native-library
berikut ke file AndroidManifest.xml
:
<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"/>
Mendownload model
Download Hammer 1B dalam format kuantisasi 8-bit dari Hugging Face. Untuk mengetahui informasi selengkapnya tentang model yang tersedia, lihat Dokumentasi model.
Kirim konten folder hammer2.1_1.5b_q8_ekv4096.task
ke perangkat
Android.
$ 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
Mendeklarasikan definisi fungsi
Tentukan fungsi yang akan tersedia untuk model. Untuk mengilustrasikan prosesnya, panduan memulai ini menyertakan dua fungsi sebagai metode statis yang menampilkan respons hard code. Implementasi yang lebih praktis akan menentukan fungsi yang memanggil REST API atau mengambil informasi dari database.
Berikut adalah definisi fungsi getWeather
dan getTime
:
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() {}
}
Gunakan FunctionDeclaration
untuk menjelaskan setiap fungsi, memberi nama dan
deskripsi, serta menentukan jenisnya. Hal ini memberi tahu model tentang fungsi yang dilakukan dan waktu untuk melakukan panggilan fungsi.
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();
Tambahkan deklarasi fungsi ke objek Tool
:
var tool = Tool.newBuilder()
.addFunctionDeclarations(getWeather)
.addFunctionDeclarations(getTime)
.build();
Membuat backend inferensi
Buat backend inferensi menggunakan LLM Inference API dan teruskan objek
formator untuk model Anda. FC SDK Formatter (ModelFormatter
) berfungsi sebagai
formator dan parser. Karena panduan memulai ini menggunakan Gemma-3 1B, kita akan menggunakan
GemmaFormatter
:
var llmInferenceOptions = LlmInferenceOptions.builder()
.setModelPath(modelFile.getAbsolutePath())
.build();
var llmInference = LlmInference.createFromOptions(context, llmInferenceOptions);
var llmInferenceBackend = new llmInferenceBackend(llmInference, new GemmaFormatter());
Untuk mengetahui informasi selengkapnya, lihat opsi konfigurasi inferensi LLM.
Membuat instance model
Gunakan objek GenerativeModel
untuk menghubungkan backend inferensi, perintah
sistem, dan alat. Kita sudah memiliki backend dan alat inferensi, sehingga kita hanya
perlu membuat perintah sistem:
var systemInstruction = Content.newBuilder()
.setRole("system")
.addParts(Part.newBuilder().setText("You are a helpful assistant."))
.build();
Buat instance model dengan GenerativeModel
:
var generativeModel = new GenerativeModel(
llmInferenceBackend,
systemInstruction,
List.of(tool),
)
Memulai sesi chat
Untuk memudahkan, panduan memulai ini memulai satu sesi chat. Anda juga dapat membuat beberapa sesi independen.
Dengan menggunakan instance GenerativeModel
baru, mulai sesi chat:
var chat = generativeModel.startChat();
Kirim perintah ke model melalui sesi chat, menggunakan metode
sendMessage
:
var response = chat.sendMessage("How's the weather in San Francisco?");
Mengurai respons model
Setelah meneruskan perintah ke model, aplikasi harus memeriksa respons untuk menentukan apakah akan melakukan panggilan fungsi atau menampilkan teks bahasa alami.
// 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());
}
Kode contoh adalah implementasi yang terlalu disederhanakan. Untuk informasi selengkapnya tentang cara aplikasi memeriksa respons model, lihat Pemformatan dan Pemrosesan.
Cara kerjanya
Bagian ini memberikan informasi yang lebih mendalam tentang konsep inti dan komponen Function Calling SDK untuk Android.
Model
SDK Panggilan Fungsi memerlukan model dengan pemformat dan parser. FC SDK berisi pemformat dan parser bawaan untuk model berikut:
Untuk menggunakan model yang berbeda dengan FC SDK, Anda harus mengembangkan formator dan parser sendiri yang kompatibel dengan LLM Inference API.
Pemformatan dan penguraian
Bagian penting dari dukungan panggilan fungsi adalah pemformatan perintah dan penguraian
output model. Meskipun ini adalah dua proses terpisah, FC SDK menangani
pemformatan dan penguraian dengan antarmuka ModelFormatter
.
Formator bertanggung jawab untuk mengonversi deklarasi fungsi terstruktur menjadi teks, memformat respons fungsi, dan menyisipkan token untuk menunjukkan awal dan akhir giliran percakapan, serta peran giliran tersebut (misalnya, "pengguna", "model").
Parser bertanggung jawab untuk mendeteksi apakah respons model berisi panggilan fungsi. Jika mendeteksi panggilan fungsi, parser akan mengurainya menjadi jenis data terstruktur. Jika tidak, sistem akan memperlakukan teks sebagai respons bahasa alam.
Decoding terbatas
Dekode terbatas adalah teknik yang memandu pembuatan output LLM untuk memastikannya mematuhi format terstruktur yang telah ditentukan sebelumnya, seperti objek JSON atau panggilan fungsi Python. Dengan menerapkan batasan ini, model akan memformat output-nya dengan cara yang selaras dengan fungsi yang telah ditentukan dan jenis parameter yang sesuai.
Untuk mengaktifkan decoding terbatas, tentukan batasan dalam objek ConstraintOptions
dan panggil metode enableConstraint
dari instance ChatSession
.
Jika diaktifkan, batasan ini akan membatasi respons agar hanya menyertakan
alat yang terkait dengan GenerativeModel
.
Contoh berikut menunjukkan cara mengonfigurasi decoding terbatas untuk
membatasi respons terhadap panggilan alat. Ini membatasi panggilan alat untuk dimulai dengan
awalan ```tool_code\n
dan diakhiri dengan akhiran
\n```
.
ConstraintOptions constraintOptions = ConstraintOptions.newBuilder()
.setToolCallOnly( ConstraintOptions.ToolCallOnly.newBuilder()
.setConstraintPrefix("```tool_code\n")
.setConstraintSuffix("\n```"))
.build();
chatSession.enableConstraint(constraintOptions);
Untuk menonaktifkan batasan aktif dalam sesi yang sama, gunakan
metode disableConstraint
:
chatSession.disableConstraint();