SDK Gọi hàm AI Edge (SDK FC) là một thư viện cho phép nhà phát triển sử dụng lệnh gọi hàm bằng LLM trên thiết bị. Lệnh gọi hàm cho phép bạn kết nối các mô hình với các công cụ và API bên ngoài, cho phép các mô hình gọi các hàm cụ thể bằng các tham số cần thiết để thực thi các hành động trong thực tế.
Thay vì chỉ tạo văn bản, LLM sử dụng SDK FC có thể tạo một lệnh gọi có cấu trúc đến một hàm thực thi một hành động, chẳng hạn như tìm kiếm thông tin mới nhất, đặt chuông báo hoặc đặt chỗ.
Hướng dẫn này sẽ hướng dẫn bạn cách bắt đầu nhanh cơ bản để thêm API suy luận LLM với SDK FC vào một ứng dụng Android. Hướng dẫn này tập trung vào việc thêm các chức năng gọi hàm vào LLM trên thiết bị. Để biết thêm thông tin về cách sử dụng API suy luận LLM, hãy xem Hướng dẫn suy luận LLM cho Android.
Bắt đầu nhanh
Hãy làm theo các bước sau để sử dụng SDK FC trong ứng dụng Android. Phần hướng dẫn nhanh này sử dụng API suy luận LLM với Hammer 2.1 (1,5 tỷ). API suy luận LLM được tối ưu hoá cho các thiết bị Android cao cấp, chẳng hạn như Pixel 8 và Samsung S23 trở lên, đồng thời không hỗ trợ đáng tin cậy cho trình mô phỏng thiết bị.
Thêm phần phụ thuộc
SDK FC sử dụng thư viện com.google.ai.edge.localagents:localagents-fc
và API suy luận LLM sử dụng thư viện com.google.mediapipe:tasks-genai
. Thêm cả hai phần phụ thuộc vào tệp build.gradle
của ứng dụng Android:
dependencies {
implementation 'com.google.mediapipe:tasks-genai:0.10.24'
implementation 'com.google.ai.edge.localagents:localagents-fc:0.1.0'
}
Đối với các thiết bị chạy Android 12 (API 31) trở lên, hãy thêm phần phụ thuộc thư viện OpenCL gốc. Để biết thêm thông tin, hãy xem tài liệu về thẻ uses-native-library
.
Thêm các thẻ uses-native-library
sau vào tệp 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"/>
Tải mô hình xuống
Tải Hammer 1B ở định dạng lượng tử hoá 8 bit từ Hugging Face. Để biết thêm thông tin về các mô hình hiện có, hãy xem Tài liệu về mô hình.
Đẩy nội dung của thư mục hammer2.1_1.5b_q8_ekv4096.task
vào thiết bị 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
Khai báo định nghĩa hàm
Xác định các hàm sẽ được cung cấp cho mô hình. Để minh hoạ quy trình này, hướng dẫn nhanh này bao gồm hai hàm dưới dạng phương thức tĩnh trả về các phản hồi được mã hoá cứng. Một cách triển khai thực tế hơn sẽ xác định các hàm gọi API REST hoặc truy xuất thông tin từ cơ sở dữ liệu.
Phần sau đây xác định các hàm getWeather
và 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() {}
}
Sử dụng FunctionDeclaration
để mô tả từng hàm, đặt tên và mô tả cho từng hàm, đồng thời chỉ định các loại. Điều này cho mô hình biết hàm thực hiện chức năng gì và thời điểm thực hiện lệnh gọi hàm.
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();
Thêm phần khai báo hàm vào đối tượng Tool
:
var tool = Tool.newBuilder()
.addFunctionDeclarations(getWeather)
.addFunctionDeclarations(getTime)
.build();
Tạo phần phụ trợ suy luận
Tạo phần phụ trợ suy luận bằng API Suy luận LLM và truyền cho phần phụ trợ này một đối tượng định dạng cho mô hình của bạn. Trình định dạng SDK FC (ModelFormatter
) đóng vai trò là cả trình định dạng và trình phân tích cú pháp. Vì hướng dẫn nhanh này sử dụng Gemma-3 1B, nên chúng ta sẽ sử dụng GemmaFormatter
:
var llmInferenceOptions = LlmInferenceOptions.builder()
.setModelPath(modelFile.getAbsolutePath())
.build();
var llmInference = LlmInference.createFromOptions(context, llmInferenceOptions);
var llmInferenceBackend = new llmInferenceBackend(llmInference, new GemmaFormatter());
Để biết thêm thông tin, hãy xem các tuỳ chọn cấu hình suy luận LLM.
Tạo thực thể cho mô hình
Sử dụng đối tượng GenerativeModel
để kết nối phần phụ trợ suy luận, lời nhắc hệ thống và các công cụ. Chúng ta đã có phần phụ trợ và công cụ suy luận, vì vậy, chúng ta chỉ cần tạo lời nhắc hệ thống:
var systemInstruction = Content.newBuilder()
.setRole("system")
.addParts(Part.newBuilder().setText("You are a helpful assistant."))
.build();
Tạo thực thể cho mô hình bằng GenerativeModel
:
var generativeModel = new GenerativeModel(
llmInferenceBackend,
systemInstruction,
List.of(tool),
)
Bắt đầu phiên trò chuyện
Để đơn giản, hướng dẫn bắt đầu nhanh này sẽ bắt đầu một phiên trò chuyện. Bạn cũng có thể tạo nhiều phiên độc lập.
Sử dụng thực thể mới của GenerativeModel
, hãy bắt đầu một phiên trò chuyện:
var chat = generativeModel.startChat();
Gửi lời nhắc đến mô hình thông qua phiên trò chuyện bằng phương thức sendMessage
:
var response = chat.sendMessage("How's the weather in San Francisco?");
Phân tích cú pháp phản hồi của mô hình
Sau khi truyền một lời nhắc đến mô hình, ứng dụng phải kiểm tra phản hồi để xác định xem có thực hiện lệnh gọi hàm hay xuất văn bản ngôn ngữ tự nhiên hay không.
// 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 response = chat.sendMessage(functionResponse);
} else if (message.hasText()) {
Log.i(message.getText());
}
Mã mẫu là một cách triển khai quá đơn giản. Để biết thêm thông tin về cách một ứng dụng có thể kiểm tra phản hồi của mô hình, hãy xem phần Định dạng và phân tích cú pháp.
Cách hoạt động
Phần này cung cấp thông tin chuyên sâu hơn về các khái niệm và thành phần cốt lõi của SDK Gọi hàm cho Android.
Mô hình
SDK Gọi hàm yêu cầu một mô hình có trình định dạng và trình phân tích cú pháp. SDK FC chứa trình định dạng và trình phân tích cú pháp tích hợp sẵn cho các mô hình sau:
Để sử dụng một mô hình khác với SDK FC, bạn phải phát triển trình định dạng và trình phân tích cú pháp của riêng mình tương thích với API suy luận LLM.
Định dạng và phân tích cú pháp
Một phần quan trọng của tính năng hỗ trợ gọi hàm là định dạng lời nhắc và phân tích cú pháp đầu ra của mô hình. Mặc dù đây là hai quy trình riêng biệt, nhưng SDK FC xử lý cả việc định dạng và phân tích cú pháp bằng giao diện ModelFormatter
.
Trình định dạng chịu trách nhiệm chuyển đổi các nội dung khai báo hàm có cấu trúc thành văn bản, định dạng các phản hồi hàm và chèn mã thông báo để cho biết điểm bắt đầu và kết thúc lượt trò chuyện, cũng như vai trò của các lượt trò chuyện đó (ví dụ: "người dùng", "mô hình").
Trình phân tích cú pháp có trách nhiệm phát hiện xem phản hồi của mô hình có chứa lệnh gọi hàm hay không. Nếu phát hiện lệnh gọi hàm, trình phân tích cú pháp sẽ phân tích cú pháp lệnh gọi đó thành một loại dữ liệu có cấu trúc. Nếu không, ứng dụng sẽ coi văn bản đó là một câu trả lời bằng ngôn ngữ tự nhiên.
Giải mã có điều kiện
Giải mã có điều kiện là một kỹ thuật hướng dẫn quá trình tạo đầu ra của LLM để đảm bảo đầu ra tuân thủ một định dạng có cấu trúc được xác định trước, chẳng hạn như đối tượng JSON hoặc lệnh gọi hàm Python. Bằng cách thực thi các quy tắc ràng buộc này, mô hình sẽ định dạng đầu ra sao cho phù hợp với các hàm được xác định trước và các loại tham số tương ứng.
Để bật tính năng giải mã có điều kiện, hãy xác định các điều kiện ràng buộc trong đối tượng ConstraintOptions
và gọi phương thức enableConstraint
của thực thể ChatSession
.
Khi được bật, quy tắc ràng buộc này sẽ hạn chế phản hồi chỉ bao gồm các công cụ liên kết với GenerativeModel
.
Ví dụ sau đây minh hoạ cách định cấu hình giải mã có điều kiện để hạn chế phản hồi đối với các lệnh gọi công cụ. Hàm này ràng buộc lệnh gọi công cụ bắt đầu bằng tiền tố ```tool_code\n
và kết thúc bằng hậu tố \n```
.
ConstraintOptions constraintOptions = ConstraintOptions.newBuilder()
.setToolCallOnly( ConstraintOptions.ToolCallOnly.newBuilder()
.setConstraintPrefix("```tool_code\n")
.setConstraintSuffix("\n```"))
.build();
chatSession.enableConstraint(constraintOptions);
Để tắt quy tắc ràng buộc đang hoạt động trong cùng một phiên, hãy sử dụng phương thức disableConstraint
:
chatSession.disableConstraint();