원격 구성을 사용하여 버전 템플릿


서버 프롬프트 템플릿을 사용하면 앱의 새 버전을 출시하지 않고도 지정된 템플릿 내에서 값을 업데이트할 수 있습니다. 하지만 템플릿에 대한 변경사항은 앱의 요청에 의해 거의 즉시 사용되므로 앱을 중단하거나 예상치 못한 동작 변경을 일으킬 수 있는 변경사항을 적용할 때는 주의해야 합니다.

따라서 더 큰 변경사항을 적용하거나 변경사항을 점진적으로 출시하려면 프로덕션 코드에 사용되는 템플릿을 변경하지 않는 것이 좋습니다.

대신 Firebase Remote Config를 사용하여 모델에 대한 요청에 사용되는 템플릿 ID 값을 제어하는 것이 좋습니다.

Firebase Remote Config을 사용하면 앱의 새 버전을 출시하지 않고도 Firebase 콘솔에서 앱의 파라미터 값 (예: 템플릿 ID)을 동적으로 원격으로 업데이트할 수 있습니다. 또한 변경사항 출시 및 A/B 테스트를 위한 간소화된 기능과 통합도 제공됩니다.

이 가이드에서는 앱에서 Remote Config를 구현하는 방법, 특히 앱에서 사용되는 템플릿 ID를 제어하는 방법을 설명합니다.

1단계: Firebase 콘솔에서 파라미터 값 설정

Remote Config 클라이언트 템플릿을 만들고 앱에서 가져와 사용할 template_id 매개변수와 값을 구성합니다.

  1. Firebase Console에서 Firebase 프로젝트를 열고 탐색 메뉴에서 실행을 펼치고 Remote Config을 선택합니다.

  2. 페이지 상단의 클라이언트/서버 선택기에서 클라이언트가 선택되어 있는지 확인합니다.

  3. 구성 만들기(또는 이전에 클라이언트 템플릿을 사용한 적이 있는 경우 파라미터 추가)를 클릭하여 클라이언트 템플릿을 시작합니다.

  4. template_id 매개변수를 정의합니다.

    매개변수 이름 설명 유형 기본값
    template_id 템플릿 ID입니다. 문자열 my-first-template-v1-0-0
  5. 이 매개변수를 추가한 후 변경사항 게시를 클릭합니다. 새 Remote Config 템플릿이 아닌 경우 변경사항을 검토하고 변경사항 게시를 다시 클릭합니다.

2단계: 앱에 Remote Config 추가 및 초기화

Remote Config 라이브러리를 추가하고 앱 내에서 Remote Config을 설정합니다.

Swift

Firebase AI Logic 설정의 일환으로 이미 Firebase SDK를 앱에 추가했지만 Remote Config도 추가해야 합니다.

  1. Xcode에서 프로젝트를 연 상태로 파일 > 패키지 종속 항목 추가로 이동합니다.

  2. firebase-ios-sdk를 선택한 다음 패키지 추가를 클릭합니다.

  3. 프로젝트 탐색기에서 앱 > 대상 > 앱을 선택합니다.

  4. 일반 탭에서 프레임워크, 라이브러리, 삽입된 콘텐츠로 스크롤합니다.

  5. +를 클릭하고 FirebaseRemoteConfig를 선택한 다음 추가를 클릭합니다.

  6. 코드에 FirebaseRemoteConfig 가져오기를 추가합니다.

    import FirebaseRemoteConfig
    
  7. 앱에 적합한 클래스에서 Firebase를 초기화하고 기본 애플리케이션 로직에 Remote Config을 추가합니다.

    여기서는 앱이 실시간으로 새 값을 가져올 수 있도록 Remote ConfigRemote Config 실시간 리스너를 가져오기로 포함하고 최소 가져오기 간격을 추가합니다.

    let remoteConfig = RemoteConfig.remoteConfig()
    let settings = RemoteConfigSettings()
    settings.minimumFetchInterval = 3600
    remoteConfig.configSettings = settings
    

