Release Radar Part 2:Deploying to Bedrock AgentCore

작성자

카테고리:

← 피드로
DEV Community · joshyfruit · 2026-09-08 개발(SW)

In Part 1, we have built Release Radar, an agent that audits pinned dependencies. It catches three failures that version numbers miss: renamed repos, archived projects, and release notes that say “This package/modeule is deprecated and will reach End-of-Life.”

Last time, we made it work on our laptop. This time, we will run it on our own infrastructure. So, we might think that we need to deploy this on Lambda or through EKS, but AWS made deployment easy through AgentCore.

AWS Bedrock AgentCore is a managed service that can deploy your local Agent code (Strands, LangGraph, or CrewAI) to scale in production without requiring custom backend plumbing. AgentCore handles hosting, scaling, IAM, and observability.

So instead of configuring through our web console on a Lambda function and exposing it through an API Gateway, AgentCore manages it for us via the CLI.

The 250MB fork

Package size sets the pace of every deploy after the first one.

When you run agentcore deploy, the CLI takes one of two paths:

Deployment Diagram

Under 250MB, the CLI packages your code, pushes it to an S3 bucket, and points the runtime at the asset. Installation takes seconds; then it builds a container and manages the runtime.

Release Radar has only two dependencies:

[project]
name = "release-radar"
requires-python = ">=3.10"
dependencies = [
  "bedrock-agentcore",
  "strands-agents",
]

Enter fullscreen mode Exit fullscreen mode

Strands also ships strands-agents-tools, a companion package with a large collection of prebuilt tools. I left it out. The three tools in this project take forty lines of standard-library urllib, and keeping the extra package out leaves Release Radar on the fast path.

Native wheels tend to push packages over the limit: numpy, pandas, torch, and anything else with compiled extensions. Sometimes you need them. Just account for the slower deployment loop when you do.

The trust boundary

Once deployed, a request follows this path:

Agentcore Request flow

Validation happens at the entry point, before the model receives anything:

from bedrock_agentcore import BedrockAgentCoreApp
from strands import Agent
from tools import repo_status, latest_release, version_gap

app = BedrockAgentCoreApp()

@app.entrypoint
async def handler(request):
    prompt = request.get("prompt")
    if not isinstance(prompt, str) or not prompt.strip():
        raise ValueError("prompt must be a non-empty string")

    agent = Agent(
        system_prompt=SYSTEM,
        tools=[repo_status, latest_release, version_gap],
    )
    async for event in agent.stream_async(prompt):
        yield event

app.run()

Enter fullscreen mode Exit fullscreen mode

That’s four lines of validation. AWS’s SDK docs give the same direct advice: validate agent input before handing it to a framework, require prompts to be strings, and send only the prompt text to the agent.

Release Radar needs this boundary because its job is to read text written by other people. Repository descriptions and release notes are attacker-writable. Someone can publish release notes containing text that looks like instructions for the agent.

Once the agent reads untrusted text, that text enters the prompt. Downstream checks cannot undo that, so the entrypoint accepts one validated string and nothing else.

stream_async then yields chunks as they arrive. An audit of ten dependencies can show results as the agent produces them instead of waiting for the entire run.

Deploy

agentcore validate
agentcore deploy
agentcore status

Enter fullscreen mode Exit fullscreen mode

The first deployment provisions CDK infrastructure and takes a few minutes. Later deployments only replace the S3 asset, which is much faster.

A shell export stays on your machine. If you set GITHUB_TOKEN in your terminal during local testing, the deployed runtime cannot see it. Put the token in agentcore/.env.local (which is gitignored), or register it properly:

agentcore add credentials    # stored in Secrets Manager
agentcore deploy             # ← the part people forget

Enter fullscreen mode Exit fullscreen mode

The second command matters because agentcore add and agentcore remove change only the local configuration. AWS sees no change until you deploy again.

Config drift between agentcore.json and the deployed stack is the most common cause of “but it works locally.”

Invoke, then read the trace

agentcore invoke

agentcore logs              # stream or search runtime logs
agentcore traces list       # recent traces
agentcore traces get <id>   # download one as JSON

Enter fullscreen mode Exit fullscreen mode

Read the trace. An agent can produce an answer that looks right without reaching it the right way. The tool-call sequence tells you which one you got.

For three dependencies, a healthy run makes six to nine tool calls: one repo_status and one latest_release per dependency, followed by version_gap wherever a release exists.

The trace catches problems that the final output hides:

  • If there are too few calls, the model probably answered from its training data instead of checking the repositories. The answer may still look plausible. A weak docstring often causes this.
  • If version_gap receives an empty tag, latest_release probably reached a repository that publishes tags instead of releases. That is expected, and the error’s hint field explains it.
  • If the calls happen in the wrong order, the model did not follow the system prompt. repo_status goes first so a rename cannot disappear beneath version chatter. Tighten the prompt if it does.

