• About Us
  • Disclaimer
  • Contact Us
  • Privacy Policy
Sunday, July 26, 2026
mGrowTech
No Result
View All Result
  • Technology And Software
    • Account Based Marketing
    • Channel Marketing
    • Marketing Automation
      • Al, Analytics and Automation
      • Ad Management
  • Digital Marketing
    • Social Media Management
    • Google Marketing
  • Direct Marketing
    • Brand Management
    • Marketing Attribution and Consulting
  • Mobile Marketing
  • Event Management
  • PR Solutions
  • Technology And Software
    • Account Based Marketing
    • Channel Marketing
    • Marketing Automation
      • Al, Analytics and Automation
      • Ad Management
  • Digital Marketing
    • Social Media Management
    • Google Marketing
  • Direct Marketing
    • Brand Management
    • Marketing Attribution and Consulting
  • Mobile Marketing
  • Event Management
  • PR Solutions
No Result
View All Result
mGrowTech
No Result
View All Result
Home Al, Analytics and Automation

The Practitioner’s Guide to AgentOps

Josh by Josh
June 10, 2026
in Al, Analytics and Automation
0
The Practitioner’s Guide to AgentOps


# research_agent.py

# Purpose: A research agent with full AgentOps instrumentation.

# Every session is logged, replayed, and cost-tracked in the AgentOps dashboard.

#

# Prerequisites:

#   pip install agentops anthropic python-dotenv

#

# Environment variables required (in .env):

#   AGENTOPS_API_KEY — from https://app.agentops.ai

#   ANTHROPIC_API_KEY — from https://console.anthropic.com

#

# How to run:

#   python research_agent.py

 

import os

import json

import time

from dotenv import load_dotenv

import anthropic

import agentops

from agentops.sdk.decorators import record_function

 

load_dotenv()

 

# ── Initialize AgentOps ────────────────────────────────────────────────────────

# This must be called before any agent code runs.

# Tags let you filter and group sessions in the dashboard.

# The SDK automatically intercepts LLM calls once initialized.

agentops.init(

    api_key=os.environ[“AGENTOPS_API_KEY”],

    tags=[“research-agent”, “production”, “v1.0”],

    auto_start_session=True       # Automatically starts a session on init

)

 

# Initialize the Anthropic client after AgentOps — the SDK wraps LLM clients

# to automatically capture every call’s input, output, tokens, and cost.

client = anthropic.Anthropic(api_key=os.environ[“ANTHROPIC_API_KEY”])

 

MODEL = “claude-sonnet-4-20250514”

 

# ── System prompt ─────────────────────────────────────────────────────────────

# Stored as a constant, not inline — version-controllable and testable.

SYSTEM_PROMPT = “”“You are a research assistant. When given a topic:

1. Use the available tools to gather information systematically

2. Call search_topic to get an overview of the subject

3. Call get_key_facts to extract the most important points

4. Call format_summary to structure the final output

 

Be thorough but concise. Always call format_summary as your final step.”“”

 

# ── Tool definitions ──────────────────────────────────────────────────────────

# These are the tools the agent can call. In a real system, search_topic

# would call a real search API (Tavily, SerpAPI, etc.). Here they are stubs

# that return realistic data so you can run the example without external APIs.

TOOLS = [

    {

        “name”: “search_topic”,

        “description”: (

            “Search for comprehensive information about a topic. “

            “Returns an overview with key themes and context. “

            “Use this as the first step for any research task.”

        ),

        “input_schema”: {

            “type”: “object”,

            “properties”: {

                “topic”: {

                    “type”: “string”,

                    “description”: “The topic to research. Be specific.”

                },

                “depth”: {

                    “type”: “string”,

                    “enum”: [“overview”, “detailed”],

                    “description”: “How deep to search. Use ‘overview’ first.”

                }

            },

            “required”: [“topic”]

        }

    },

    {

        “name”: “get_key_facts”,

        “description”: (

            “Extract the most important facts about a topic from search results. “

            “Use after search_topic to identify the 5-7 most significant points.”

        ),

        “input_schema”: {

            “type”: “object”,

            “properties”: {

                “topic”: {

                    “type”: “string”,

                    “description”: “The topic to extract facts about”

                },

                “focus”: {

                    “type”: “string”,

                    “description”: “Optional: specific angle to focus on (e.g., ‘recent developments’, ‘key players’)”

                }

            },

            “required”: [“topic”]

        }

    },

    {

        “name”: “format_summary”,

        “description”: (

            “Format research findings into a clean structured summary. “

            “Always call this as the final step before returning to the user.”

        ),

        “input_schema”: {

            “type”: “object”,

            “properties”: {

                “title”: {

                    “type”: “string”,

                    “description”: “Title for the summary”

                },

                “key_points”: {

                    “type”: “array”,

                    “items”: {“type”: “string”},

                    “description”: “List of key findings (5-7 items)”

                },

                “conclusion”: {

                    “type”: “string”,

                    “description”: “A 2-3 sentence synthesis of the research”

                }

            },

            “required”: [“title”, “key_points”, “conclusion”]

        }

    }

]

 

 

