# SmartAIBytes — Full Documentation > Free, high-depth tutorials and expert blogs on AI Agent development, Generative AI testing, and integrating AI within modern software testing methodologies. --- ## Tutorials ### Getting Started with Google ADK: Your First AI Agent - **URL**: http://localhost:3000/tutorials/getting-started-google-adk - **Difficulty**: beginner - **Duration**: 10 min - **Category**: AI Agents - **Tags**: Google ADK, AI Agents, Python, Cloud Run ## Prerequisites Before starting, ensure you have: - Python 3.11+ installed - A Google Cloud account with billing enabled - Basic familiarity with Python async/await patterns ## What is Google ADK? The Agent Development Kit (ADK) is Google's open-source framework for building, testing, and deploying AI agents. It provides: - A structured agent class hierarchy - Built-in tool registration and execution - Session management and memory - Deployment utilities for Google Cloud ## Step 1: Install ADK ```bash pip install google-adk ``` ## Step 2: Define Your Agent ```python from google.adk.agents import Agent from google.adk.tools import tool @tool def search_web(query: str) -> str: """Search the web for information.""" # Implementation here return f"Results for: {query}" agent = Agent( name="research_assistant", model="gemini-2.0-flash", tools=[search_web], instruction="You are a helpful research assistant.", ) ``` ## Step 3: Test Locally ```bash adk web ``` This starts a local web interface where you can chat with your agent. ## Step 4: Deploy to Cloud Run ```bash adk deploy cloud_run --project my-project --region us-central1 ``` ## What's Next? In the next tutorial, we'll add multi-tool orchestration and implement a human-in-the-loop approval workflow. --- ### Multi-Agent Orchestration with Strands - **URL**: http://localhost:3000/tutorials/multi-agent-orchestration-strands - **Difficulty**: advanced - **Duration**: 10 min - **Category**: AI Agents - **Tags**: Strands, Multi-Agent, Python, Orchestration ## Why Multi-Agent Systems? Single agents hit a ceiling when tasks require diverse expertise. Multi-agent systems decompose complex problems across specialized agents that collaborate to achieve outcomes no single agent could. In strands there are multiple ways to build multi agent systems: 1. **Agent as a Tool** - This the simplest way to develop a multi agent system in strands. In this specialized agents are given to orchestrator agent as a tool. Which decide when to call which agent. 2. **Graph** - Graph gives a determinitic approach to multi agent system execution. In this approach specialized agents fucntion as nodes and data flow is defined by edges connecting them. 3. **Swarm** - This is the most advanced way to develop a multi agent system in strands. In this agents are given a common goal and they collaborate to achieve it. ## Defining Multi Agents ```python import logging from strands import Agent from strands.multiagent import Swarm # Enable debug logs and print them to stderr logging.getLogger("strands.multiagent").setLevel(logging.DEBUG) logging.basicConfig( format="%(levelname)s | %(name)s | %(message)s", handlers=[logging.StreamHandler()] ) # Create specialized agents researcher = Agent(name="researcher", system_prompt="You are a research specialist...") coder = Agent(name="coder", system_prompt="You are a coding specialist...") reviewer = Agent(name="reviewer", system_prompt="You are a code review specialist...") architect = Agent(name="architect", system_prompt="You are a system architecture specialist...") # Create a swarm with these agents, starting with the researcher swarm = Swarm( [coder, researcher, reviewer, architect], entry_point=researcher, # Start with the researcher max_handoffs=20, max_iterations=20, execution_timeout=900.0, # 15 minutes node_timeout=300.0, # 5 minutes per agent repetitive_handoff_detection_window=8, # There must be >= 3 unique agents in the last 8 handoffs repetitive_handoff_min_unique_agents=3 ) ``` ## Running the agents ```python # Execute the swarm on a task result = swarm("Design and implement a simple REST API for a todo app") # Or use invoke_async for async execution: result = await swarm.invoke_async(...) # Access the final result print(f"Status: {result.status}") print(f"Node history: {[node.node_id for node in result.node_history]}") ``` ## Conclusion Multi-agent orchestration is the future of complex AI workflows. Strands provides a clean abstraction for designing these systems. Strands provides various ways to develope multi agent systems that can achieve different agentic pattern. --- ## Blog Posts ### Why We Need Guardrails for AI Agents - **URL**: http://localhost:3000/blog/why-we-need-guardrails-for-AI-Agents - **Category**: AI Security - **Tags**: AI Agents, Guardrails, AI Security, LLM - **Published**: 2026-03-28 ## Introduction AI agents are getting more and more powerful and are being adopted widely. However, with the increasing power of AI agents comes the increasing risk of AI agents causing harm. While LLMs have their own security measures in place, it is not enough to prevent AI agents from causing harm. That is why we need to implement guardrails for AI agents. ## What are Guardrails? > Guardrails are a set of rules and constraints that are put in place to prevent AI agents from causing harm. They are a way to ensure that AI agents are used safely and responsibly. In the context of AI agents, guardrails are implemented to prevent the AI agent from taking actions that could cause harm to the user or the system, they can detect and prevent malicious inputs, outputs, and actions at key points during the agent's execution. ## Why AI Agents Need Guardrails when LLMs have their own security measures? LLMs are trained on massive datasets and envisioned for wide range of applications. Their security measures and guardrails are designed for general threats and issues like General Ethics, Toxicity, PII leakage, Jailbreaking, etc. However, when LLMs are used in AI agents, they are used in specific contexts and for specific purposes. In such cases, the general security measures and guardrails are not enough to prevent AI agents from causing harm. AI Agents nowadays are more capable and have access to a wide variety of tools and in some cases proprietary data and systems. Here are a few examples where LLM's security measures are not enough to prevent AI agents from causing harm and thus require additional guardrails: 1. **PII Leakage via Tool Call** - LLM's security measures are designed to prevent PII leakage from the LLM's responses. However, AI agents can call tools that can access PII data. For **example**, if an AI Agent has access to two tools, one to `fetch_customer_data` from a database and another to `send_promotional_email` to users, if the AI agent is not properly configured, it can send one customer's data to all the customers. 2. **Dangerous operation** - AI agents can be used to perform dangerous operations. For **example**, an AI agent can be used to delete all the data from a database. If the AI agent is not properly configured, it can lead to data loss. LLMs consider this operation as safe because they only generate instructions for the AI Agent to execute a particular tool. We need to implement guardrails to prevent AI agents from performing dangerous operations. 3. **Context aware and Specific Limitation** - LLM's security measures are designed for general threats and issues. However, AI agents are used in specific contexts and for specific purposes. In such cases, any specific limitation or business rules required for the AI agent is not taken into consideration by the LLM's security measures. For **example**, if an AI Agent is designed to provide customer support for an e-commerce company, it should not be able to issue a refund beyond a certain amount. The LLM itself isn't aware of this specific limitation and can issue a refund beyond the certain amount if not restricted by specific guardrails. 4. **Cost of AI Usage** - LLMs are single-turn operations, but AI Agents can run in loops and can call multiple tools. An agent stuck in a loop and making expensive calls, like analyzing large file content or API responses, consumes a lot of tokens and can lead to unexpected costs. We need to implement guardrails to prevent AI agents from performing expensive operations in loops. ## Guardrail Types and Implementation Guardrails primarily fall into three categories (though they are not limited to these): **Input Guardrail** - Input guardrails are used to validate the input to the AI agent. They are used to prevent the AI agent from processing malicious input. They can be configured to block processing of dangerous inputs like prompt injection, jailbreaking attempts, etc. **Output Guardrail** - Output guardrails are used to validate the output of the AI agent. They are used to prevent the AI agent from generating malicious or unethical output. They can also be used to ensure that the output is in the desired format. **Execution Guardrail** - Execution guardrails prevent AI agents from performing malicious operations, directly or via tools. They can also be configured to prevent the AI agent from going off-topic, getting stuck in a loop, or performing expensive operations. Human-in-the-loop implementation can also be considered part of an execution guardrail. ### Implementation **Inbuilt Guardrails** - Many AI agent frameworks like Google ADK, LangChain, etc., provide inbuilt guardrails. In LangChain, inbuilt middleware can be used to implement guardrails; it comes with middlewares like PII detection, Model call limit, Tool call limit, Human-in-the-loop, etc. ```python from langchain.agents.middleware import ModelCallLimitMiddleware ModelCallLimitMiddleware( thread_limit=10, run_limit=5, exit_behavior="end", ), ``` Similarly in ADK we can use SafetySetting class in types module to create filter and threshold for various safety categories like hate speech, harassment, etc. ```python from google.genai.types import SafetySetting, HarmCategory, HarmBlockThreshold safety_settings = [ SafetySetting( category=HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold=HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, ), ] ``` **Custom Guardrails** - Platforms like AWS Bedrock provide features to create custom guardrail patterns and content rules. It also provides the feature to use their predefined guardrails. Then these guardrails can be used to validate the input, output, and actions of the AI agent built using standards or Bedrock agent SDKs. Instruction based custom guardrails can also be used with any agentic framework. We can give the rules and filters in the system prompt of the agent. ```python CUSTOM_GUARDRAILS = """ Please follow the input, output, and tool execution rules strictly: 1. Custom input rules 2. Custom Output rules 3. Custom Tool execution rules """ ``` Alternatively, we can also have a separate Guard Agent in a multi-agent system to validate the input and output. This agent can be a simple rule-based agent or a complex LLM-based agent. **Human-In-The-Loop Guardrails** - Almost all agentic frameworks provide a way to implement human-in-the-loop guardrails. It can be used to pause the execution of the agent and wait for human approval before proceeding. This is a very important and powerful tool to guard against dangerous operations and tool execution by the agent. Before executing any tool or action, we can ask for human approval, showing the parameters and expected output of the tool or action. ## Best Practices 1. **Use multiple layers of guardrails** - Don't rely on a single type of guardrail. Use a combination of input, output, and execution guardrails to create a comprehensive safety system. Use inbuilt, platform-based, and custom guardrails to create a comprehensive safety system. 2. **Test your guardrails regularly** - AI agents are constantly evolving, so you need to test your guardrails regularly to ensure they are still effective. 3. **Keep your guardrails updated** - As new threats and vulnerabilities emerge, you need to update your guardrails to stay ahead of potential attacks. 4. **Use human-in-the-loop guardrails for critical operations** - For critical operations like deleting data or making financial transactions, always use human-in-the-loop guardrails to ensure that the AI agent is not making mistakes. 5. **Monitor your guardrails** - Use monitoring tools to track the effectiveness of your guardrails and identify any issues that need to be addressed. Log low-level details of guardrail triggers and responses. Log false positives and use them to improve your guardrails. 6. **Perform Red Teaming** - Regularly perform red teaming exercises to identify vulnerabilities in your guardrails and improve them. ## Conclusion As we move towards more autonomous AI agents, the need for robust guardrails becomes increasingly important. Guardrails are not a replacement for good agent design, but they are an essential part of any production-ready AI agent. By implementing a comprehensive guardrail strategy, we can ensure that our AI agents are safe, reliable, and trustworthy. It is important to have comprehensive agent guardrails along with the LLM's inbuilt safety measures to maintain the integrity of the AI agents. *For any feedback and questions, feel free to write to us at* [contact@smartaibytes.com](mailto:contact@smartaibytes.com) --- ### Building Reliable AI Agents with LangGraph: A Practical Deep Dive - **URL**: http://localhost:3000/blog/building-reliable-ai-agents-langgraph - **Category**: AI Agents - **Tags**: LangGraph, AI Agents, Python, State Machines - **Published**: 2026-03-20 ## Introduction AI agents represent a paradigm shift from traditional software — they make decisions, use tools, and adapt their behavior based on context. But building agents that work reliably in production requires more than just chaining LLM calls. In this deep dive, we'll explore LangGraph, a framework that models agent workflows as state machines, giving you fine-grained control over execution flow, error handling, and human intervention points. ## Why State Machines for Agents? Traditional agent frameworks often use simple loops: the LLM decides what to do, executes an action, observes the result, and repeats. This works for demos but fails in production because: 1. **No structured error recovery** — when a tool call fails, the agent may spiral 2. **No checkpoint/resume** — long-running workflows can't survive process restarts 3. **No visibility** — it's hard to understand why an agent made specific decisions LangGraph solves these by treating each step as a node in a directed graph, with explicit edges defining the flow between states. ## Core Architecture Pattern ```python from langgraph.graph import StateGraph, END class AgentState(TypedDict): messages: list tool_results: list iteration_count: int graph = StateGraph(AgentState) graph.add_node("reason", reason_node) graph.add_node("act", action_node) graph.add_node("observe", observation_node) graph.add_edge("reason", "act") graph.add_edge("act", "observe") graph.add_conditional_edges("observe", should_continue, { "continue": "reason", "end": END, }) ``` ## Implementing Error Recovery The key insight is adding explicit error-handling nodes to your graph. When a tool call fails, instead of letting the LLM figure out what to do, you route to a dedicated recovery node that can: - Retry with exponential backoff - Fall back to an alternative tool - Escalate to a human reviewer - Log the failure and gracefully degrade ```python def should_continue(state: AgentState) -> str: last_result = state["tool_results"][-1] if last_result.get("error"): if state["iteration_count"] < MAX_RETRIES: return "retry" return "escalate" if last_result.get("final_answer"): return "end" return "continue" ``` ## Human-in-the-Loop Workflows LangGraph's checkpointing system makes it trivial to implement approval gates: ```python graph.add_node("await_approval", human_approval_node) graph.add_edge("propose_action", "await_approval") graph.add_conditional_edges("await_approval", check_approval, { "approved": "execute_action", "rejected": "revise_proposal", }) ``` The execution pauses at `await_approval`, serializes the full state to a checkpoint store, and resumes when the human provides their decision — even days later. ## Conclusion LangGraph provides the control plane that production AI agents need. By modeling workflows as state machines, you gain deterministic error recovery, checkpoint/resume capabilities, and clear observability into agent behavior. The investment in structured agent design pays dividends in reliability and maintainability. ---