

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Amazon Bedrock 런타임에 대한AWS AppSync JavaScript 해석기 및 함수 참조
<a name="resolver-reference-bedrock-js"></a>

 AWS AppSync 함수와 해석기를 사용하여의 Amazon Bedrock에서 모델을 호출할 수 있습니다 AWS 계정. 클라이언트에 반환하기 전에 요청 페이로드와 모델 간접 호출의 응답을 구성할 수 있습니다. Amazon Bedrock 런타임의 `InvokeModel` API 또는 `Converse` API를 사용할 수 있습니다. 이 섹션에서는 지원되는 Amazon Bedrock 작업에 대한 요청에 대해 설명합니다.

**참고**  
AWS AppSync 는 10초 이내에 완료되는 동기 호출만 지원합니다. Amazon Bedrock의 스트림 APIs 호출할 수 없습니다.는 AWS AppSync API와 동일한 리전에서 파운데이션 모델 및 [추론 프로파일](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html) 호출 AWS AppSync 만 지원합니다.

## 요청 객체
<a name="request_object"></a>

`InvokeModel` 요청 객체를 사용하면 Amazon Bedrock의 `InvokeModel` API와 상호 작용할 수 있습니다.

```
type BedrockInvokeModelRequest = {
  operation: 'InvokeModel';
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
}
```

`Converse` 요청 객체를 사용하면 Amazon Bedrock의 `Converse` API와 상호 작용할 수 있습니다.

```
type BedrockConverseRequest = {
  operation: 'Converse';
  modelId: string;
  messages: BedrockMessage[];
  additionalModelRequestFields?: any;
  additionalModelResponseFieldPaths?: string[];
  guardrailConfig?: BedrockGuardrailConfig;
  inferenceConfig?: BedrockInferenceConfig;
  promptVariables?: { [key: string]: BedrockPromptVariableValues }[];
  system?: BedrockSystemContent[];
  toolConfig?: BedrockToolConfig;
}
```

