โซลูชัน

สร้างแอปวางแผนการเดินทางที่ขับเคลื่อนโดยตัวแทนด้วย Generative AI

แผนภาพต่อไปนี้แสดงภาพรวมระดับสูงของวิธีผสานรวมบริการที่ดีที่สุดจากบริษัทสำหรับนักพัฒนาแอปของ Google เพื่อสร้างแอปพลิเคชันที่ขับเคลื่อนด้วย AI

สร้างแอปที่สวยงามที่ทำงานด้วยระบบ AI สำหรับอุปกรณ์เคลื่อนที่และเว็บ

คุณใช้ Flutter และ Firebase Genkit เพื่อสร้างแอปหลายแพลตฟอร์มที่ผสานรวมกับ AI ได้อย่างราบรื่น
คุณใช้ Genkit เพื่อให้แอปใช้ข้อมูลจาก LLM ได้อย่างมั่นใจด้วยการกำหนดสคีมาที่ตรวจสอบเอาต์พุตของ LLM ได้ ใน Flutter คุณสามารถใช้ Dart เพื่อเรียงลำดับคำขอและดีซีเรียลการตอบกลับเพื่อให้ตรงกับสคีมา Genkit โดยใช้คำขอ HTTP มาตรฐาน
เมื่อใช้ IDX คุณจะสร้างแอป Flutter ได้โดยไม่ต้องติดตั้งซอฟต์แวร์ใดๆ ซึ่งจะทำให้สามารถพัฒนาและทดสอบแอป Android และเว็บแอปในเบราว์เซอร์ได้
Firebase Data Connect เป็นบริการฐานข้อมูลเชิงสัมพันธ์สำหรับแอปบนอุปกรณ์เคลื่อนที่และเว็บแอปที่ให้คุณสร้างและปรับขนาดโดยใช้ฐานข้อมูล PostgreSQL ที่มีการจัดการโดยสมบูรณ์ซึ่งขับเคลื่อนโดย Cloud SQL โดยมีสคีมา การค้นหา และการจัดการการเปลี่ยนแปลงที่ปลอดภัยโดยใช้ GraphQL ซึ่งผสานรวมกับการตรวจสอบสิทธิ์ Firebase ได้อย่างมีประสิทธิภาพ Data Connect รองรับ SDK สําหรับ Kotlin Android และเว็บ

สร้างตัวแทนด้วย Firebase Genkit

Agent จะใช้เฟรมเวิร์ก AI เป็นกลุ่มเพื่อรับความคิดเห็นจากผู้ใช้และสร้างคำตอบ
---
model: googleai/gemini-1.5-flash-latest
config:
  temperature: 1.0
  safetySettings:
    - category: HARM_CATEGORY_HATE_SPEECH
      threshold: BLOCK_LOW_AND_ABOVE
    - category: HARM_CATEGORY_DANGEROUS_CONTENT
      threshold: BLOCK_ONLY_HIGH
    - category: HARM_CATEGORY_HARASSMENT
      threshold: BLOCK_LOW_AND_ABOVE
    - category: HARM_CATEGORY_SEXUALLY_EXPLICIT
      threshold: BLOCK_LOW_AND_ABOVE
input:
  schema:
    request: string, The users request for where they want to travel to.
    place: string, The place that closely represents the users request.
    placeDescription: string, A description of that place.
    activities(array, a stringify list of activities that can be found at the specified place): string
    restaurants?(array, a stringify list of all the restaurants found at that location): string
output:
  schema:
    place: string, The place the user is traveling to.
    itineraryName: string, a catchy itinerary name that encapsulates the spirit of the trip and includes the place name
    startDate: string, the start date of the trip
    endDate: string, the end date of the trip
    tags(array, relevant tags for the trip): string
    itinerary(array):
      day: number
      date: string
      planForDay(array):
        activityRef: string, the reference value for the activity - this comes from the available activities JSON. If no value is present use a ref value of restaurant.
        activityTitle: string, a catchy title for the activity
        activityDesc: string, a six word description of the activity
        photoUri?: string, set the photo uri value for restaurants only.
        googleMapsUri?: string, if this is a restaurant include the googleMapsUri
---

Generate an itinerary for a tourist planning on traveling to the location specified based in their request.
If there is something that does not exist within the list of activities, do not include it in your answer.
Feel free to relate the activitiy to the request in a meaningful way.
In the plan for day array, put activities as a travel brouchure might do.
Come up with a catchy name for the itinerary.

Pick three activities per day, minimum of three day trip unless otherwise specified in the request.

Output schema should not include the properties type or object.

Pick a date after 2024-05-14 but before 2024-12-31.

The output date must be in the format year-month-day.

Give each activity a unique title and description.

Limit activity descriptions to 6 words.

If no restaurants are supplied, do not recommend any restaurants to eat at.

