Lex Basics
Build and test a minimal bot with one intent via SDK.
Busque em todas as páginas da documentação
Build and test a minimal bot with one intent via SDK.
This page walks the full build-time pipeline for the smallest useful Lex V2 bot: one bot, one locale, one intent with a couple of sample utterances, built and tested. Each example is small and builds on the last, ending with a real conversation turn against your bot through RecognizeText. Lex V2 is the current API generation used throughout.
pip install boto3 (boto3 1.43.x, Python 3.10+). TypeScript: npm install @aws-sdk/client-lex-models-v2 @aws-sdk/client-lex-runtime-v2 (Node.js 18+).aws configure, environment variables, or an IAM role - the SDK finds them automatically.roleArn in CreateBot) with a trust policy for lexv2.amazonaws.com and the AWS-managed AmazonLexV2BotPolicy (or equivalent) attached.lexv2-models:* for the build-time calls in this page and lexv2-runtime:RecognizeText for the test calls.us-east-1.Every Lex resource nests under a bot, so this is always the first call.
# --- Python (boto3) ---
import boto3
lex_models = boto3.client("lexv2-models", region_name="us-east-1")
bot = lex_models.create_bot(
botName="OrderStatusBot",
description="Looks up an order's status.",
roleArn="arn:aws:iam::123456789012:role/LexV2BotRole", # your bot's service role
dataPrivacy={"childDirected": False},
idleSessionTTLInSeconds=300,
)
bot_id = bot["botId"]
print(bot_id, bot["botStatus"])// --- TypeScript (AWS SDK v3) ---
import { LexModelsV2Client, CreateBotCommand } from "@aws-sdk/client-lex-models-v2";
const lexModels = new LexModelsV2Client({ region: "us-east-1" });
const bot = await lexModels.send(new CreateBotCommand({
botName: "OrderStatusBot",
description: "Looks up an order's status.",
roleArn: "arn:aws:iam::123456789012:role/LexV2BotRole", // your bot's service role
dataPrivacy: { childDirected: false },
idleSessionTTLInSeconds: 300,
}));
const botId = bot.botId!;
console.log(botId, bot.botStatus);dataPrivacy.childDirected is a required COPPA declaration - false unless your bot targets children.roleArn must trust lexv2.amazonaws.com and have permission to log conversations and invoke fulfillment Lambdas.botStatus starts at Creating; poll DescribeBot or wait briefly before the next step.idleSessionTTLInSeconds caps how long a paused conversation's session state is kept.A bot needs at least one locale before it can hold any intents.
# --- Python (boto3) ---
lex_models.create_bot_locale(
botId=bot_id,
botVersion="DRAFT",
localeId="en_US",
nluIntentConfidenceThreshold=0.40,
)// --- TypeScript (AWS SDK v3) ---
import { CreateBotLocaleCommand } from "@aws-sdk/client-lex-models-v2";
await lexModels.send(new CreateBotLocaleCommand({
botId: botId,
botVersion: "DRAFT",
localeId: "en_US",
nluIntentConfidenceThreshold: 0.40,
}));DRAFT version until you explicitly publish a version.localeId (en_US, es_ES, ...) must match across every intent, slot, and slot type you add to this locale.nluIntentConfidenceThreshold controls when Lex falls back to AMAZON.FallbackIntent instead of a low-confidence match.voiceSettings here; text-only bots can skip it.Related: Intents, Slots & Slot Types - what goes inside a locale next.
The intent is the user goal; sample utterances teach Lex to recognize it.
# --- Python (boto3) ---
intent = lex_models.create_intent(
botId=bot_id,
botVersion="DRAFT",
localeId="en_US",
intentName="CheckOrderStatus",
sampleUtterances=[
{"utterance": "What's the status of my order"},
{"utterance": "Check my order"},
{"utterance": "Where is my order"},
],
)
print(intent["intentId"])// --- TypeScript (AWS SDK v3) ---
import { CreateIntentCommand } from "@aws-sdk/client-lex-models-v2";
const intent = await lexModels.send(new CreateIntentCommand({
botId: botId,
botVersion: "DRAFT",
localeId: "en_US",
intentName: "CheckOrderStatus",
sampleUtterances: [
{ utterance: "What's the status of my order" },
{ utterance: "Check my order" },
{ utterance: "Where is my order" },
],
}));
console.log(intent.intentId);AMAZON.FallbackIntent per locale for anything that doesn't match a defined intent.intentId is what later calls (CreateSlot, code hooks) reference - save it.Compiling turns your intents and slots into a working NLU model.
# --- Python (boto3) ---
lex_models.build_bot_locale(botId=bot_id, botVersion="DRAFT", localeId="en_US")
# poll until botLocaleStatus is "Built" (or "ReadyExpressTesting")
locale = lex_models.describe_bot_locale(botId=bot_id, botVersion="DRAFT", localeId="en_US")
print(locale["botLocaleStatus"])// --- TypeScript (AWS SDK v3) ---
import { BuildBotLocaleCommand, DescribeBotLocaleCommand } from "@aws-sdk/client-lex-models-v2";
await lexModels.send(new BuildBotLocaleCommand({ botId: botId, botVersion: "DRAFT", localeId: "en_US" }));
// poll until botLocaleStatus is "Built" (or "ReadyExpressTesting")
const locale = await lexModels.send(new DescribeBotLocaleCommand({ botId: botId, botVersion: "DRAFT", localeId: "en_US" }));
console.log(locale.botLocaleStatus);BuildBotLocale only ever builds DRAFT - you cannot build a published version directly.botLocaleStatus (Building -> Built or Failed) before testing.ReadyExpressTesting means a fast partial build good enough for quick manual testing.A version freezes the built DRAFT; an alias is the stable pointer runtime traffic targets.
# --- Python (boto3) ---
version = lex_models.create_bot_version(
botId=bot_id,
botVersionLocaleSpecification={"en_US": {"sourceBotVersion": "DRAFT"}},
)
bot_version = version["botVersion"]
alias = lex_models.create_bot_alias(
botId=bot_id,
botAliasName="prod",
botVersion=bot_version,
)
print(alias["botAliasId"])// --- TypeScript (AWS SDK v3) ---
import { CreateBotVersionCommand, CreateBotAliasCommand } from "@aws-sdk/client-lex-models-v2";
const version = await lexModels.send(new CreateBotVersionCommand({
botId: botId,
botVersionLocaleSpecification: { en_US: { sourceBotVersion: "DRAFT" } },
}));
const botVersion = version.botVersion!;
const alias = await lexModels.send(new CreateBotAliasCommand({
botId: botId,
botAliasName: "prod",
botVersion: botVersion,
}));
console.log(alias.botAliasId);DRAFT and cut a new version.prod) points at a specific version and is what you wire into a channel or client code - move the alias, not client code, to release.TSTALIASID alias that always points at the current DRAFT, for pre-publish testing.botAliasLocaleSettings, covered on the fulfillment page.Related: Lambda Fulfillment & Dialog Hooks - attaching logic before you publish.
Send a real utterance through the runtime client and see what Lex resolves.
# --- Python (boto3) ---
lex_runtime = boto3.client("lexv2-runtime", region_name="us-east-1")
resp = lex_runtime.recognize_text(
botId=bot_id,
botAliasId=alias["botAliasId"],
localeId="en_US",
sessionId="test-session-1",
text="Where is my order",
)
print(resp["sessionState"]["intent"]["name"], resp["sessionState"]["intent"]["state"])// --- TypeScript (AWS SDK v3) ---
import { LexRuntimeV2Client, RecognizeTextCommand } from "@aws-sdk/client-lex-runtime-v2";
const lexRuntime = new LexRuntimeV2Client({ region: "us-east-1" });
const resp = await lexRuntime.send(new RecognizeTextCommand({
botId: botId,
botAliasId: alias.botAliasId!,
localeId: "en_US",
sessionId: "test-session-1",
text: "Where is my order",
}));
console.log(resp.sessionState?.intent?.name, resp.sessionState?.intent?.state);sessionId scopes conversation memory - reuse it across calls in the same conversation, and use a new one per user/session.intent.state reaches ReadyForFulfillment rather than Fulfilled.botAliasId for TSTALIASID to always test against the latest DRAFT without publishing.lexv2-runtime) is entirely separate from the build-time client (lexv2-models) used in every prior step.Related: Runtime Conversation Handling - the full request/response shape and session state.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Revisado por Chris St. John·Última atualização: 24 de jul. de 2026