Taking your AgentScope application From Dev to Prod: How to Deploy AgentScope Applications is a multi-step process that goes well beyond writing working agent code. Production deployments require containerization, environment hardening, CI/CD automation, and observability. This guide covers every layer, from preparing your async-first codebase for production to scaling it on Kubernetes using the dedicated agentscope-runtime toolchain.
If you are new to the AgentScope mental model, the ReAct: Reasoning and Acting — The Paper Behind Agent Frameworks primer is a good starting point before continuing here.
Preparing Your AgentScope App for Production
Before touching Docker, your application code must be production-ready. AgentScope v1.0+ made two changes that directly affect deployment posture.
Async-first architecture means every agent call must be awaited. If you still have synchronous agent invocations in your codebase, they will either block the event loop or raise errors under production concurrency. Audit every call site:
# Bad — synchronous call that blocks the event loop
response = agent(user_message)
# Good — properly awaited
response = await agent(user_message)
Explicit model instantiation replaces the old YAML/JSON configuration files. Models are now instantiated directly in code, which makes secret management cleaner — you inject credentials from environment variables rather than baking them into config files:
import os
from agentscope.model import DashScopeChatModel
model = DashScopeChatModel(
api_key=os.environ["DASHSCOPE_API_KEY"],
model_name="qwen-max",
)
Never hardcode API keys. Use environment variables exclusively, and never commit a .env file to your repository.
Structuring entrypoints: create a clean main.py that serves as your single entrypoint. Production runners need a predictable entry point to start your application:
# main.py
import asyncio
import logging
import os
from agentscope.agent import ReActAgent, UserAgent
from agentscope.model import DashScopeChatModel
from agentscope.tool import Toolkit
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s — %(message)s",
)
logger = logging.getLogger(__name__)
async def main() -> None:
toolkit = Toolkit()
# Register your custom tools here
# toolkit.register_tool_function(my_tool_function)
model = DashScopeChatModel(
api_key=os.environ["DASHSCOPE_API_KEY"],
model_name="qwen-max",
)
agent = ReActAgent(
name="ProdAgent",
model=model,
toolkit=toolkit,
)
user = UserAgent()
logger.info("Agent started")
message = "Hello, what can you help me with today?"
while True:
response = await agent(message)
logger.info("Agent: %s", response)
message = await user(response)
if str(message).strip().lower() == "exit":
break
if __name__ == "__main__":
asyncio.run(main())
Note that AgentScope replaced loguru with Python’s native logging module as of v1.0.0. Ensure your logging configuration uses logging.basicConfig or a logging.config.dictConfig setup, not loguru.
Containerizing the Application with Docker
agentscope-runtime (github.com/agentscope-ai/agentscope-runtime) is the official production runtime for AgentScope. It handles containerization, sandboxed tool execution, and Kubernetes orchestration — none of which the core agentscope library manages itself.
Start with a lean Dockerfile. Python 3.10 is the minimum supported version:
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Copy and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application source
COPY . .
# Do not run as root in production
RUN useradd --create-home appuser
USER appuser
CMD ["python", "main.py"]
Your requirements.txt should pin versions to ensure reproducible builds:
agentscope>=1.0.0
# Add other dependencies with pinned versions
Build and test the image locally before pushing:
docker build -t agentscope-app:latest .
docker run --rm \
-e DASHSCOPE_API_KEY=your_key_here \
agentscope-app:latest
Sandboxed tool execution is one of agentscope-runtime’s key features. When your agent uses tools like execute_python_code, the runtime isolates execution inside the container, preventing runaway code from affecting the host. This is critical for any agent that runs user-supplied or LLM-generated code.
Push your image to a container registry (Docker Hub, AWS ECR, Google Artifact Registry, or GitHub Container Registry) before moving to cloud deployment:
docker tag agentscope-app:latest your-registry/agentscope-app:1.0.0
docker push your-registry/agentscope-app:1.0.0
Deploying to a Cloud Virtual Machine
For a first production deployment, a Virtual Private Server (VPS) or cloud VM (AWS EC2, GCP Compute Engine, Azure VM) is the simplest path. This avoids Kubernetes complexity while giving you full control.
Install Docker on your VM, pull your image, and run it as a managed service using Docker Compose:
# docker-compose.yml
version: "3.9"
services:
agentscope-app:
image: your-registry/agentscope-app:1.0.0
restart: unless-stopped
environment:
- DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY}
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
Store secrets in a .env file on the VM (not in the repository), and load them at runtime:
# On the VM
echo "DASHSCOPE_API_KEY=your_actual_key" > /etc/agentscope/.env
docker compose --env-file /etc/agentscope/.env up -d
The restart: unless-stopped policy ensures the container recovers from crashes automatically.
For Kubernetes deployments at scale, agentscope-runtime provides Helm charts and deployment manifests that handle pod scheduling, health checks, and rolling updates. A minimal Kubernetes Deployment looks like:
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: agentscope-app
spec:
replicas: 2
selector:
matchLabels:
app: agentscope-app
template:
metadata:
labels:
app: agentscope-app
spec:
containers:
- name: agentscope-app
image: your-registry/agentscope-app:1.0.0
env:
- name: DASHSCOPE_API_KEY
valueFrom:
secretKeyRef:
name: agentscope-secrets
key: dashscope-api-key
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
Create the Kubernetes secret from your local environment:
kubectl create secret generic agentscope-secrets \
--from-literal=dashscope-api-key="$DASHSCOPE_API_KEY"
Automating Deployments with a CI/CD Pipeline
Manual deployments are error-prone. A CI/CD pipeline (GitHub Actions, GitLab CI, or similar) automates building, testing, and deploying every time you push to main.
Here is a complete GitHub Actions workflow:
# .github/workflows/deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Deploy to VM via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
script: |
docker pull ghcr.io/${{ github.repository }}:latest
docker compose -f /opt/agentscope/docker-compose.yml up -d --force-recreate
Store VM_HOST, VM_USER, and VM_SSH_KEY as GitHub repository secrets. Never put these values directly in the workflow file.
This pipeline gives you immutable image tags via github.sha. Every deployment is traceable to a specific commit, which makes rollbacks straightforward — just update the image tag to a previous SHA and redeploy.
Monitoring, Logging, and Tracing
Production agents fail in ways local tests never reveal. Observability is not optional.
Structured logging: AgentScope v1.0.0 uses Python’s native logging module. Configure it to emit JSON for log aggregation tools like Datadog, Loki, or CloudWatch:
import logging
import json
class JsonFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
log_entry = {
"time": self.formatTime(record),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
}
if record.exc_info:
log_entry["exception"] = self.formatException(record.exc_info)
return json.dumps(log_entry)
handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
logging.basicConfig(handlers=[handler], level=logging.INFO)
OpenTelemetry tracing: AgentScope v1.0.0 adopts OpenTelemetry as its standard tracing mechanism. This integrates with observability platforms like Jaeger, Tempo, or any OTLP-compatible backend. Install the SDK and configure an exporter:
pip install opentelemetry-sdk opentelemetry-exporter-otlp
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
provider = TracerProvider()
exporter = OTLPSpanExporter(endpoint="http://your-otel-collector:4317")
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
With tracing in place, you can follow a single user conversation through every tool call and model invocation, which is invaluable when debugging unexpected agent behavior in production.
Scaling: For stateless agents, horizontal scaling is straightforward — add more replicas in your Kubernetes Deployment or run more containers behind a load balancer. If your agent uses MsgHub for multi-agent coordination, ensure all replicas connect to a shared message broker or that requests are routed to a single coordinator pod. The built-in distribution module is temporarily deprecated in v1.0.0, so plan your multi-agent scaling architecture carefully until the replacement lands.
For tips on designing agents that remain coherent across long sessions, the Getting Started with AutoGen: Build Your First Multi-Agent System article shows complementary patterns for stateful multi-agent coordination that translate well to AgentScope deployments.
Frequently Asked Questions
Does the core agentscope library handle production deployment?
No. The core agentscope package handles agent logic, model wrappers, and toolkits. For production deployment — Docker containerization, Kubernetes orchestration, and sandboxed tool execution — you need the separate agentscope-runtime project. Treat them as complementary: agentscope for what your agent does, agentscope-runtime for where and how it runs.
How do I manage API keys securely in production?
Never hardcode API keys or commit .env files to your repository. On a VM, store secrets in a protected file (chmod 600) and load them at container runtime via --env-file. On Kubernetes, use kubectl create secret and reference secrets via secretKeyRef in your Deployment manifest. In CI/CD, use your platform’s encrypted secrets store (GitHub Actions Secrets, GitLab CI Variables).
What happened to DialogAgent and model configuration files in v1.0.0?
Both are deprecated. DialogAgent and DictDialogAgent are replaced by ReActAgent. Global model configuration files (YAML/JSON) are replaced by explicit in-code instantiation (e.g., DashScopeChatModel(api_key=...)). Migrating before deployment is required — attempting to use deprecated APIs in production will result in errors.
How do I roll back a bad deployment?
Because the CI/CD pipeline tags images with the Git commit SHA, rollback is a one-line operation. On Kubernetes, update the image tag in your Deployment manifest to the previous known-good SHA and apply it. On a VM with Docker Compose, pull the previous image tag and restart the service. This is why immutable image tagging matters.
Can AgentScope agents run user-supplied code safely in production?
Only with agentscope-runtime’s sandboxed execution environment. The runtime isolates tool calls like execute_python_code inside the container, preventing arbitrary code from escaping to the host. Do not run user-supplied or LLM-generated code in production without this sandboxing layer in place.