{{#if restaurants}}
Find a restaurant to eat at each day.

Include a restaurant to visit in the itinerary for each day from the available restaurants.
The restaurant should be the only activity with a photoUri.
The photoUri for the restaurant should be from the photoUri property from the restaurant array.
If there are no restaurants to pick from, do not include it in the list.

The photoUri from the restaurantFinder should be in the format of places/${placeId}/photos/${photoId}

Each restaurant should be unique to the overall itinerary.
Each restaurant must contain a photoUri in their output JSON schema.
Each restaurant must also include  an activitiyRef, activityTitle, and activityDesc in their output
{{/if}}
Output must be in JSON format.

REQUEST : {{request}}
PLACE : {{place}}
PLACE DESCRIPTION : {{placeDescription}}
AVAILABLE ACTIVITIES : {{activities}}
RESTAURANTS : {{restaurants}}
เมื่อทำงานกับ Generative AI สิ่งสำคัญคือต้องสร้างพรอมต์ที่มีประสิทธิภาพเพื่อให้โมเดลส่งคืนคำตอบที่มีคุณภาพสูง Firebase Genkit มีปลั๊กอิน Dotprompt และรูปแบบข้อความเพื่อช่วยคุณเขียนและจัดระเบียบพรอมต์ Generative AI รูปแบบจะสรุปพรอมต์ สคีมาอินพุตและเอาต์พุต โมเดล และการกำหนดค่าทั้งหมดไว้ในไฟล์เดียว

ตัวอย่างโค้ดต่อไปนี้แสดงไฟล์ Dotprompt ที่ใช้ในแอปท่องเที่ยว โดยสคีมาจะอิงตามข้อมูลที่ผู้ใช้ให้ไว้เมื่ออธิบายทริปในฝัน
Dotprompt ได้รับการออกแบบมารอบๆ พื้นที่ที่ข้อความแจ้งเป็นโค้ด จากนั้นเขียนและเก็บรักษาพรอมต์ในไฟล์ที่มีรูปแบบพิเศษที่เรียกว่าไฟล์ .comtprompt ติดตามการเปลี่ยนแปลงของพรอมต์โดยใช้ระบบควบคุมเวอร์ชันเดียวกันกับที่คุณใช้สำหรับโค้ด และทำให้ใช้งานได้พร้อมกับโค้ดที่เรียกใช้โมเดล Generative AI
โฟลว์เป็นฟังก์ชันที่พิมพ์อย่างเข้มงวด สตรีมได้ เรียกใช้ได้ในเครื่องและจากระยะไกล และสังเกตได้ทั้งหมด Firebase Genkit มีอินเทอร์เฟซบรรทัดคำสั่งและ UI ของนักพัฒนาซอฟต์แวร์สำหรับการดำเนินการกับโฟลว์ เช่น การเรียกใช้หรือการแก้ไขข้อบกพร่องของโฟลว์
import {defineTool} from '@genkit-ai/ai/tool';
...
{
  name: 'restaurantFinder',
  description: `Used when needing to find a restaurant based on a users location.
  The location should be used to find nearby restaurants to a place. You can also
  selectively find restaurants based on the users preferences, but you should default
  to 'Local' if there are no indications of restaurant types in the users request.
  `,
  inputSchema: z.object({
    place: z.string(),
    typeOfRestaurant: z.string().optional() }),
    outputSchema: z.unknown(),
},
...
async (input) => {
  if (input.typeOfRestaurant == undefined) {
    input.typeOfRestaurant = "Local";
  }
  const geocodeEndpoint = "https://places.googleapis.com/v1/places:searchText";
  const textQuery = {textQuery: `${input.typeOfRestaurant} restaurants in ${input.place}`};

  const  response = await axios.post(
    geocodeEndpoint,
    JSON.stringify(textQuery),
    {
      headers: {
        "Content-Type": "application/json",
        "X-Goog-Api-Key": MAPS_API_KEY,
        "X-Goog-FieldMask": "places.displayName,places.formattedAddress,places.priceLevel,places.photos.name,places.editorialSummary,places.googleMapsUri"
      }
    }
  );
  console.log(response.data);
  let data = (response.data as PlaceResponse);
  for(let i = 0; i < data.places.length; i++) {
    if (data.places[i].photos) {
      data.places[i].photos = [data.places[i].photos[0]];
    }
  }
  return data as PlaceResponse;
}
คุณสามารถใช้การเรียกใช้ฟังก์ชันใน Genkit เพื่อขยายฟังก์ชันการทํางานของตัวแทน เพื่อให้ตัวแทนปรับแต่งคําตอบเพิ่มเติมและทำงานเพิ่มเติมให้เสร็จได้ แอปการเดินทางกำหนดเครื่องมือที่สามารถแสดงผลข้อมูลร้านอาหารจาก Places API ตามการเดินทางที่ผู้ใช้ต้องการ โค้ดจะใช้ Zod ในการกำหนดสคีมาอินพุตและเอาต์พุตเพื่อให้ตรวจสอบผลการค้นหาได้
...
export const textRefinement = defineFlow(
{
  name: 'textRefinement',
  inputSchema: z.string(),
  outputSchema: z.unknown(),
},
async (userRequest) => {
  const refinementPrompt = await prompt('textRefinement')
  const result = await refinementPrompt.generate({
      input: {
          request: userRequest
      },
  });
  return result.output();
});
Gemini จะพิจารณาว่าต้องการข้อมูลเพิ่มเติมหรือไม่ตามพรอมต์จากแอปท่องเที่ยวและส่งสัญญาณไปยังแอปหากเห็นว่าจำเป็นต้องระบุข้อมูลเพิ่มเติม เพื่อช่วยให้ผู้ใช้ได้รับประสบการณ์การค้นหาที่ปรับให้เหมาะกับผู้ใช้แต่ละคนมากขึ้น จากนั้นแอปจะแสดงข้อความแจ้งผู้ใช้สำหรับข้อมูลดังกล่าว แล้วนำไปต่อท้ายคำขอในแบ็กเอนด์
import 'package:http:http.dart' as http;
...
Future<List<Trip>> generateTrips(String description, List<Image> images) async {
  final uri = Uri.parse('.../generateTrips');
  final request = http.MultipartRequest('POST', uri);
  request.fields['description'] = description;
  request.files.add(http.MultipartFile.fromData(
      images.name, images.bytes,
      contentType: MediaType('image', 'png'),
  ));
  var response = await request.send();
  if (response.statusCode == 200) {
      final body = await response.body.text();
      final items = jsonDecode(body) as List<dynamic>;
      return items.map(Trip.fromJson).toList();
  }
  ...
  import { imagen2, geminiProVision } from '@genkit-ai/vertexai';
  import { generate } from '@genkit-ai/ai';

  const imageResult = await generate({
    model: imagen2,
    prompt: 'Generate an image of a very specific historical time and place.',
  });
  const generatedImage = imageResult.media();

  const descriptionResult = await generate({
    model: geminiProVision,
    prompt: [
      {
        text: 'What is the historical time and place represented in this picture?',
      },
      { media: generatedImage },
    ],
  });
  console.log(descriptionResult.text());
  }
แอปท่องเที่ยวจะขอให้ผู้ใช้กำหนดการเดินทางในฝันโดยใช้การป้อนข้อความหรือแตะปุ่มไมโครโฟนเพื่อเปิดใช้งานการแปลงเสียงพูดเป็นข้อความ นอกจากนี้ ผู้ใช้ยังเลือกที่จะอัปโหลดรูปภาพได้อีกด้วย

แอปนี้ใช้แพ็กเกจ Dart จาก pub.dev เพื่อผสานรวมกับความสามารถในการอ่านออกเสียงข้อความดั้งเดิมสำหรับแต่ละแพลตฟอร์ม และใช้ Gemini API ภายใน Firebase Genkit เพื่อจัดการอินพุตหลายรูปแบบ เช่น รูปภาพหรือวิดีโอ Gemini API ใช้การสร้าง Retrieval-augmented (RAG) เพื่อแสดงผลชุดการเดินทางที่แนะนำโดยใช้ Firebase Data Connect และการฝังเพื่อค้นหาเพื่อนบ้านที่อยู่ใกล้ที่สุด

ปรับขนาดแอปสำหรับเวอร์ชันที่ใช้งานจริง

Firebase Hosting ผสานรวมกับเฟรมเวิร์กเว็บสมัยใหม่ที่ได้รับความนิยมอย่าง Flutter การใช้โฮสติ้งของ Firebase และ Cloud Functions for Firebase กับเฟรมเวิร์กเหล่านี้จะช่วยให้คุณพัฒนาแอปและ Microservice ในสภาพแวดล้อมเฟรมเวิร์กที่ต้องการ แล้วทำให้ใช้งานได้ในสภาพแวดล้อมของเซิร์ฟเวอร์ที่มีการจัดการและปลอดภัยได้ ก่อนไปยังเวอร์ชันที่ใช้งานจริง โปรดทำความเข้าใจเกี่ยวกับความปลอดภัยและประสิทธิภาพของบริการทั้งหมดในแอป ดูข้อมูลเพิ่มเติมได้ที่รายการตรวจสอบการเปิดตัว Firebase
แอปการเดินทางใช้ AI ของ Google เพื่อทำซ้ำข้อมูลทดสอบอย่างรวดเร็ว และเป็นตัวเลือกที่ดีสำหรับแอปที่มี Use Case ของ AI เพียงเล็กน้อยซึ่งไม่จำเป็นต้องปรับขนาด Vertex AI มีโควต้าที่สูงขึ้นเพื่อช่วยปรับขนาดแอปพลิเคชันเวอร์ชันที่ใช้งานจริงและนโยบายความเป็นส่วนตัวที่เข้มงวดยิ่งขึ้นเพื่อปกป้องข้อมูลผู้ใช้ Genkit มีฟังก์ชันในตัวเพื่อให้เปลี่ยนรูปแบบได้อย่างง่ายดาย คุณจึงไม่จำเป็นต้องเขียนพรอมต์หรือการเรียก API ใหม่