# ── Tool implementations ──────────────────────────────────────────────────────

# @record_function decorates each tool so AgentOps captures:

# – The function name

# – Input arguments

# – Return value

# – Execution time

# – Any exceptions

# These appear as labeled spans in the session replay timeline.

 

@record_function(“search_topic”)

def search_topic(topic: str, depth: str = “overview”) -> dict:

    “”“

    Search for information about a topic.

    In production: replace this stub with a real search API call.

    ““”

    # Simulate search latency — remove in production

    time.sleep(0.3)

 

    # Stub response — replace with: tavily_client.search(query=topic)

    return {

        “topic”: topic,

        “depth”: depth,

        “results”: f“Comprehensive overview of {topic}: This is a rapidly evolving field “

                   f“with significant developments in 2025-2026. Key themes include “

                   f“technical innovation, adoption patterns, and organizational impact. “

                   f“Multiple research groups and companies are actively advancing the field.”,

        “source_count”: 12,

        “timestamp”: “2026-05-26”

    }

 

 

@record_function(“get_key_facts”)

def get_key_facts(topic: str, focus: str = None) -> dict:

    “”“

    Extract key facts about a topic.

    In production: this would process real search results.

    ““”

    time.sleep(0.2)

 

    focus_note = f” (focus: {focus})” if focus else “”

    return {

        “topic”: topic,

        “focus”: focus_note,

        “facts”: [

            f“{topic} has seen 42% year-over-year growth in adoption”,

            f“Leading organizations report 3-5x productivity improvements”,

            f“Key technical challenges include reliability, cost, and governance”,

            f“The market is projected to reach $4.9B by 2028”,

            f“Open-source tooling has matured significantly in the past 18 months”,

        ],

        “confidence”: “high”

    }

 

 

@record_function(“format_summary”)

def format_summary(title: str, key_points: list, conclusion: str) -> dict:

    “”“

    Format research into a structured summary.

    This is always the final step in the research workflow.

    ““”

    return {

        “title”: title,

        “key_points”: key_points,

        “conclusion”: conclusion,

        “format”: “structured_summary”,

        “generated_at”: “2026-05-26”

    }

 

 

def execute_tool(tool_name: str, tool_input: dict) -> str:

    “”“

    Route tool calls to the correct implementation.

    Returns the result as a JSON string for the model to read.

    ““”

    if tool_name == “search_topic”:

        result = search_topic(**tool_input)

    elif tool_name == “get_key_facts”:

        result = get_key_facts(**tool_input)

    elif tool_name == “format_summary”:

        result = format_summary(**tool_input)

    else:

        result = {“error”: f“Unknown tool: {tool_name}”}

 

    return json.dumps(result)

 

 

# ── The agent loop ─────────────────────────────────────────────────────────────