Kotlin

  1. 모듈(앱 수준) Gradle 파일(일반적으로 app/build.gradle.kts 또는 app/build.gradle)에 Remote Config 종속 항목을 추가합니다.

    dependencies {
        implementation(platform("com.google.firebase:firebase-bom:34.5.0"))
        implementation("com.google.firebase:firebase-ai")
        implementation("com.google.firebase:firebase-config")
        // ... other dependencies
    }
    
  2. 기본 애플리케이션 로직에 Remote Config을 추가합니다. 여기서는 Remote Config을 초기화하고 최소 가져오기 간격을 추가합니다.

    val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig
    val configSettings = remoteConfigSettings {
    minimumFetchIntervalInSeconds = 3600
    }
    remoteConfig.setConfigSettingsAsync(configSettings)
    

Java

  1. 모듈(앱 수준) Gradle 파일(일반적으로 app/build.gradle.kts 또는 app/build.gradle)에 Remote Config 종속 항목을 추가합니다.

    dependencies {
        implementation(platform("com.google.firebase:firebase-bom:34.5.0"))
        implementation("com.google.firebase:firebase-ai")
        implementation("com.google.firebase:firebase-config")
        // ... other dependencies
    }
    
  2. 기본 애플리케이션 로직에 Remote Config을 추가합니다. 여기서는 Remote Config을 초기화하고 최소 가져오기 간격을 추가합니다.

    FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
    FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
        .setMinimumFetchIntervalInSeconds(3600)
        .build();
    mFirebaseRemoteConfig.setConfigSettingsAsync(configSettings);
    

Web

  1. 텍스트 편집기에서 코드를 열고 Remote Config을 가져옵니다.

    import { getRemoteConfig } from 'firebase/remote-config';
    
  2. 기본 함수 내에서 Firebase AI Logic SDK에 대해 Firebase 앱이 초기화된 후 Remote Config을 초기화합니다.

      // Initialize Remote Config and get a reference to the service
      const remoteConfig = getRemoteConfig(app);
    
  3. 가져오기 간격 최솟값을 설정합니다.

    remoteConfig.settings.minimumFetchIntervalMillis = 3600000;
    

3단계: 인앱 파라미터 값 설정

Remote Config 객체에서 인앱 기본 파라미터 값을 설정해야 합니다. 이렇게 하면 앱이 Remote Config 서비스에서 값을 가져올 수 없더라도 예상대로 동작합니다.

Swift

  1. Firebase Console에서 Remote Config을 엽니다.

  2. 파라미터 탭에서 메뉴를 열고 기본값 다운로드를 선택합니다.

  3. 메시지가 표시되면 iOS의 경우 .plist를 사용 설정하고 파일 다운로드를 클릭합니다.

  4. 애플리케이션 디렉터리에 파일을 저장합니다.

  5. Xcode에서 앱을 마우스 오른쪽 버튼으로 클릭하고 파일 추가를 선택합니다.

  6. remote_config_defaults.plist를 선택한 다음 추가를 클릭합니다.

  7. 기본 파일을 참조하도록 앱 코드를 업데이트합니다.

    // Set default values for Remote Config parameters.
    remoteConfig.setDefaults(fromPlist: "remote_config_defaults")
    

Kotlin

  1. Firebase Console에서 Remote Config을 엽니다.

  2. 매개변수 탭에서 메뉴를 열고 기본값 다운로드를 선택합니다.

  3. 메시지가 표시되면 Android의 경우 .xml을 사용 설정한 후 파일 다운로드를 클릭합니다.

  4. 앱의 XML 리소스 디렉터리에 파일을 저장합니다.

  5. 이전에 추가한 configSettings 뒤에 기본값을 추가하도록 기본 활동 파일을 업데이트합니다.

    // Set default values for Remote Config parameters.
    remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults)
    

