How the Pieces of an AI Developer Stack Actually Connect

A bundle of four parts reads like a feature list. In practice it behaves like a dependency graph, and the work that decides whether it survives production happens in three seams: shared configuration, runtime handoffs, and version compatibility. Below is a walk through those seams and the failure modes each one produces.

The bundle is a dependency graph, not a list

The four components in a typical AI developer bundle have different release cadences and different opinions about what your project is.

  • The prompt library thinks in templates: an identifier, a version, a set of variables, some model hints.
  • The agent framework thinks in a run loop: messages, tool calls, retries, state.
  • The deployment tooling thinks in artifacts: an image or archive, environment variables, secrets, a target environment.
  • The tutorials think in narrative time. They assume a specific state of the other three at the moment they were written.

None of that is a feature you can evaluate in isolation. The integration surface is a small set of shared objects: one config file, one prompt identity convention, one runtime contract. When a bundle is described as pre-configured to work together, it means someone already made the decisions about those objects. When it breaks, you re-make those decisions under pressure. If you are still deciding which parts belong in an automation pipeline at all, the broader map is in /blog/ultimate-ai-automation-guide-2026/.

Shared configuration: one file, three readers

The config file is the only place where all the parts meet. It should be boring, flat, and versioned.

# stack.config.yaml โ€” read by the prompt loader, agent runtime and deploy tool
schema: 2                      # bump when keys change meaning, not when they are added
project: support-triage

prompts:
  root: ./prompts
  defaults:
    temperature: 0.2
    max_tokens: 1024

agents:
  entrypoint: ./agents/triage.py
  prompt_refs:
    - classify_intent@v3       # version pinned at deploy time, not at import time
    - draft_reply@v2

deploy:
  target: container
  env: ${STACK_ENV:-staging}   # one expansion pass, at load
  secrets_from: .env.${STACK_ENV}

runtime:
  python: "3.11"
  framework: ">=0.9,<1.0"

Four rules keep this from rotting:

  1. No logic in config. Conditionals and string templating in YAML become an untestable programming language with no debugger.
  2. One expansion pass. Environment variables expand once, at load. If deploy.secrets_from is itself templated, you now have two resolution orders and a bug class that only appears in CI.
  3. Fail on unknown keys. A typo’d max_token should stop the build, not fall back silently to the model default.
  4. Write the override precedence down. If prompts.defaults.temperature and a per-prompt temperature both exist, one wins. Document which; the framework will not guess the same way across versions.

Where the handoffs actually happen

The first handoff is prompt to agent, and the common mistake is treating a prompt as a string. Treat it as an object: identity, version, declared variables, model hints. That makes the boundary testable, because a template with an undeclared variable can fail at load instead of after you have already paid for a model call.

from stack.prompts import registry

reg = registry.load("stack.config.yaml")
prompt = reg.get("classify_intent")        # resolves the pinned @v3
payload = prompt.render(ticket=text)       # raises on missing or extra variables
result = agent.run(
    prompt_id=prompt.id,
    prompt_version=prompt.version,
    messages=payload,
)

Note the last call. Passing prompt_version into the run means your logs and traces can record which prompt produced which output. Without it, you cannot distinguish a model regression from a prompt edit, and you will spend a day guessing.

The second handoff is agent to deployment. Here you choose how prompts reach production.

Handoff strategyPrompt livesChange without redeployTypical failure mode
Inline in codesource filenoevery wording tweak is a code review and a release
Runtime registry lookupexternal storeyesprod depends on store uptime; versions drift silently
Build-time compilebaked into artifactnoartifact and registry history diverge; hotfixes get messy

Many teams end up with runtime lookup in staging and compiled prompts in production. That is defensible, as long as the config declares which applies per environment instead of leaving it to whatever the deploy script does.

Version compatibility is three problems wearing one name

There are three version spaces in this stack, and only one of them follows semver.

  • Package versions (framework, SDKs) follow semver, imperfectly but predictably.
  • Prompt versions are content. A bump means @v4 exists and a person decided why.
  • Model versions are controlled by your provider. A snapshot deprecation is a version event you did not schedule.

The tutorial problem lives here too. A tutorial written against framework 0.8 and config schema 1 still reads fine at 0.9 and schema 2, which is exactly why people follow it and then wonder why nothing runs. Pin tutorials to a tag, or read them as orientation rather than instructions.

A lock file plus one check command catches most of it:

stack lock --write stack.lock.yaml      # resolve config, prompts, framework, model ids
stack check --strict                    # non-zero exit on any disagreement

# in CI, before tests
stack check --strict || { echo "stack drift"; exit 1; }

check should fail on: a prompt reference in config that does not exist at the pinned version; a framework major outside runtime.framework; a Python version in the deploy image that disagrees with runtime.python; a variable used in a template but not declared.

The failure modes this prevents are boring and expensive. A renamed variable raises at runtime rather than build time. A framework minor version changes how tool calls serialize, and the agent starts looping on a tool it cannot parse. A deploy image gets rebuilt with a newer SDK than the lock file specifies, and the difference only appears under retries. None of this is exotic. All of it is a seam.

What to do next

  1. Write the config schema before the config. List every key the components need to read, mark which are versioned, and give the file a schema number you intend to bump deliberately.
  2. Add stack lock and stack check to CI this week. Non-zero exit on drift. It costs an afternoon and removes a class of “works locally” bugs.
  3. Make prompt identity explicit. id@version, passed into every run and recorded in logs. If you cannot answer which prompt version produced an output, fix that first.
  4. Pick one handoff strategy per environment and declare it. Runtime lookup in staging, compiled prompts in production, is fine when the config says so.
  5. If you want a fixed reference point, the AI Developer Stack Bundle ($79, one-time) packages a prompt library, agent framework, deployment tooling and tutorials that are pre-configured to work together. Read it for the seams, not the feature list: the useful part is seeing which integration decisions were already made, and where you would override them.

Get AI Developer Stack Bundle

AI Developer Stack Bundle โ€” $79, one-time payment, instant download. See the full breakdown on the review page.

๐ŸŽ Want to try before you buy?

Both samples are 100% free. Enter your email to unlock the download links and get our 3-day AI toolkit drip in your inbox.

No spam. Unsubscribe anytime. We respect your privacy.

Or browse the full catalogue in the Slashman Tools storefront.

About the author
Published by slashman413 โ€” writing practical, evergreen guides on money, productivity, developer tooling and the web. More about this site โ†’

Frequently Asked Questions

Should prompts live in code or in a registry?

Compile them into the artifact for production so releases are reproducible, and use a registry lookup in staging where you want to iterate without redeploying. The important part is declaring which environment uses which.

Why does my agent work locally but loop in production?

Usually a version mismatch: the deploy image resolved a newer framework or SDK than your lock file, which can change how tool calls serialize. Pin versions and run a compatibility check before tests.

Do I need a lock file if I already pin versions in config?

Pinning ranges in config is not the same as recording resolved versions. A lock file captures the exact package, prompt and model versions a build used, which is what you need to reproduce or roll back a release.

๐ŸŽ Recommended Tools

๐Ÿ“š Related Articles

๐Ÿ“ฌ Free Weekly AI Product Guides

New tools, templates and automation walkthroughs โ€” plus hands-on updates on the Slashman Tools catalogue. One email a week, zero fluff.

Free forever ยท No spam ยท Unsubscribe anytime ยท Sent instantly

๐ŸŽ Get Free Toolkit