What breaks

Symptom Cause Fix command not found Old toolkit shadowing the new CLI Uninstall bedrock-agentcore-starter-toolkit; which -a agentcore must return one path HTTP 403 Anonymous GitHub limit is 60/hr; this spends ~3 per dependency Set GITHUB_TOKEN locally and in the runtime HTTP 404 Repo publishes tags not releases, or you queried a renamed path Expected — repo_status still resolves renames AccessDenied Bedrock model access not enabled in that region Enable Claude Sonnet in the Bedrock console for your aws-targets.json region Deploy got slow Package crossed 250MB Drop unused deps; keep native wheels out of app/ Tools never called Docstrings lost in copy Every @tool needs a docstring saying when to call it Works local, fails deployed Env var never left your shell agentcore/.env.local or agentcore add credentials, then redeploy

You’ll probably meet the 403 first. At roughly three API calls per dependency, one run over a twenty-dependency manifest uses the entire anonymous allowance of 60 requests per hour.

Turn it off

A deployed runtime keeps billing while it exists.

agentcore remove     # pick resources to drop
agentcore deploy     # applies the removal to AWS
agentcore status     # confirm nothing is left

Enter fullscreen mode Exit fullscreen mode

I checked the full command surface. There is no destroy, down, or delete command, and deploy has no destroy flag. The teardown path really is remove followed by deploy. To clear everything, use remove all:

agentcore remove all -y    # "Reset all agentcore schemas to empty state"
agentcore deploy -y        # log prints: ✓ Tear down stack

Enter fullscreen mode Exit fullscreen mode

A clean status is not enough. Check from outside the CLI:

aws cloudformation describe-stacks --stack-name AgentCore-<project>-default
# → ValidationError: stack does not exist

aws bedrock-agentcore-control list-agent-runtimes --region <region>
# → empty

Enter fullscreen mode Exit fullscreen mode

Both checks came back clean after my run. The generated IAM role also returned NoSuchEntity.

I have left pricing figures out. They will age faster than the rest of this post, so check the current Bedrock and AgentCore Runtime rates before leaving resources running.

Four ways to extend it

Each extension starts with one add command and requires another deploy.

Run agentcore add memory to give the agent last week’s verdicts. This is the most useful addition of the four. Instead of reading every result as new, it can report changes such as “3 new BLOCKED since Monday.” That produces a report you can skim and act on.

A web-search gateway can find a migration guide after the agent flags a dependency:

agentcore add gateway-target --type connector --connector web-search --gateway <name> --name <target>

Use --exclude-domains to keep content farms out.

agentcore add evaluator defines an LLM-as-a-judge, and agentcore run eval scores it against real traces. Add this once verdicts start driving real decisions.

agentcore add policy-engine applies Cedar policies before and after calls, including prompt-attack detection. That fits this project because the agent reads attacker-writable release notes.

There is also agentcore add harness. It puts the runtime, model, tools, memory, and observability into declarative configuration, with no agent code. If you outgrow that setup, agentcore export harness converts it into a Strands agent. Read the generated EXPORT_NOTES.md before deploying because it lists anything the exporter could not automate.

What I wish I’d known

Docstrings route tool calls. When an agent ignores a tool, a vague docstring is often the problem, not the model.

The deterministic code still needs tests. I shipped a real version-comparison bug, and Part 1 has the autopsy. Five assertions found it in thirty seconds. A model may make part of the system fuzzy, but arithmetic is still arithmetic.

Run the agent locally before deploying it. agentcore dev uses the same entrypoint against real Bedrock on your machine, so a bad tool signature fails in seconds rather than after an upload.

Part 1 originally said, “I have not run this end-to-end against live AWS.” That is no longer true. I deployed Release Radar to a real account, invoked it, tore it down, and verified the teardown outside the CLI. The deployment details above came from that run.

The run also forced four corrections. The most visible one is the scaffold from agentcore create, which is much richer than the version shown in Part 1. It has a two-argument entrypoint, a different import path, a generated model loader, and five dependencies instead of two. Part 1 shows the version you would write by hand because it makes the shape easier to learn. When working from the scaffold, modify the generated file instead of replacing it.

Two more corrections affect how you run it. Bedrock’s on-demand model IDs do not invoke in every region, so you need the global. inference profile. The CLI handles that for you. Automation also needs explicit flags because bare agentcore deploy refuses to run without a TTY.

Deployment enables transaction search automatically. It takes about ten minutes to index and adds a cost I had not accounted for.

If you build this and find another mistake, I want to hear about it. Corrections are the point of this project.

원문에서 계속 ↗