Java

  1. Firebase Console에서 Remote Config을 엽니다.

  2. 매개변수 탭에서 메뉴를 열고 기본값 다운로드를 선택합니다.

  3. 메시지가 표시되면 Android의 경우 .xml을 사용 설정한 후 파일 다운로드를 클릭합니다.

  4. 앱의 XML 리소스 디렉터리에 파일을 저장합니다.

  5. 이전에 추가한 configSettings 뒤에 기본값을 추가하도록 기본 활동 파일을 업데이트합니다.

    // Set default values for Remote Config parameters.
    mFirebaseRemoteConfig.setDefaultsAsync(R.xml.remote_config_defaults);
    

Web

코드에서 직접 모델 이름의 기본값을 설정할 수 있습니다.

// Set default values for Remote Config parameters.
remoteConfig.defaultConfig = {
  template_id: 'my-first-template-v1-0-0',
};

4단계: 값 가져오기 및 활성화

모델 이름의 기본값을 설정한 후 다음을 추가하여 값을 가져오고 활성화합니다.

Swift

// Fetch and activate Remote Config values
remoteConfig.fetchAndActivate { status, error in
  if let error = error {
    print("Error fetching Remote Config: \(error.localizedDescription)")
  }
}

이렇게 하면 새 Remote Config 템플릿이 게시될 때마다 Remote Config 객체가 업데이트됩니다.

Kotlin

// Fetch and activate Remote Config values
remoteConfig.fetchAndActivate()
      .addOnCompleteListener(this) { task ->
          if (task.isSuccessful) {
              val updated = task.result
              Log.d(TAG, "Remote Config values fetched and activated: $updated")
          } else {
              Log.e(TAG, "Error fetching Remote Config", task.exception)
          }
      }

Java

  // Fetch and activate Remote Config values
  mFirebaseRemoteConfig.fetchAndActivate()
    .addOnCompleteListener(this, new OnCompleteListener<Boolean>() {
        @Override
        public void onComplete(@NonNull Task<Boolean> task) {
            if (task.isSuccessful()) {
                boolean updated = task.getResult();
                Log.d(TAG, "Config params updated: " + updated);
            } else {
                Log.e(TAG, "Error fetching Remote Config", task.exception)
            }
          }
    });

Web

  1. 가져오기에 getValuefetchAndActivate를 추가합니다.

    import { getValue, fetchAndActivate } from 'firebase/remote-config';
    
  2. 모델 이름의 기본값을 지정하는 코드를 찾습니다. 해당 코드 블록 바로 뒤에 다음 코드를 추가하여 구성을 가져와 활성화하고 가져온 값을 templateID 상수에 할당합니다.

    // Fetch and activate Remote Config.
    try {
      await fetchAndActivate(remoteConfig);
    } catch(err) {
      console.error('Remote Config fetch failed', err);
    }
    
    console.log('Remote Config fetched.');
    
    // Assign Remote Config values.
    const templateID = getValue(remoteConfig, 'template_id').asString();
    

5단계: 실시간 Remote Config 리스너 추가

Remote Config 템플릿에 적용한 변경사항이 업데이트되는 즉시 클라이언트로 전파되도록 앱에 실시간 Remote Config 리스너를 추가합니다.

다음 코드는 파라미터 값이 변경될 때마다 Remote Config 객체를 업데이트합니다.

Swift

// Add real-time Remote Config
remoteConfig.addOnConfigUpdateListener { configUpdate, error in
  guard let configUpdate = configUpdate, error == nil else {
    print("Error listening for config updates: \(error?.localizedDescription ?? "No error available")")
    return
  }

  print("Updated keys: \(configUpdate.updatedKeys)")
  remoteConfig.activate { changed, error in
    guard error == nil else {
      print("Error activating config: \(error?.localizedDescription ?? "No error available")")
      return
    }
    print("Activated config successfully")
  }
}

Kotlin