def run_research_agent(topic: str) -> dict:

    “”“

    Run the research agent on a given topic.

 

    The loop:

    1. Send the goal to Claude with the available tools

    2. If Claude wants to call a tool, execute it and return the result

    3. Continue until Claude signals it is done (stop_reason == ‘end_turn’)

    4. Return the final structured summary

 

    AgentOps captures every iteration automatically because:

    – The LLM client is wrapped after agentops.init()

    – Each tool is decorated with @record_function

    – The session spans the full lifecycle from init to end_session()

    ““”

    print(f“\nStarting research agent for topic: ‘{topic}'”)

    print(“Session will be visible at https://app.agentops.ai\n”)

 

    messages = [

        {“role”: “user”, “content”: f“Research this topic and produce a structured summary: {topic}”}

    ]

 

    final_summary = None

    iteration = 0

    max_iterations = 10  # Safety limit — prevents runaway loops

 

    while iteration < max_iterations:

        iteration += 1

        print(f“Iteration {iteration}: Calling Claude…”)

 

        response = client.messages.create(

            model=MODEL,

            max_tokens=4096,

            system=SYSTEM_PROMPT,

            tools=TOOLS,

            messages=messages

        )

 

        print(f”  stop_reason: {response.stop_reason}”)

 

        # Add assistant response to message history

        messages.append({“role”: “assistant”, “content”: response.content})

 

        # If Claude is done, extract the final summary and exit

        if response.stop_reason == “end_turn”:

            # Look for the format_summary result in the message history

            for msg in reversed(messages):

                if msg[“role”] == “user” and isinstance(msg[“content”], list):

                    for block in msg[“content”]:

                        if (hasattr(block, “type”) and block.type == “tool_result”):

                            try:

                                result_data = json.loads(block.content[0].text)

                                if result_data.get(“format”) == “structured_summary”:

                                    final_summary = result_data

                                    break

                            except (json.JSONDecodeError, (AttributeError, KeyError, IndexError, TypeError)):

                                pass

                if final_summary:

                    break

            break

 

        # Process tool calls if Claude wants to use tools

        if response.stop_reason == “tool_use”:

            tool_results = []

 

            for block in response.content:

                if block.type == “tool_use”:

                    print(f”  Tool call: {block.name}({json.dumps(block.input, indent=2)})”)

                    result = execute_tool(block.name, block.input)

                    print(f”  Result: {result[:100]}…”)

 

                    tool_results.append({

                        “type”: “tool_result”,

                        “tool_use_id”: block.id,

                        “content”: result

                    })

 

            # Return tool results to Claude

            messages.append({“role”: “user”, “content”: tool_results})

 

    if iteration >= max_iterations:

        print(f“WARNING: Agent hit max iterations ({max_iterations}). Possible loop detected.”)

        # AgentOps will show this as a session ending in Fail

        agentops.end_session(“Fail”)

        return {“error”: “Max iterations reached — check session replay for loop analysis”}

 

    # End session with Success — this finalizes the session in AgentOps

    # The session replay is now available at app.agentops.ai

    agentops.end_session(“Success”)

 

    return final_summary or {“message”: “Research complete — check session replay for full trace”}

 

 

# ── Run the agent ─────────────────────────────────────────────────────────────

if __name__ == “__main__”:

    topic = “AgentOps and AI agent observability in 2026”

 

    try:

        result = run_research_agent(topic)

 

        print(“\n” + “=” * 60)

        print(“RESEARCH SUMMARY”)

        print(“=” * 60)

 

        if “error” in result:

            print(f“Error: {result[‘error’]}”)

        else:

            print(f“Title: {result.get(‘title’, ‘N/A’)}”)

            print(“\nKey Points:”)

            for i, point in enumerate(result.get(“key_points”, []), 1):

                print(f”  {i}. {point}”)

            print(f“\nConclusion: {result.get(‘conclusion’, ‘N/A’)}”)

 

        print(“\n” + “=” * 60)

        print(“Session replay available at: https://app.agentops.ai”)

        print(“Look for your session tagged ‘research-agent'”)

        print(“=” * 60)

 

    except KeyboardInterrupt:

        # Clean session end if the user interrupts

        agentops.end_session(“Fail”)

        print(“\nSession ended by user. Partial trace saved to AgentOps.”)

 

    except Exception as e:

        # Record failures so they show up in the dashboard

        agentops.end_session(“Fail”)

        print(f“Agent failed: {e}”)

        raise



Source_link

READ ALSO

Sakana AI Releases Fugu-Cyber: An Orchestration Model Reporting 86.9% on CyberGym and 72.1% on CTI-REALM

Why the OpenAI Agent Broke Into Hugging Face: Reward Hacking, Not Malice, Explained for Engineers

Related Posts

Sakana AI Releases Fugu-Cyber: An Orchestration Model Reporting 86.9% on CyberGym and 72.1% on CTI-REALM
Al, Analytics and Automation

Sakana AI Releases Fugu-Cyber: An Orchestration Model Reporting 86.9% on CyberGym and 72.1% on CTI-REALM

July 26, 2026
Al, Analytics and Automation

Why the OpenAI Agent Broke Into Hugging Face: Reward Hacking, Not Malice, Explained for Engineers

July 25, 2026
Datalab’s Marker 2 vs MinerU, Docling and LiteParse: 76.0 on olmOCR-bench at 5× MinerU’s Throughput
Al, Analytics and Automation

Datalab’s Marker 2 vs MinerU, Docling and LiteParse: 76.0 on olmOCR-bench at 5× MinerU’s Throughput

July 25, 2026
Working to automate nuclear plant operations | MIT News
Al, Analytics and Automation

Working to automate nuclear plant operations | MIT News

July 24, 2026
How to Build an End-to-End OCR Pipeline with Baidu’s Unlimited-OCR for High-Resolution Images and Multi-Page PDF Parsing
Al, Analytics and Automation

How to Build an End-to-End OCR Pipeline with Baidu’s Unlimited-OCR for High-Resolution Images and Multi-Page PDF Parsing

July 24, 2026
MIT projects selected for funding under US Department of Energy’s Genesis Mission | MIT News
Al, Analytics and Automation

MIT projects selected for funding under US Department of Energy’s Genesis Mission | MIT News

July 23, 2026
Next Post
ISO 27001: The Security Standard Every Business Needs Right Now

ISO 27001: The Security Standard Every Business Needs Right Now

POPULAR NEWS

Trump ends trade talks with Canada over a digital services tax

Trump ends trade talks with Canada over a digital services tax

June 28, 2025
15 Trending Songs on TikTok in 2025 (+ How to Use Them)

15 Trending Songs on TikTok in 2025 (+ How to Use Them)

June 18, 2025
Communication Effectiveness Skills For Business Leaders

Communication Effectiveness Skills For Business Leaders

June 10, 2025
App Development Cost in Singapore: Pricing Breakdown & Insights

App Development Cost in Singapore: Pricing Breakdown & Insights

June 22, 2025
Comparing the Top 7 Large Language Models LLMs/Systems for Coding in 2025

Comparing the Top 7 Large Language Models LLMs/Systems for Coding in 2025

November 4, 2025

EDITOR'S PICK

How to decide which AI search prompts to track

How to decide which AI search prompts to track

June 10, 2026
AI is transforming medicine. Could it bring doctors and patients together?

AI is transforming medicine. Could it bring doctors and patients together?

October 28, 2025
A Checklist for Your Team

A Checklist for Your Team

September 11, 2025
Kash Patel’s clothing brand website shut down after reports it was hacked

Kash Patel’s clothing brand website shut down after reports it was hacked

May 22, 2026

About

We bring you the best Premium WordPress Themes that perfect for news, magazine, personal blog, etc. Check our landing page for details.

Follow us

Categories

  • Account Based Marketing
  • Ad Management
  • Al, Analytics and Automation
  • Brand Management
  • Channel Marketing
  • Digital Marketing
  • Direct Marketing
  • Event Management
  • Google Marketing
  • Marketing Attribution and Consulting
  • Marketing Automation
  • Mobile Marketing
  • PR Solutions
  • Social Media Management
  • Technology And Software
  • Uncategorized

Recent Posts

  • Monday.com is the latest tech company to blame AI for layoffs — here are 20 others
  • How to Compete With Big Companies in 2026
  • Google launches Alliance for America’s Skilled Trades
  • GeoGuessr Daily Challenge Answer Today for July 25, 2026
  • About Us
  • Disclaimer
  • Contact Us
  • Privacy Policy
No Result
View All Result
  • Technology And Software
    • Account Based Marketing
    • Channel Marketing
    • Marketing Automation
      • Al, Analytics and Automation
      • Ad Management
  • Digital Marketing
    • Social Media Management
    • Google Marketing
  • Direct Marketing
    • Brand Management
    • Marketing Attribution and Consulting
  • Mobile Marketing
  • Event Management
  • PR Solutions