Chapter 18 · Agents Get Started
Subchapter 18.1
references/example-support-agent.mdMarkdown7 KBView on GitHub
A complete, realistic example of a customer support agent scaffolded with agentcore create. Use this as a reference when the developer asks to “build a customer support agent” or similar task-framed prompts.
Answers customer questions about product policies, shipping, and returns. Uses Strands as the framework, Bedrock (Claude Sonnet) as the model, and starts without memory or tools (both can be added later).
agentcore create \
--name SupportAgent \
--framework Strands \
--protocol HTTP \
--build CodeZip \
--model-provider Bedrock \
--memory noneAfter scaffolding, app/SupportAgent/main.py looks something like:
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
from model.load import load_model # scaffolded by `agentcore create` in model/load.py
app = BedrockAgentCoreApp()
SYSTEM_PROMPT = """You are a customer support agent for Acme Corp.
You answer questions about product policies, shipping, and returns.
Guidelines:
- Be concise and friendly
- If you don't know the answer, say so — don't make up policies
- For order-specific questions, ask for the order number
- Escalate to a human agent if the customer expresses frustration"""
@app.entrypoint
def invoke(payload, context):
agent = Agent(
model=load_model(),
system_prompt=SYSTEM_PROMPT,
)
result = agent(payload.get("prompt", ""))
return {"response": str(result)}
if __name__ == "__main__":
app.run()The generated
model/load.pyreturns aBedrockModelconfigured with a cross-region inference profile (e.g.,global.anthropic.claude-sonnet-4-5-*). Usingload_model()instead of hardcoding the model ID means your code tracks whatever default the CLI ships. To use a different model, editmodel/load.py.
agentcore devIn another terminal:
curl -X POST http://localhost:8080/invocations \
-H "Content-Type: application/json" \
-d '{"prompt": "What is your return policy?"}'agentcore deployAfter the basic agent is working, the developer typically asks for one of these next:
| “I want to…” | Next skill |
|---|---|
| “Let it look up orders in our database” | agents-connect (add a gateway target for the order API) |
| “Remember the customer’s name between sessions” | agents-build (loads references/memory.md (opens in a new tab)) |
| “Make sure it can’t say anything off-policy” | agents-connect (loads references/policy.md (opens in a new tab)) |
| “Put it on our website” | agents-build (loads references/integrate.md (opens in a new tab)) |
| “Know if it’s actually helpful” | agents-optimize |
agentcore create --name SupportAgent --framework LangChain_LangGraph --model-provider Bedrock --memory noneGenerated main.py uses create_react_agent and langchain_aws:
from langchain_core.messages import HumanMessage, SystemMessage
from langgraph.prebuilt import create_react_agent
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from model.load import load_model
app = BedrockAgentCoreApp()
SYSTEM_PROMPT = "..." # same as Strands version
@app.entrypoint
async def invoke(payload, context):
graph = create_react_agent(load_model(), tools=[])
result = await graph.ainvoke({
"messages": [
SystemMessage(content=SYSTEM_PROMPT),
HumanMessage(content=payload["prompt"]),
]
})
return {"response": result["messages"][-1].content}
if __name__ == "__main__":
app.run()agentcore create --name SupportAgent --framework OpenAIAgents --model-provider OpenAI --memory nonefrom agents import Agent, Runner
from bedrock_agentcore.runtime import BedrockAgentCoreApp
app = BedrockAgentCoreApp()
@app.entrypoint
async def invoke(payload, context):
agent = Agent(
name="SupportAgent",
instructions="...", # same as Strands version
)
result = await Runner.run(agent, payload["prompt"])
return {"response": result.final_output}
if __name__ == "__main__":
app.run()agentcore create --name SupportAgent --framework GoogleADK --model-provider Gemini --memory nonefrom google.adk.agents import Agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from bedrock_agentcore.runtime import BedrockAgentCoreApp
app = BedrockAgentCoreApp()
agent = Agent(
model="gemini-2.5-flash",
name="SupportAgent",
description="Customer support agent",
instruction="...", # same as Strands version
)
@app.entrypoint
async def invoke(payload, context):
user_id = payload.get("user_id", "default_user")
session_id = getattr(context, "session_id", "default_session")
session_service = InMemorySessionService()
session = await session_service.create_session(
app_name="support", user_id=user_id, session_id=session_id
)
runner = Runner(agent=agent, app_name="support", session_service=session_service)
content = types.Content(role="user", parts=[types.Part(text=payload["prompt"])])
async for event in runner.run_async(user_id=user_id, session_id=session.id, new_message=content):
if event.is_final_response():
return {"response": event.content.parts[0].text}
if __name__ == "__main__":
app.run()The CLI supports four model providers:
| Provider | Best for | Notes |
|---|---|---|
Bedrock | Default, no API key needed, IAM-based auth | Uses cross-region inference profiles (e.g., global.anthropic.claude-sonnet-4-5-*) |
Anthropic | Direct Anthropic API access | Requires ANTHROPIC_API_KEY; model IDs like claude-sonnet-4-5-20250929 |
OpenAI | GPT-4 / GPT-5 models | Requires OPENAI_API_KEY; typically paired with OpenAI Agents SDK |
Gemini | Google Gemini models | Requires GEMINI_API_KEY; typically paired with Google ADK |
For cost-sensitive use cases, consider Bedrock Nova models (e.g., amazon.nova-micro-v1:0, amazon.nova-lite-v1:0) — significantly cheaper than Claude for simpler extractive tasks. See agents-optimize/references/cost.md (opens in a new tab) for model selection guidance.
For a chatbot that remembers conversations, add --memory longAndShortTerm during scaffolding. Memory can also be added later — see agents-build/references/memory.md (opens in a new tab).