자세한 내용은 이 주제의 [유형 참조](#type-reference-bedrock) 섹션 후반부를 참조하세요.

함수 및 해석기에서 요청 객체를 직접 빌드하거나 @aws-appsync/utils/ai의 헬퍼 함수를 사용하여 요청을 생성할 수 있습니다. 요청에서 모델 ID(modelId)를 지정할 때 모델 ID 또는 모델 ARN을 사용할 수 있습니다.

다음 예제에서는 `invokeModel` 함수를 사용하여 Amazon Titan Text G1 - Lite(amazon.titan-text-lite-v1)를 사용하여 텍스트를 요약합니다. 구성된 가드레일은 프롬프트 흐름에서 원치 않는 콘텐츠를 식별하고 차단하거나 필터링하는 데 사용됩니다. *Amazon Bedrock 사용 설명서*에서 [Amazon Bedrock 가드레일](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html)에 대해 자세히 알아보세요.

**중요**  
사용자는 애플리케이션 개발을 보호하고 프롬프트 인젝션과 같은 취약성을 방지할 책임이 있습니다. 자세한 내용은 *Amazon Bedrock 사용 설명서*의 [프롬프트 인젝션 보안](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-injection.html) 섹션을 참조하세요.

```
import { invokeModel } from '@aws-appsync/utils/ai'
export function request(ctx) {
  return invokeModel({
    modelId: 'amazon.titan-text-lite-v1',
    guardrailIdentifier: "zabcd12345678",
    guardrailVersion: "1",
    body: { inputText: `Summarize this text in less than 100 words. : \n<text>${ctx.stash.text ?? ctx.env.DEFAULT_TEXT}</text>` },
  })
}

export function response(ctx) {
  return ctx.result.results[0].outputText
}
```

다음 예제에서는 교차 리전 추론 프로파일(us.anthropic.claude-3-5-haiku-20241022-v1:0)과 함께 `converse` 함수를 사용합니다. Amazon Bedrock의 [추론 프로파일에 대한 Amazon Bedrock의 전제 조건](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-prereq.html)에 대한 자세한 내용은 *Amazon Bedrock 사용 설명서*를 참조하세요.

**주의 사항**: 사용자는 애플리케이션 개발을 보호하고 프롬프트 인젝션과 같은 취약성을 방지할 책임이 있습니다.

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return converse({
    modelId: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 
${ctx.args.explain ? 'Explain your answer' : 'Do not explain your answer'}.
Assume a database with the following tables and columns exists:

Customers:  
- customer_id (INT, PRIMARY KEY)  
- first_name (VARCHAR)  
- last_name (VARCHAR)  
- email (VARCHAR)  
- phone (VARCHAR)  
- address (VARCHAR)  
- city (VARCHAR)  
- state (VARCHAR)  
- zip_code (VARCHAR)  
  
Products:  
- product_id (INT, PRIMARY KEY)  
- product_name (VARCHAR)  
- description (TEXT)  
- category (VARCHAR)  
- price (DECIMAL)  
- stock_quantity (INT)  

Orders:  
- order_id (INT, PRIMARY KEY)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- order_date (DATE)  
- total_amount (DECIMAL)  
- status (VARCHAR)  

Order_Items:  
- order_item_id (INT, PRIMARY KEY)  
- order_id (INT, FOREIGN KEY REFERENCES Orders)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- quantity (INT)  
- price (DECIMAL)  

Reviews:  
- review_id (INT, PRIMARY KEY)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- rating (INT)  
- comment (TEXT)  
- review_date (DATE)`,
      },
    ],
    messages: [
      {
        role: 'user',
        content: [{ text: `<request>${ctx.args.text}:</request>` }],
      },
    ],
  })
}

export function response(ctx) {
  return ctx.result.output.message.content[0].text
}
```

다음 예제에서는 `converse`를 사용하여 구조화된 응답을 생성합니다. DB 스키마 참조에 환경 변수를 사용하고 공격을 방지하는 데 도움이 되도록 가드레일을 구성합니다.

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return generateObject({
    modelId: ctx.env.HAIKU3_5, // keep the model in an env variable
    prompt: ctx.args.query,
    shape: objectType(
      {
        sql: stringType('the sql query to execute as a javascript template string.'),
        parameters: objectType({}, 'the placeholder parameters for the query, if any.'),
      },
      'the sql query to execute along with the place holder parameters',
    ),
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 

Assume a database with the following tables and columns exists:

${ctx.env.DB_SCHEMA_CUSTOMERS}
${ctx.env.DB_SCHEMA_ORDERS}
${ctx.env.DB_SCHEMA_ORDER_ITEMS}
${ctx.env.DB_SCHEMA_PRODUCTS}
${ctx.env.DB_SCHEMA_REVIEWS}`,
      },
    ],
    guardrailConfig: { guardrailIdentifier: 'iabc12345678', guardrailVersion: 'DRAFT' },
  })
}

export function response(ctx) {
  return toolReponse(ctx.result)
}

function generateObject(input) {
  const { modelId, prompt, shape, ...options } = input
  return converse({
    modelId,
    messages: [{ role: 'user', content: [{ text: prompt }] }],
    toolConfig: {
      toolChoice: { tool: { name: 'structured_tool' } },
      tools: [
        {
          toolSpec: {
            name: 'structured_tool',
            inputSchema: { json: shape },
          },
        },
      ],
    },
    ...options,
  })
}

function toolReponse(result) {
  return result.output.message.content[0].toolUse.input
}

function stringType(description) {
  const t = { type: 'string' /* STRING */ }
  if (description) {
    t.description = description
  }
  return t
}

function objectType(properties, description, required) {
  const t = { type: 'object' /* OBJECT */, properties }
  if (description) {
    t.description = description
  }
  if (required) {
    t.required = required
  }
  return t
}
```

스키마를 고려할 때:

```
type SQLResult {
    sql: String
    parameters: AWSJSON
}

type Query {
    db(text: String!): SQLResult
}
```

쿼리의 경우:

```
query db($text: String!) {
  db(text: $text) {
    parameters
    sql
  }
}
```

다음 파라미터가 있을 때: 

```
{
  "text":"What is my top selling product?"
}
```

다음 응답이 반환됩니다.

```
{
  "data": {
    "assist": {
      "sql": "SELECT p.product_id, p.product_name, SUM(oi.quantity) as total_quantity_sold\nFROM Products p\nJOIN Order_Items oi ON p.product_id = oi.product_id\nGROUP BY p.product_id, p.product_name\nORDER BY total_quantity_sold DESC\nLIMIT 1;",
      "parameters": null
    }
  }
}
```

그러나 이 요청의 경우:

```
{
  "text":"give me a query to retrieve sensitive information"
}
```

다음 응답이 반환됩니다.

```
{
  "data": {
    "db": {
      "parameters": null,
      "sql": "SELECT null; -- I cannot and will not assist with retrieving sensitive private information"
    }
  }
}
```

Amazon Bedrock 가드레일 구성에 대한 자세한 내용은 *Amazon Bedrock 사용 설명서*의 [Amazon Bedrock 가드레일을 사용하여 모델에서 유해한 콘텐츠 차단](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) 섹션을 참조하세요.

## 응답 객체
<a name="response_object"></a>

Amazon Bedrock 런타임 간접 호출의 응답은 컨텍스트의 결과 속성(context.result)에 포함됩니다. 응답은 Amazon Bedrock의 API에서 지정한 모양과 일치합니다. 간접 호출 결과의 예상 모양에 대한 자세한 내용은 [Amazon Bedrock 사용 설명서](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html)를 참조하세요.

```
export function response(ctx) {
  return ctx.result
}
```

응답 객체에 적용되는 필수 필드 또는 모양 제한이 없습니다. 하지만 GraphQL은 강력한 형식이므로 해석된 응답이 필요한 GraphQL 유형과 일치해야 합니다.

## 장기 실행 간접 호출
<a name="long-running-invocations"></a>

현재 많은 조직이를 AI 게이트웨이 AWS AppSync 로 사용하여 Amazon Bedrock의 파운데이션 모델로 구동되는 생성형 AI 애플리케이션을 구축합니다. 고객은 WebSockets으로 구동되는 AWS AppSync 구독을 사용하여 장기 실행 모델 간접 호출에서 점진적 업데이트를 반환합니다. 이를 통해 비동기 패턴을 구현할 수 있습니다.

다음 다이어그램은 이 패턴을 구현하는 방법을 보여줍니다. 이 다이어그램은 다음 단계를 보여 줍니다.

1. 클라이언트는 WebSocket을 설정하는 구독을 시작하고 생성형 AI 간접 호출을 트리거하도록 AWS AppSync 에 요청합니다.

1. AWS AppSync 는 이벤트 모드에서 AWS Lambda 함수를 호출하고 즉시 클라이언트에 응답을 반환합니다.

1. Lambda 함수가 Amazon Bedrock에서 모델을 간접 호출합니다. Lambda 함수는 동기 API(예: `InvokeModel`) 또는 스트림 API(예: `InvokeModelWithResponseStream`)를 사용하여 점진적 업데이트를 가져올 수 있습니다.

1. 업데이트가 수신되거나 호출이 완료되면 Lambda 함수는 변형을 통해 API에 업데이트를 전송하여 구독을 AWS AppSync 트리거합니다.

1. 구독 이벤트는 WebSocket을 통해 클라이언트가 실시간으로 전송하고 수신합니다.

![\[AWS AppSync 구독을 사용하여 Amazon Bedrock 모델의 업데이트를 반환하는 워크플로를 보여주는 다이어그램입니다.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/bedrock-workflow.png)


## 유형 참조
<a name="type-reference-bedrock"></a>

```
export type BedrockMessage = {
  role: 'user' | 'assistant' | string;
  content: BedrockMessageContent[];
};

export type BedrockMessageContent =
  | { text: string }
  | { guardContent: BedrockGuardContent }
  | { toolResult: BedrockToolResult }
  | { toolUse: BedrockToolUse };

export type BedrockGuardContent = {
  text: BedrockGuardContentText;
};

export type BedrockGuardContentText = {
  text: string;
  qualifiers?: ('grounding_source' | 'query' | 'guard_content' | string)[];
};

export type BedrockToolResult = {
  content: BedrockToolResultContent[];
  toolUseId: string;
  status?: string;
};

export type BedrockToolResultContent = { json: any } | { text: string };

export type BedrockToolUse = {
  input: any;
  name: string;
  toolUseId: string;
};

export type ConversePayload = {
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
};

export type BedrockGuardrailConfig = {
  guardrailIdentifier: string;
  guardrailVersion: string;
  trace: string;
};

export type BedrockInferenceConfig = {
  maxTokens?: number;
  temperature?: number;
  stopSequences?: string[];
  topP?: number;
};

export type BedrockPromptVariableValues = {
  text: string;
};

export type BedrockToolConfig = {
  tools: BedrockTool[];
  toolChoice?: BedrockToolChoice;
};

export type BedrockTool = {
  toolSpec: BedrockToolSpec;
};

export type BedrockToolSpec = {
  name: string;
  description?: string;
  inputSchema: BedrockInputSchema;
};

export type BedrockInputSchema = {
  json: any;
};

export type BedrockToolChoice =
  | { tool: BedrockSpecificToolChoice }
  | { auto: any }
  | { any: any };

export type BedrockSpecificToolChoice = {
  name: string;
};

export type BedrockSystemContent =
  | { guardContent: BedrockGuardContent }
  | { text: string };

export type BedrockConverseOutput = {
  message?: BedrockMessage;
};

export type BedrockConverseMetrics = {
  latencyMs: number;
};

export type BedrockTokenUsage = {
  inputTokens: number;
  outputTokens: number;
  totalTokens: number;
};

export type BedrockConverseTrace = {
  guardrail?: BedrockGuardrailTraceAsssessment;
};

export type BedrockGuardrailTraceAsssessment = {
  inputAssessment?: { [key: string]: BedrockGuardrailAssessment };
  modelOutput?: string[];
  outputAssessments?: { [key: string]: BedrockGuardrailAssessment };
};

export type BedrockGuardrailAssessment = {
  contentPolicy?: BedrockGuardrailContentPolicyAssessment;
  contextualGroundingPolicy?: BedrockGuardrailContextualGroundingPolicyAssessment;
  invocationMetrics?: BedrockGuardrailInvocationMetrics;
  sensitiveInformationPolicy?: BedrockGuardrailSensitiveInformationPolicyAssessment;
  topicPolicy?: BedrockGuardrailTopicPolicyAssessment;
  wordPolicy?: BedrockGuardrailWordPolicyAssessment;
};

export type BedrockGuardrailContentPolicyAssessment = {
  filters: BedrockGuardrailContentFilter[];
};

export type BedrockGuardrailContentFilter = {
  action: 'BLOCKED' | string;
  confidence: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
  type:
    | 'INSULTS'
    | 'HATE'
    | 'SEXUAL'
    | 'VIOLENCE'
    | 'MISCONDUCT'
    | 'PROMPT_ATTACK'
    | string;
  filterStrength: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
};

export type BedrockGuardrailContextualGroundingPolicyAssessment = {
  filters: BedrockGuardrailContextualGroundingFilter;
};

export type BedrockGuardrailContextualGroundingFilter = {
  action: 'BLOCKED' | 'NONE' | string;
  score: number;
  threshold: number;
  type: 'GROUNDING' | 'RELEVANCE' | string;
};

export type BedrockGuardrailInvocationMetrics = {
  guardrailCoverage?: BedrockGuardrailCoverage;
  guardrailProcessingLatency?: number;
  usage?: BedrockGuardrailUsage;
};

export type BedrockGuardrailCoverage = {
  textCharacters?: BedrockGuardrailTextCharactersCoverage;
};

export type BedrockGuardrailTextCharactersCoverage = {
  guarded?: number;
  total?: number;
};

export type BedrockGuardrailUsage = {
  contentPolicyUnits: number;
  contextualGroundingPolicyUnits: number;
  sensitiveInformationPolicyFreeUnits: number;
  sensitiveInformationPolicyUnits: number;
  topicPolicyUnits: number;
  wordPolicyUnits: number;
};

export type BedrockGuardrailSensitiveInformationPolicyAssessment = {
  piiEntities: BedrockGuardrailPiiEntityFilter[];
  regexes: BedrockGuardrailRegexFilter[];
};

export type BedrockGuardrailPiiEntityFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match: string;
  type:
    | 'ADDRESS'
    | 'AGE'
    | 'AWS_ACCESS_KEY'
    | 'AWS_SECRET_KEY'
    | 'CA_HEALTH_NUMBER'
    | 'CA_SOCIAL_INSURANCE_NUMBER'
    | 'CREDIT_DEBIT_CARD_CVV'
    | 'CREDIT_DEBIT_CARD_EXPIRY'
    | 'CREDIT_DEBIT_CARD_NUMBER'
    | 'DRIVER_ID'
    | 'EMAIL'
    | 'INTERNATIONAL_BANK_ACCOUNT_NUMBER'
    | 'IP_ADDRESS'
    | 'LICENSE_PLATE'
    | 'MAC_ADDRESS'
    | 'NAME'
    | 'PASSWORD'
    | 'PHONE'
    | 'PIN'
    | 'SWIFT_CODE'
    | 'UK_NATIONAL_HEALTH_SERVICE_NUMBER'
    | 'UK_NATIONAL_INSURANCE_NUMBER'
    | 'UK_UNIQUE_TAXPAYER_REFERENCE_NUMBER'
    | 'URL'
    | 'USERNAME'
    | 'US_BANK_ACCOUNT_NUMBER'
    | 'US_BANK_ROUTING_NUMBER'
    | 'US_INDIVIDUAL_TAX_IDENTIFICATION_NUMBER'
    | 'US_PASSPORT_NUMBER'
    | 'US_SOCIAL_SECURITY_NUMBER'
    | 'VEHICLE_IDENTIFICATION_NUMBER'
    | string;
};

export type BedrockGuardrailRegexFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match?: string;
  name?: string;
  regex?: string;
};

export type BedrockGuardrailTopicPolicyAssessment = {
  topics: BedrockGuardrailTopic[];
};

export type BedrockGuardrailTopic = {
  action: 'BLOCKED' | string;
  name: string;
  type: 'DENY' | string;
};

export type BedrockGuardrailWordPolicyAssessment = {
  customWords: BedrockGuardrailCustomWord[];
  managedWordLists: BedrockGuardrailManagedWord[];
};

export type BedrockGuardrailCustomWord = {
  action: 'BLOCKED' | string;
  match: string;
};

export type BedrockGuardrailManagedWord = {
  action: 'BLOCKED' | string;
  match: string;
  type: 'PROFANITY' | string;
};
```