Genkit Dart 발표: Dart와 Flutter로 풀스택 AI 앱 만들기

Genkit Dart 발표: Dart와 Flutter로 풀스택 AI 앱 만들기

Genkit Dart의 프리뷰 출시 소식을 전해 드릴게요. 어떤 플랫폼에서든 풀스택 AI 앱을 만들 수 있는 오픈소스 AI 프레임워크예요. Dart와 Flutter 커뮤니티는 언제나 스크린을 넘어서 가능한 것의 경계를 넓혀 왔어요. 고품질 멀티 플랫폼 앱을 만드는 데 개발자 경험을 희생할 필요가 없다는 걸 보여 주셨죠. 이제 우리는 그런 '한 번 작성하면 어디서든 실행되는'(write once, run anywhere) 철학을 AI 기능과 애플리케이션으로 가져오고 있어요.

TypeScript, Go, Python에서 이미 사용 가능했던 Genkit가 이제 Dart와 Flutter 개발자를 위해 어떤 플랫폼에서든 고품질 풀스택 AI 앱을 만들 수 있게 해 줍니다.

출처: Announcing Genkit Dart: Build full-stack AI apps with Dart and Flutter

본문

왜 Genkit Dart인가요?

Genkit Dart는 다음과 같은 역량을 제공해요.

  • 모델에 구애받지 않는 API(Model-agnostic API): Google, Anthropic, OpenAI, 그리고 OpenAI API 호환 모델을 기본으로 지원해요. 단 하나의 제공자에게 묶이지 않아요.
  • 타입 안전: Dart의 강력한 타입 시스템을 schemantic 패키지와 함께 사용해 강력하게 타입이 지정된 데이터를 만들고 타입 안전한 AI 흐름(flows)을 만들어요.
  • 어디서든 코드 실행: AI 로직을 한 번 작성하면 백엔드 서비스로, 또는 Flutter 앱 안에서 직접 실행할 수 있어요.
  • 개발자 UI: 프롬프트를 테스트하고, 트레이스를 보고, 흐름을 디버깅할 수 있는 로컬호스트 웹 UI를 제공해요.
  • 완전한 AI 툴킷: 구조화된 출력, 도구, 다단계 흐름, 관측 가능성(observability) 등 고품질 AI 기능을 만드는 데 필요한 모든 것을 제공해요.

모델에 구애받지 않는 API

Genkit는 어떤 LLM 제공자든 지원하도록 설계되었어요. 이번 릴리스에서는 Google, Anthropic, OpenAI, OpenAI API 호환 모델을 기본으로 지원하죠. 그래서 최소한의 코드 변경으로 제공자를 전환할 수 있어요.

import 'package:genkit/genkit.dart';
import 'package:genkit_google_genai/genkit_google_genai.dart';
import 'package:genkit_anthropic/genkit_anthropic.dart';

void main() async {
  // Initialize Genkit with plugins
  final ai = Genkit(plugins: [
    googleAI(),
    anthropic(),
  ]);

  // Call Google Gemini
  final geminiResponse = await ai.generate(
    model: googleAI.gemini('gemini-3.1-pro-preview'),
    prompt: 'Hello from Gemini',
  );

  // Call Anthropic Claude
  final claudeResponse = await ai.generate(
    model: anthropic.model('claude-opus-4.6'),
    prompt: 'Hello from Claude',
  );
}

타입 안전한 AI 흐름(flows)

Genkit는 AI 로직을 테스트 가능하고, 관찰 가능하며, 배포 가능한 함수인 flow로 감쌀 수 있게 해 줘요. 다음은 도구 호출을 사용하고, 강력하게 타입이 지정된 입력/출력 스키마를 지닌 Travel Planner 흐름의 예시예요.

import 'package:genkit/genkit.dart';
import 'package:genkit_google_genai/genkit_google_genai.dart';
import 'package:schemantic/schemantic.dart';

