From 1cc0aa6e46e8ae53854e3d666b68f8c53257943a Mon Sep 17 00:00:00 2001 From: Ian Saultz <52051793+atierian@users.noreply.github.com> Date: Wed, 11 Sep 2024 11:07:50 -0400 Subject: [PATCH 1/3] add initial generation route page --- .../build-a-backend/ai/generation/index.mdx | 167 ++++++++++++++++++ .../build-a-backend/ai/set-up-ai/index.mdx | 20 +++ 2 files changed, 187 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/ai/generation/index.mdx b/src/pages/[platform]/build-a-backend/ai/generation/index.mdx index bc48c6c5437..c5dfccef866 100644 --- a/src/pages/[platform]/build-a-backend/ai/generation/index.mdx +++ b/src/pages/[platform]/build-a-backend/ai/generation/index.mdx @@ -32,3 +32,170 @@ export function getStaticProps(context) { Amplify AI sections are under construction + + +## Generation Routes + +Generation routes are request-response API used to generate structured output from AI models. +Examples of generation routes include: +- generated structured data from unstructured input. +- summarization. + +Under the hood, a generation route is an AppSync query that ensures the AI model responds with the response type defined for the route. + +### Generate Typed Objects + +```ts title="Schema Definition" +const schema = a.schema({ + generateRecipe: a.generation({ + aiModel: a.ai.model('Claude 3 Haiku'), + systemPrompt: 'You are a helpful assistant that generates recipes.', + }) + .arguments({ description: a.string() }) + .returns( + a.customType({ + name: a.string(), + ingredients: a.string().array(), + instructions: a.string(), + }) + ) + .authorization((allow) => allow.authenticated()) +}); +``` + +```ts title="Data Client Request" +const description = 'I would like to bake a birthday cake for my friend. She has celiac disease and loves chocolate.' +const { data: recipe, errors } = client.generations.generateRecipe({ description }) + +/** +Example response: +{ + "generateRecipe": { + "name": "Gluten-Free Chocolate Birthday Cake", + "ingredients": [ + "gluten-free all-purpose flour", + "cocoa powder", + "granulated sugar", + "baking powder", + "baking soda", + "salt", + "eggs", + "milk", + "vegetable oil", + "vanilla extract" + ], + "instructions": "1. Preheat oven to 350°F. Grease and flour two 9-inch round baking pans.\n2. In a medium bowl, whisk together the gluten-free flour, cocoa powder, sugar, baking powder, baking soda and salt.\n3. In a separate bowl, beat the eggs. Then add the milk, oil and vanilla and mix well.\n4. Gradually add the wet ingredients to the dry ingredients and mix until just combined. Do not over mix.\n5. Divide the batter evenly between the prepared pans.\n6. Bake for 30-35 minutes, until a toothpick inserted in the center comes out clean.\n7. Allow cakes to cool in pans for 10 minutes, then transfer to a wire rack to cool completely.\n8. Frost with your favorite gluten-free chocolate frosting." + } +} +*/ +``` + +### Generate Scalar Types + +```ts title="Schema Definition" +const schema = ({ + summarize: a.generation({ + aiModel: a.ai.model('Claude 3 Haiku'), + systemPrompt: 'Provide an accurate, clear, and concise summary of the input provided" + }) + .arguments({ input: a.string() }) + .returns(a.string()) + .authorization((allow) => allow.guest()), +}); +``` + +```ts title="Data Client Request" +const { data: summary, errors } = client.generations.summarize({ input }) +``` + +### Setting Inference Parameters + +You can influence response generation by setting inference parameters for the AI model. +This ability to control the randomness and diversity of responses is useful for generating responses that are tailored to your needs. +For more information on inference parameters, see [Amazon Bedrock > Inference Parameters](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-parameters.html). +```ts title="Inference Parameters" +const schema = a.schema({ + generateHaiku: a.generation({ + aiModel: a.ai.model('Claude 3 Haiku'), + systemPrompt: 'You are a helpful assistant that generates haikus.', + // highlight-start + inferenceConfiguration: { + maxTokens: 1000, + temperature: 0.5, + topP: 0.9, + } + // highlight-end + }), +}); +``` + +### Limitations + +#### 1. Generation routes do not support referencing models + +For example, the following schema defines a `Recipe` model, but this model cannot be used as the return type of a generation route. + +```ts title="Invalid Model Reference" +const schema = a.schema({ + Recipe: a.model({ + name: a.string(), + ingredients: a.string().array(), + instructions: a.string(), + }), + generateRecipe: a.generation({ + aiModel: a.ai.model('Claude 3 Haiku'), + systemPrompt: 'You are a helpful assistant that generates recipes.', + }) + .arguments({ description: a.string() }) + .returns(a.ref('Recipe')) // ❌ Invalid + .authorization((allow) => allow.authenticated()), +}); +``` + +You can, however, reference custom types. Here's an example of a custom type that can be used as the return type of a generation route. +```ts title="Valid Custom Type Reference" +const schema = a.schema({ + Recipe: a.customType({ + name: a.string(), + ingredients: a.string().array(), + instructions: a.string(), + }), + generateRecipe: a.generation({ + aiModel: a.ai.model('Claude 3 Haiku'), + systemPrompt: 'You are a helpful assistant that generates recipes.', + }) + .arguments({ description: a.string() }) + .returns(a.ref('Recipe')) // ✅ Valid + .authorization((allow) => allow.authenticated()), +}); +``` + +#### 2. Generation routes do not support some required types. + +The following AppSync scalar types are not supported as **required** fields in response types: +- `AWSEmail` +- `AWSDate` +- `AWSTime` +- `AWSDateTime` +- `AWSTimestamp` +- `AWSPhone` +- `AWSURL` +- `AWSIPAddress` + +```ts title="Unsupported Required Type" +const schema = a.schema({ + generateUser: a.generation({ + aiModel: a.ai.model('Claude 3 Haiku'), + systemPrompt: 'You are a helpful assistant that generates users.', + }) + .arguments({ description: a.string() }) + .returns( + a.customType({ + name: a.string(), + email: a.email().required(), // ❌ Required field with unsupported type + dateOfBirth: a.date().required(), // ❌ Required field with unsupported type + }) + ) + .authorization((allow) => allow.authenticated()), +}); + diff --git a/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx b/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx index 2c30b1bd323..31f7c9332c7 100644 --- a/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx +++ b/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx @@ -32,3 +32,23 @@ export function getStaticProps(context) { Amplify AI sections are under construction + +In this guide, you will learn how to set up Amplify AI. This includes building Conversation and Generation routes, and securing access to these routes with authorization rules. + +Before you begin, you will need: + +- [Node.js](https://nodejs.org/) v18.16.0 or later +- [npm](https://www.npmjs.com/) v6.14.4 or later +- [git](https://git-scm.com/) v2.14.1 or later + +With Amplify AI, you can define Conversation and Generation routes backed by an AWS AppSync API and Amazon Bedrock. + +## Building your AI backend +If you've run `npm create amplify@latest` already, you should see an `amplify/data/resource/ts` file, which is the central location to configure your AI backend. Within the `schema` object, you define Conversation routes (`a.conversation({})`) and Generation routes (`a.generation({})`), and can integrate them seamlessly with existing Amplify Data schema objects. + +```ts title="amplify/data/resources.ts" +import { a, defineData, type ClientSchema } from '@aws-amplify/backend'; + +const schema = a.schema({ +}); +``` From d7a4917b614ebfbdd2dd7a37bbeef492397e48ec Mon Sep 17 00:00:00 2001 From: Danny Banks Date: Mon, 16 Sep 2024 10:24:21 -0700 Subject: [PATCH 2/3] cleaning up ai generation docs --- .../build-a-backend/ai/generation/index.mdx | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/ai/generation/index.mdx b/src/pages/[platform]/build-a-backend/ai/generation/index.mdx index c5dfccef866..899128348a7 100644 --- a/src/pages/[platform]/build-a-backend/ai/generation/index.mdx +++ b/src/pages/[platform]/build-a-backend/ai/generation/index.mdx @@ -34,16 +34,13 @@ Amplify AI sections are under construction -## Generation Routes - -Generation routes are request-response API used to generate structured output from AI models. -Examples of generation routes include: +AI generation routes are a request-response API used to generate structured output from AI models. Examples of generation routes include: - generated structured data from unstructured input. - summarization. Under the hood, a generation route is an AppSync query that ensures the AI model responds with the response type defined for the route. -### Generate Typed Objects +## Generate Typed Objects ```ts title="Schema Definition" const schema = a.schema({ @@ -65,38 +62,37 @@ const schema = a.schema({ ```ts title="Data Client Request" const description = 'I would like to bake a birthday cake for my friend. She has celiac disease and loves chocolate.' -const { data: recipe, errors } = client.generations.generateRecipe({ description }) +const { data, errors } = await client.generations + .generateRecipe({ description }) /** Example response: { - "generateRecipe": { - "name": "Gluten-Free Chocolate Birthday Cake", - "ingredients": [ - "gluten-free all-purpose flour", - "cocoa powder", - "granulated sugar", - "baking powder", - "baking soda", - "salt", - "eggs", - "milk", - "vegetable oil", - "vanilla extract" - ], - "instructions": "1. Preheat oven to 350°F. Grease and flour two 9-inch round baking pans.\n2. In a medium bowl, whisk together the gluten-free flour, cocoa powder, sugar, baking powder, baking soda and salt.\n3. In a separate bowl, beat the eggs. Then add the milk, oil and vanilla and mix well.\n4. Gradually add the wet ingredients to the dry ingredients and mix until just combined. Do not over mix.\n5. Divide the batter evenly between the prepared pans.\n6. Bake for 30-35 minutes, until a toothpick inserted in the center comes out clean.\n7. Allow cakes to cool in pans for 10 minutes, then transfer to a wire rack to cool completely.\n8. Frost with your favorite gluten-free chocolate frosting." - } + "name": "Gluten-Free Chocolate Birthday Cake", + "ingredients": [ + "gluten-free all-purpose flour", + "cocoa powder", + "granulated sugar", + "baking powder", + "baking soda", + "salt", + "eggs", + "milk", + "vegetable oil", + "vanilla extract" + ], + "instructions": "1. Preheat oven to 350°F. Grease and flour two 9-inch round baking pans.\n2. In a medium bowl, whisk together the gluten-free flour, cocoa powder, sugar, baking powder, baking soda and salt.\n3. In a separate bowl, beat the eggs. Then add the milk, oil and vanilla and mix well.\n4. Gradually add the wet ingredients to the dry ingredients and mix until just combined. Do not over mix.\n5. Divide the batter evenly between the prepared pans.\n6. Bake for 30-35 minutes, until a toothpick inserted in the center comes out clean.\n7. Allow cakes to cool in pans for 10 minutes, then transfer to a wire rack to cool completely.\n8. Frost with your favorite gluten-free chocolate frosting." } */ ``` -### Generate Scalar Types +## Generate Scalar Types ```ts title="Schema Definition" const schema = ({ summarize: a.generation({ aiModel: a.ai.model('Claude 3 Haiku'), - systemPrompt: 'Provide an accurate, clear, and concise summary of the input provided" + systemPrompt: 'Provide an accurate, clear, and concise summary of the input provided' }) .arguments({ input: a.string() }) .returns(a.string()) @@ -105,10 +101,11 @@ const schema = ({ ``` ```ts title="Data Client Request" -const { data: summary, errors } = client.generations.summarize({ input }) +const { data: summary, errors } = await client.generations + .summarize({ input }) ``` -### Setting Inference Parameters +## Setting Inference Parameters You can influence response generation by setting inference parameters for the AI model. This ability to control the randomness and diversity of responses is useful for generating responses that are tailored to your needs. @@ -129,9 +126,9 @@ const schema = a.schema({ }); ``` -### Limitations +## Limitations -#### 1. Generation routes do not support referencing models +### 1. Generation routes do not support referencing models For example, the following schema defines a `Recipe` model, but this model cannot be used as the return type of a generation route. @@ -170,7 +167,7 @@ const schema = a.schema({ }); ``` -#### 2. Generation routes do not support some required types. +### 2. Generation routes do not support some required types. The following AppSync scalar types are not supported as **required** fields in response types: - `AWSEmail` From 65528c650e34311bd89728f78577ba299745d160 Mon Sep 17 00:00:00 2001 From: Danny Banks Date: Mon, 16 Sep 2024 10:54:28 -0700 Subject: [PATCH 3/3] fixing broken build --- src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx b/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx index 26ee4152123..ad483e56c66 100644 --- a/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx +++ b/src/pages/[platform]/build-a-backend/ai/set-up-ai/index.mdx @@ -54,8 +54,6 @@ If you've run `npm create amplify@latest` already, you should see an `amplify/da import { a, defineData, type ClientSchema } from '@aws-amplify/backend'; const schema = a.schema({ -}); -``` // This will add a new conversation route to your Amplify Data backend. chat: a.conversation({ aiModel: a.ai.model('Claude 3 Haiku'),