원하는 경우 addOnCompleteListener 활성화 내에서 작업을 구성할 수도 있습니다.

      // Add a real-time Remote Config listener
      remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {
          override fun onUpdate(configUpdate : ConfigUpdate) {
              Log.d(ContentValues.TAG, "Updated keys: " + configUpdate.updatedKeys);
              remoteConfig.activate().addOnCompleteListener {
                  // Optionally, add an action to perform on update here.
              }
          }

          override fun onError(error : FirebaseRemoteConfigException) {
              Log.w(ContentValues.TAG, "Config update error with code: " + error.code, error)
          }
      }

Java

원하는 경우 addOnCompleteListener 활성화 내에서 작업을 구성할 수도 있습니다.

  // Add a real-time Remote Config listener
  remoteConfig.addOnConfigUpdateListener(new ConfigUpdateListener() {
      @Override
      public void onUpdate(ConfigUpdate configUpdate) {
          Log.d(ContentValues.TAG, "Updated keys: " + configUpdate.getUpdatedKeys());
                remoteConfig.activate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
                  @Override
                  public void onComplete(@NonNull Task<Boolean> task) {
                      // Optionally, add an action to perform on update here.
                  }
              });
          }

      @Override
      public void onError(FirebaseRemoteConfigException error) {
          Log.w(ContentValues.TAG, "Config update error with code: " + error.getCode(), error);
      }
  });

Web

웹 앱에는 실시간 Remote Config 리스너가 지원되지 않습니다.

6단계: Remote Config 값을 사용하도록 Gemini API 요청 업데이트

Gemini API 제공업체를 클릭하여 이 페이지에서 제공업체별 콘텐츠와 코드를 확인합니다.

이제 Remote Config이 완전히 구성되었으므로 하드코딩된 값을 Remote Config에서 가져온 값으로 대체하도록 코드를 업데이트합니다.

Swift

import FirebaseAI

let templateID = remoteConfig.configValue(forKey: "template_id").stringValue
let model = FirebaseAI.firebaseAI(backend: .googleAI()).templateGenerativeModel()
let customerName = "Jane"

// When making the `generateContent` call, source the template ID value from Remote Config
let response = try await model.generateContent(
  templateID: templateID,
  // Provide the values for any input variables required by your template.
  inputs: [
    "customerName": customerName
  ]
)

// ...

Kotlin

// ...

val model = Firebase.ai().templateGenerativeModel()
val customerName = "Jane"

// When making the `generateContent` call, source the template ID value from Remote Config
val response = model.generateContent(
  remoteConfig.getString("template_id"),
  // Provide the values for any input variables required by your template.
  mapOf(
    "customerName" to customerName
  )
)

val text = response.text
println(text)

Java

// ...

TemplateGenerativeModel ai = FirebaseAI.getInstance()
    .templateGenerativeModel(null /* Request Options */);

TemplateGenerativeModelFutures model = TemplateGenerativeModelFutures.from(ai);
String customerName = "Jane";

// When making the `generateContent` call, source the template ID value from Remote Config
Future<GenerateContentResponse> response = model.generateContent(
    remoteConfig.getString("template_id"),
    // Provide the values for any input variables required by your template.
    mapOf("customerName", customerName)

);
addCallback(response,
      new FutureCallback<GenerateContentResponse>() {
          public void onSuccess(GenerateContentResponse result) {
            System.out.println(result.getText());
          }
          public void onFailure(Throwable t) {
            reportError(t);
          }
    }
executor);

// ...

Web

// ...

const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

const model = getTemplateGenerativeModel(ai);
const templateID = getValue(remoteConfig, 'template_id').asString();
const customerName = 'Jane';

// When making the `generateContent` call, source the template ID value from Remote Config
const result = await model.generateContent(
  templateID,
  // Provide the values for any input variables required by your template
  {
    customerName: customerName,
  }
);

// ...

7단계: 앱 실행

앱을 빌드하고 실행하여 작동하는지 확인합니다. Firebase Console의 Remote Config 페이지에서 구성을 변경하고 변경사항을 게시한 후 결과를 확인합니다.

다음 단계