part 'travel_flow.g.dart';

// Define flow input schema with schemantic
@Schema()
abstract class $TripRequest {
  String get destination;
  int get days;
}

// Define tool input schema
@Schema()
abstract class $WeatherRequest {
  @Field(description: 'The city name')
  String get city;
}

void main() async {
  // Initialize Genkit and register the Google AI plugin
  final ai = Genkit(plugins: [googleAI()]);

  // Define a tool the model can invoke to fetch live data
  ai.defineTool(
    name: 'fetchWeather',
    description: 'Retrieves the current weather forecast for a given city',
    inputSchema: WeatherRequest.$schema,
    fn: (request, _) async => request.city.toLowerCase() == 'seattle' ? 'Rainy' : 'Sunny',
  );

  // Construct a strongly-typed, observable flow
  final tripPlannerFlow = ai.defineFlow(
    name: 'planTrip',
    inputSchema: TripRequest.$schema,
    outputSchema: .string(),
    fn: (request, _) async {
      // Generate content using the model and tool
      final response = await ai.generate(
        model: googleAI.gemini('gemini-3.1-pro-preview'),
        prompt: 'Build a ${request.days}-day travel itinerary for ${request.destination}. '
                'Make sure to check the weather forecast first to suggest appropriate activities.',
        toolNames: ['fetchWeather'],
      );

      return response.text;
    },
  );

  // Run the flow
  final itinerary = await tripPlannerFlow(
    TripRequest(destination: 'Seattle', days: 3)
  );
  print(itinerary);
}

준비가 되면 genkit_shelf 패키지를 사용해 흐름을 API로 쉽게 노출하고, Dart를 지원하는 어떤 플랫폼에든 배포할 수 있어요.

import 'package:genkit_shelf/genkit_shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf_io.dart' as io;

void main() async {
  // ... initialize Genkit and define tripPlannerFlow ...

  final router = Router()
    ..post(
      '/api/planTrip',
      shelfHandler(tripPlannerFlow),
    );

  await io.serve(router.call, 'localhost', 8080);
}

Dart가 실행되는 어디든

대부분의 복잡한 AI 로직은 서버에서 실행돼요. 하지만 Dart가 프런트엔드와 백엔드 양쪽에서 동작하기 때문에, Genkit로 AI 코드를 서버와 Flutter 앱 사이에서 쉽게 옮길 수 있어요. Genkit Dart로 만들 수 있는 몇 가지 방법을 살펴볼게요.

1. 프로토타이핑을 위해 전부 Flutter 안에서

모델 호출을 포함한 모든 Genkit 로직을 Flutter 앱 안에서 직접 작성할 수 있어요. 프로토타입이나 사용자가 자신의 API 키를 제공하고 프롬프트가 비공개가 아닌 앱에 아주 좋아요.

경고: 소스 코드에 API 키를 박아 넣은 앱을 게시하면 안 돼요. API 키가 추출되어 다른 사람이 사용할 수 있으니까요.

2. Flutter에서 백엔드 흐름 호출하기

프롬프트가 민감하거나 AI 로직이 복잡하다면 전체 흐름을 백엔드로 옮길 수 있어요. 그러면 Flutter 앱이 이 흐름을 "remote action"으로 정의해서 호출할 수 있어요. 백엔드와 프런트엔드가 모두 Dart이므로, 같은 스키마를 공유해 끝에서 끝까지(end-to-end) 타입 안전을 얻을 수 있죠. 앞서 정의한 Trip Planner 백엔드 흐름을 Flutter 앱에서 호출하는 예시를 볼게요.

import 'package:genkit/client.dart';
import 'package:my_shared_models/models.dart'; // Shared schema

final tripPlannerFlow = defineRemoteAction(
  url: 'https://your-server.com/api/planTrip',
  inputSchema: TripRequest.$schema,
  outputSchema: .string(),
);

