本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
您可以使用 AWS AppSync 函數和解析程式,在 中的 Amazon Bedrock 上叫用模型 AWS 帳戶。您可以在將請求承載傳回給用戶端之前,從模型調用函數中塑造請求承載和回應。您可以使用 Amazon Bedrock 執行時間的 InvokeModel
API 或 Converse
API。本節說明支援 Amazon Bedrock 操作的請求。
注意
AWS AppSync 僅支援在 10 秒內完成的同步調用。無法呼叫 Amazon Bedrock 的串流 APIs。 AWS AppSync 僅支援在與 AWS AppSync API 相同的區域中叫用基礎模型和推論描述檔。
請求物件
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;
}
如需詳細資訊,請參閱本主題稍後的 類型參考一節。
您可以從函數和解析程式直接建置請求物件,或使用 @aws-appsync/utils/ai 的協助程式函數來建立請求。在請求中指定模型 ID (modelId) 時,您可以使用模型 ID 或模型 ARN。
下列範例使用 invokeModel
函數,使用 Amazon Titan Text G1 - Lite (amazon.titan-text-lite-v1) 來摘要文字。設定的護欄用於識別和封鎖或篩選提示流程中不需要的內容。請參閱 Amazon Bedrock 使用者指南,進一步了解 Amazon Bedrock Guardrails。
重要
您負責安全的應用程式開發和防止漏洞,例如提示注入。若要進一步了解,請參閱《Amazon Bedrock 使用者指南》中的提示注入安全性。
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 推論描述檔的先決條件
提醒:您必須負責安全的應用程式開發和防止漏洞,例如提示注入。
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
來建立結構化回應。請注意,我們使用環境變數做為資料庫結構描述參考,並設定護欄以協助防止攻擊。
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 Guardrails,請參閱《Amazon Bedrock 使用者指南》中的使用 Amazon Bedrock Guardrails 在模型中停止有害內容。
回應物件
來自 Amazon Bedrock 執行期調用的回應包含在內容的結果屬性 (context.result) 中。回應符合 Amazon Bedrock APIs指定的形狀。如需調用結果預期形狀的詳細資訊,請參閱 Amazon Bedrock 使用者指南。
export function response(ctx) {
return ctx.result
}
沒有適用於回應物件的必要欄位或形狀限制。不過,由於 GraphQL 是強式輸入,因此解析的回應必須符合預期的 GraphQL 類型。
長時間執行調用
許多組織目前使用 AWS AppSync 做為 AI 閘道,來建置由 Amazon Bedrock 基礎模型提供支援的生成式 AI 應用程式。客戶使用 AWS AppSync 由 WebSockets 提供支援的訂閱,從長期執行的模型調用中傳回漸進式更新。這可讓它們實作非同步模式。
下圖示範如何實作此模式。在圖表中,會發生下列步驟。
-
您的用戶端會啟動訂閱,以設定 WebSocket,並請求 AWS AppSync 觸發生成式 AI 調用。
-
AWS AppSync 在事件模式下呼叫您的 AWS Lambda 函數,並立即將回應傳回給用戶端。
-
您的 Lambda 函數會在 Amazon Bedrock 上叫用模型。Lambda 函數可以使用同步 API,例如
InvokeModel
,或串流 API,例如InvokeModelWithResponseStream
,以取得漸進式更新。 -
收到更新時,或呼叫完成時,Lambda 函數會透過觸發訂閱的 AWS AppSync API 變動來傳送更新。
-
訂閱事件會透過 WebSocket 即時傳送並由用戶端接收。

類型參考
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;
};