final itinerary = await tripPlannerFlow(
  input: TripRequest(destination: 'Tokyo', days: 5),
);

3. Flutter에서 원격 모델 사용하기

API 키를 안전하게 지키면서 핵심 AI 로직은 Flutter 앱에 두고 싶다면, 커스텀 인증 로직으로 모델 제공자에 요청을 프록시하는 작은 Genkit 백엔드를 만들 수 있어요. 이 백엔드를 통해 노출되는 모델을 remote models(원격 모델)이라고 해요.

import 'package:genkit_google_genai/genkit_google_genai.dart';
import 'package:genkit_shelf/genkit_shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf_io.dart' as io;

// Backend securely proxies requests to the model
void main() async {
  final geminiApi = googleAI();
  final targetModel = geminiApi.model('gemini-3.1-flash-lite-preview');
  final router = Router()
    ..post(
      '/api/gemini-model',
      shelfHandler(
        targetModel,
        // Insert custom authorization logic here
        contextProvider: (req) async => {'customAuth': true},
      ),
    );
  await io.serve(router.call, 'localhost', 8080);
}

Flutter 앱에서는 직접 모델 플러그인 대신 원격 모델을 사용하고, 서버가 필요한 헤더를 전달해 주면 돼요. 이렇게 하면 API 키를 노출하지 않아도 되고 요청 인증을 더 잘 제어할 수 있어요.

import 'package:genkit/genkit.dart';

// Flutter app communicates with the proxy server
final ai = Genkit();
final secureModel = ai.defineRemoteModel(
  name: 'secureModel',
  url: 'https://api.yourdomain.com/api/gemini-model',
  headers: (context) => {'Authorization': 'Bearer ${fetchSessionToken()}'},
);
final response = await ai.generate(model: secureModel, prompt: 'Write me a poem.');

AI 개발을 위한 강력한 도구

고품질 AI 애플리케이션을 만들려면 신뢰할 수 있는 결과를 얻기 위해 철저한 테스트와 지속적인 반복이 필요해요. 이를 돕기 위해 Genkit는 강력한 로컬 개발자 UI(Developer UI)를 제공해요.

앱을 Genkit CLI로 실행하면 코드와 함께 개발자 UI를 시작할 수 있어요.

genkit start -- dart run bin/server.dart

Trip Planner 흐름의 더 발전된 버전을 개발자 UI에서 테스트하는 모습도 살펴볼 수 있어요.

AI 코딩 지원

Antigravity, Gemini CLI, Claude Code 같은 AI 코딩 도구에서 Genkit Dart를 최상의 경험으로 사용하려면 Genkit Dart 에이전트 스킬을 설치하세요. AI 어시스턴트가 여러분의 AI 기능을 정확하게 작성하고 디버깅하는 데 필요한 지식을 얻게 돼요.

프로젝트에 스킬을 추가해 보세요.

npx skills add genkit-ai/skills

더 알아보기

이번 릴리스는 조기 프리뷰예요. 프레임워크를 개선하기 위해 Dart와 Flutter 개발자들과 함께 일하고 싶어요. 핵심 패키지와 제공자 플러그인은 지금 pub.dev에서 찾을 수 있어요.

  • 시작하기: quickstart 가이드를 읽어 보세요.
  • 커뮤니티 참여: Discord 서버에 참여해 질문하고 팀과 대화해 보세요.
  • 최신 소식 받기: X와 LinkedIn에서 팔로우해 주세요.
  • 피드백 주기: GitHub 저장소에 이슈를 열어 버그를 보고하거나 기능을 요청해 주세요.

Genkit Dart로 무엇을 만들어 주실지 정말 기대됩니다!

더 알아보기

  • pub.dev에서 Genkit Dart 핵심 패키지와 제공자 플러그인 찾아보기
  • Genkit Dart quickstart 가이드를 읽고 첫 풀스택 AI 앱 만들어 보기