{"id":15664,"date":"2025-07-27T09:42:46","date_gmt":"2025-07-27T09:42:46","guid":{"rendered":"https:\/\/dmsretail.com\/RetailNews\/creating-a-netai-playground-for-agentic-ai-experimentation\/"},"modified":"2025-07-27T09:42:46","modified_gmt":"2025-07-27T09:42:46","slug":"creating-a-netai-playground-for-agentic-ai-experimentation","status":"publish","type":"post","link":"https:\/\/dmsretail.com\/RetailNews\/creating-a-netai-playground-for-agentic-ai-experimentation\/","title":{"rendered":"Creating a NetAI Playground for Agentic AI Experimentation"},"content":{"rendered":"<p> <p><a href=\"https:\/\/dmsretail.com\/online-workshops-list\/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-496\" src=\"https:\/\/dmsretail.com\/RetailNews\/wp-content\/uploads\/2022\/05\/RETAIL-ONLINE-TRAINING-728-X-90.png\" alt=\"Retail Online Training\" width=\"729\" height=\"91\" srcset=\"https:\/\/dmsretail.com\/RetailNews\/wp-content\/uploads\/2022\/05\/RETAIL-ONLINE-TRAINING-728-X-90.png 729w, https:\/\/dmsretail.com\/RetailNews\/wp-content\/uploads\/2022\/05\/RETAIL-ONLINE-TRAINING-728-X-90-300x37.png 300w\" sizes=\"auto, (max-width: 729px) 100vw, 729px\" \/><\/a><\/p><br \/>\n<\/p>\n<div>\n<p>Hey there, everyone, and welcome to the latest installment of \u201cHank shares his AI journey.\u201d \ud83d\ude42 Artificial Intelligence (AI) continues to be all the rage, and coming back from Cisco Live in San Diego, I was excited to dive into the world of agentic AI.<\/p>\n<p>With announcements like Cisco\u2019s\u00a0<span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\"><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">own agentic AI solution,\u00a0AI Canvas, as well as discussions with partners and other engineers about this next phase of AI possibilities, my curiosity was piqued<\/span>:\u00a0<em>What does this all mean for us<\/em><\/span><em>\u00a0network engineers? Moreover, how can we start to experiment and learn about agentic AI?<\/em><\/p>\n<p>I began my exploration of the topic of agentic AI, reading and watching a wide range of content to gain a deeper understanding of the subject. I won\u2019t delve into a detailed definition in this blog, but here are the basics of how I think about it:<\/p>\n<p style=\"padding-left: 40px;\"><strong>Agentic AI is a vision for a world where AI doesn\u2019t just answer questions we ask, but it begins to work more independently.<\/strong> Driven by the goals we set, and utilizing access to tools and systems we provide, an agentic AI solution can monitor the current state of the network and take actions to ensure our network operates exactly as intended.<\/p>\n<p>Sounds pretty darn futuristic, right?\u00a0Let\u2019s dive into the technical aspects of how it works\u2014roll up your sleeves, get into the lab, and let\u2019s learn some new things.<\/p>\n<h2><strong>What are AI \u201ctools?\u201d<\/strong><\/h2>\n<p>The first thing I wanted to explore and better understand was the concept of \u201ctools\u201d within this agentic framework. As you may recall, the LLM (large language model) that powers AI systems is essentially an algorithm trained on vast amounts of data. An LLM can \u201cunderstand\u201d your questions and instructions. On its <em>own<\/em>, however, the LLM is limited to the data it was trained on. It can\u2019t even search the web for current movie showtimes without some \u201ctool\u201d allowing it to perform a web search.<\/p>\n<p>From the very early days of the GenAI buzz, developers have been building and adding \u201ctools\u201d into AI applications. Initially, the creation of these tools was ad hoc and varied depending on the developer, LLM, programming language, and the tool\u2019s goal.\u00a0 But recently, a new framework for building AI tools has gotten a lot of excitement and is starting to become a new \u201cstandard\u201d for tool development.<\/p>\n<p>This framework is known as the Model Context Protocol (MCP). Originally developed by Anthropic, the company behind Claude, any developer to use MCP to build tools, called \u201cMCP Servers,\u201d and any AI platform can act as an \u201cMCP Client\u201d to use these tools. It\u2019s essential to remember that we are still in the very early days of AI and AgenticAI; however, currently, MCP appears to be <span style=\"text-decoration: underline;\">the<\/span> approach for tool building. So I figured I\u2019d dig in and figure out how MCP works by building my own very basic <em>NetAI Agent<\/em>.<\/p>\n<p>I\u2019m far from the first networking engineer to want to dive into this space, so I started by reading a couple of very helpful blog posts by my buddy Kareem Iskander, Head of Technical Advocacy in Learn with Cisco.<\/p>\n<p>These gave me a jumpstart on the key topics, and Kareem was helpful enough to provide some example code for creating an MCP server. I was ready to explore more on my own.<\/p>\n<h2><strong>Creating a local NetAI playground lab<\/strong><\/h2>\n<p>There is no shortage of AI tools and platforms today. There is ChatGPT, Claude, Mistral, Gemini, and so many more. Indeed, I utilize many of them regularly for various AI tasks. However, for experimenting with agentic AI and AI tools, I wanted something that was 100% local and didn\u2019t rely on a cloud-connected service.<\/p>\n<p>A primary reason for this desire was that I wanted to ensure all of my AI interactions remained entirely on my computer and within my network. I knew I would be experimenting in an entirely new area of development. I was also going to send data about \u201cmy network\u201d to the LLM for processing. And while I\u2019ll be using non-production lab systems for all the testing, I still didn\u2019t like the idea of leveraging cloud-based AI systems. I would feel freer to learn and make mistakes if I knew the risk was low. Yes, <em>low<\/em>\u2026 Nothing is completely risk-free.<\/p>\n<p>Luckily, this wasn\u2019t the first time I considered local LLM work, and I had a couple of possible options ready to go. The first is Ollama, a powerful open-source engine for running LLMs locally, or at least on your own server.\u00a0 The second is LMStudio, and while not itself open source, it has an open source foundation, and it is free to use for both personal and \u201cat work\u201d experimentation with AI models. When I read a recent blog by LMStudio about MCP support now being included, I decided to give it a try for my experimentation.<\/p>\n<figure id=\"attachment_475934\" aria-describedby=\"caption-attachment-475934\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden wp-image-475934 size-full\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-01.jpg\" alt=\"Creating Mr Packets with LMStudio\" width=\"800\" height=\"642\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-475934 size-full\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-01.jpg\" alt=\"Creating Mr Packets with LMStudio\" width=\"800\" height=\"642\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-01-300x241.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-01-768x616.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-01.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><figcaption id=\"caption-attachment-475934\" class=\"wp-caption-text\">Creating Mr Packets with LMStudio<\/figcaption><\/figure>\n<p style=\"padding-left: 40px;\"><em>LMStudio is a client for running LLMs, but it isn\u2019t an LLM itself.\u00a0 It provides access to a large number of LLMs available for download and running. With so many LLM options available, it can be overwhelming when you get started. The key things for this blog post and demonstration are that you need a model that has been trained for \u201ctool use.\u201d Not all models are. And furthermore, not all \u201ctool-using\u201d models actually work with tools. For this demonstration, I\u2019m using the google\/gemma-2-9b model. It\u2019s an \u201copen model\u201d built using the same research and tooling behind Gemini.<\/em><\/p>\n<p>The next thing I needed for my experimentation was an initial idea for a tool to build. After some thought, I decided a good \u201chello world\u201d for my new NetAI project would be a way for AI to send and process \u201cshow commands\u201d from a network device. I chose pyATS to be my NetDevOps library of choice for this project. In addition to being a library that I\u2019m very familiar with, it has the benefit of automatic output processing into JSON through the library of parsers included in pyATS. I could also, within just a couple of minutes, generate a basic Python function to send a show command to a network device and return the output as a starting point.<\/p>\n<p>Here\u2019s that code:<\/p>\n<pre>def send_show_command(&#13;\n    command: str,&#13;\n    device_name: str,&#13;\n    username: str,&#13;\n    password: str,&#13;\n    ip_address: str,&#13;\n    ssh_port: int = 22,&#13;\n    network_os: Optional[str] = \"ios\",&#13;\n) -&gt; Optional[Dict[str, Any]]:&#13;\n&#13;\n    # Structure a dictionary for the device configuration that can be loaded by PyATS&#13;\n    device_dict = {&#13;\n        \"devices\": {&#13;\n            device_name: {&#13;\n                \"os\": network_os,&#13;\n                \"credentials\": {&#13;\n                    \"default\": {\"username\": username, \"password\": password}&#13;\n                },&#13;\n                \"connections\": {&#13;\n                    \"ssh\": {\"protocol\": \"ssh\", \"ip\": ip_address, \"port\": ssh_port}&#13;\n                },&#13;\n            }&#13;\n        }&#13;\n    }&#13;\n    testbed = load(device_dict)&#13;\n    device = testbed.devices[device_name]&#13;\n&#13;\n    device.connect()&#13;\n    output = device.parse(command)&#13;\n    device.disconnect()&#13;\n&#13;\n    return output&#13;\n<\/pre>\n<p>Between Kareem\u2019s blog posts and the getting-started guide for FastMCP 2.0, I learned it was <em>frighteningly easy<\/em> to convert my function into an MCP Server\/Tool. I just needed to add five lines of code.<\/p>\n<pre>from fastmcp import FastMCP&#13;\n&#13;\nmcp = FastMCP(\"NetAI Hello World\")&#13;\n&#13;\n@mcp.tool()&#13;\ndef send_show_command()&#13;\n    .&#13;\n    .&#13;\n&#13;\n&#13;\nif __name__ == \"__main__\":&#13;\n    mcp.run()&#13;\n<\/pre>\n<p>Well.. it was ALMOST that easy. I <em>did <\/em>have to make a few adjustments to the above basics to get it to run successfully. You can see the full working copy of the code\u00a0in my newly created NetAI-Learning project on GitHub.<\/p>\n<p>As for those few adjustments, the changes I made were:<\/p>\n<ul>\n<li>A nice, detailed docstring for the function behind the tool. MCP clients use the details from the docstring to understand how and why to use the tool.<\/li>\n<li>After some experimentation, I opted to use \u201chttp\u201d transport for the MCP server rather than the default and more common \u201cSTDIO.\u201d The reason I went this way was to prepare for the next phase of my experimentation, when my pyATS MCP server would likely run within the network lab environment itself, rather than on my laptop. STDIO requires the MCP Client and Server to run on the same host system.<\/li>\n<\/ul>\n<p>So I fired up the MCP Server, hoping that there wouldn\u2019t be any errors. (Okay, to be honest, it took <em>a couple of iterations<\/em> in development to get it working without errors\u2026 but I\u2019m doing this blog post \u201ccooking show style,\u201d where the boring work along the way is hidden. \ud83d\ude09<\/p>\n<pre>python netai-mcp-hello-world.py &#13;\n&#13;\n\u256d\u2500 FastMCP 2.0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e&#13;\n\u2502                                                                            \u2502&#13;\n\u2502        _ __ ___ ______           __  __  _____________    ____    ____     \u2502&#13;\n\u2502       _ __ ___ \/ ____\/___ ______\/ \/_\/  |\/  \/ ____\/ __   |___   \/ __     \u2502&#13;\n\u2502      _ __ ___ \/ \/_  \/ __ `\/ ___\/ __\/ \/|_\/ \/ \/   \/ \/_\/ \/  ___\/ \/ \/ \/ \/ \/    \u2502&#13;\n\u2502     _ __ ___ \/ __\/ \/ \/_\/ (__  ) \/_\/ \/  \/ \/ \/___\/ ____\/  \/  __\/_\/ \/_\/ \/     \u2502&#13;\n\u2502    _ __ ___ \/_\/    __,_\/____\/__\/_\/  \/_\/____\/_\/      \/_____(_)____\/      \u2502&#13;\n\u2502                                                                            \u2502&#13;\n\u2502                                                                            \u2502&#13;\n\u2502                                                                            \u2502&#13;\n\u2502    \ud83d\udda5\ufe0f  Server name:     FastMCP                                             \u2502&#13;\n\u2502    \ud83d\udce6 Transport:       Streamable-HTTP                                     \u2502&#13;\n\u2502    \ud83d\udd17 Server URL:      http:\/\/127.0.0.1:8002\/mcp\/                          \u2502&#13;\n\u2502                                                                            \u2502&#13;\n\u2502    \ud83d\udcda Docs:            https:\/\/gofastmcp.com                               \u2502&#13;\n\u2502    \ud83d\ude80 Deploy:          https:\/\/fastmcp.cloud                               \u2502&#13;\n\u2502                                                                            \u2502&#13;\n\u2502    \ud83c\udfce\ufe0f  FastMCP version: 2.10.5                                              \u2502&#13;\n\u2502    \ud83e\udd1d MCP version:     1.11.0                                              \u2502&#13;\n\u2502                                                                            \u2502&#13;\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f&#13;\n&#13;\n&#13;\n[07\/18\/25 14:03:53] INFO     Starting MCP server 'FastMCP' with transport 'http' on http:\/\/127.0.0.1:8002\/mcp\/server.py:1448&#13;\nINFO:     Started server process [63417]&#13;\nINFO:     Waiting for application startup.&#13;\nINFO:     Application startup complete.&#13;\nINFO:     Uvicorn running on http:\/\/127.0.0.1:8002 (Press CTRL+C to quit)&#13;\n<\/pre>\n<p>The next step was to configure LMStudio to act as the MCP Client and connect to the server to have access to the new \u201csend_show_command\u201d tool. While not \u201cstandardized, \u201cmost MCP Clients use a very common JSON configuration to define the servers. LMStudio is one of these clients.<\/p>\n<figure id=\"attachment_475935\" aria-describedby=\"caption-attachment-475935\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden wp-image-475935 size-full\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-02-mcpconfig.jpg\" alt=\"Adding the pyATS MCP server to LMStudio\" width=\"800\" height=\"498\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-475935 size-full\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-02-mcpconfig.jpg\" alt=\"Adding the pyATS MCP server to LMStudio\" width=\"800\" height=\"498\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-02-mcpconfig-300x187.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-02-mcpconfig-768x478.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-02-mcpconfig.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><figcaption id=\"caption-attachment-475935\" class=\"wp-caption-text\">Adding the pyATS MCP server to LMStudio<\/figcaption><\/figure>\n<p>Wait\u2026 if you\u2019re wondering, \u2018W<em>here\u2019s the network, Hank? What device are you sending the \u2018show commands\u2019 to?\u2019 <\/em>No worries, my inquisitive friend: I created a very simple Cisco Modeling Labs (CML) topology with a couple of IOL devices configured for direct SSH access using the PATty feature.<\/p>\n<figure id=\"attachment_475936\" aria-describedby=\"caption-attachment-475936\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden wp-image-475936 size-full\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-cml-01.jpg\" alt=\"NetAI Hello World CML Network\" width=\"800\" height=\"458\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-475936 size-full\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-cml-01.jpg\" alt=\"NetAI Hello World CML Network\" width=\"800\" height=\"458\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-cml-01-300x172.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-cml-01-768x440.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-cml-01.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><figcaption id=\"caption-attachment-475936\" class=\"wp-caption-text\">NetAI Hello World CML Network<\/figcaption><\/figure>\n<h2><strong>Let\u2019s see it in action!<\/strong><\/h2>\n<p>Okay, I\u2019m sure you are ready to see it in action.\u00a0 I know I sure was as I was building it.\u00a0 So let\u2019s do it!<\/p>\n<p>To start, I instructed the LLM on how to connect to my network devices in the initial message.<\/p>\n<figure id=\"attachment_475939\" aria-describedby=\"caption-attachment-475939\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden size-full wp-image-475939\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-03.jpg\" alt=\"Telling the LLM about my devices\" width=\"800\" height=\"498\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-475939\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-03.jpg\" alt=\"Telling the LLM about my devices\" width=\"800\" height=\"498\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-03-300x187.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-03-768x478.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-03.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><figcaption id=\"caption-attachment-475939\" class=\"wp-caption-text\">Telling the LLM about my devices<\/figcaption><\/figure>\n<p>I did this because the pyATS tool needs the address and credential information for the devices.\u00a0 In the future I\u2019d like to look at the MCP servers for different source of truth options like NetBox and Vault so it can \u201clook them up\u201d as needed.\u00a0 But for now, we\u2019ll start simple.<\/p>\n<p>First question: Let\u2019s ask about software version info.<\/p>\n<p><img decoding=\"async\" class=\"lazy lazy-hidden aligncenter size-full wp-image-475943\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-question-01.gif\" alt=\"Short video of the asking the LLM what version of software is running.\" width=\"800\"\/><noscript><img decoding=\"async\" class=\"aligncenter size-full wp-image-475943\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-question-01.gif\" alt=\"Short video of the asking the LLM what version of software is running.\" width=\"800\"\/><\/noscript><\/p>\n<p>You can see the details of the tool call by diving into the input\/output screen.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden aligncenter size-full wp-image-475946\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-04-command-details.jpg\" alt=\"Tool inputs and outputs\" width=\"800\" height=\"438\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-475946\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-04-command-details.jpg\" alt=\"Tool inputs and outputs\" width=\"800\" height=\"438\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-04-command-details-300x164.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-04-command-details-768x420.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-04-command-details.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><\/p>\n<p>This is pretty cool, but what exactly is happening here? Let\u2019s walk through the steps involved.<\/p>\n<ol>\n<li>The LLM client starts and queries the configured MCP servers to discover the tools available.<\/li>\n<li>I send a \u201cprompt\u201d to the LLM to consider.<\/li>\n<li>The LLM processes my prompts. It \u201cconsiders\u201d the different tools available and if they might be relevant as part of building a response to the prompt.<\/li>\n<li>The LLM determines that the \u201csend_show_command\u201d tool is relevant to the prompt and builds a proper payload to call the tool.<\/li>\n<li>The LLM invokes the tool with the proper arguments from the prompt.<\/li>\n<li>The MCP server processes the called request from the LLM and returns the result.<\/li>\n<li>The LLM takes the returned results, along with the original prompt\/question as the new input to use to generate the response.<\/li>\n<li>The LLM generates and returns a response to the query.<\/li>\n<\/ol>\n<p>This isn\u2019t all that different from what you might do if you were asked the same question.<\/p>\n<ol>\n<li>You would consider the question, \u201cWhat software version is router01 running?\u201d<\/li>\n<li>You\u2019d think about the different ways you could get the information needed to answer the question. Your \u201ctools,\u201d so to speak.<\/li>\n<li>You\u2019d decide on a tool and use it to gather the information you needed. Probably SSH to the router and run \u201cshow version.\u201d<\/li>\n<li>You\u2019d review the returned output from the command.<\/li>\n<li>You\u2019d then reply to whoever asked you the question with the proper answer.<\/li>\n<\/ol>\n<p>Hopefully, this helps demystify a little about how these \u201cAI Agents\u201d work under the hood.<\/p>\n<p>How about one more example? Perhaps something a bit more complex than simply \u201cshow version.\u201d Let\u2019s see if the NetAI agent can help identify which switch port the host is connected to by describing the basic process involved.<\/p>\n<p>Here\u2019s the question\u2014sorry, <em>prompt<\/em>, that I submit to the LLM:<\/p>\n<figure id=\"attachment_475950\" aria-describedby=\"caption-attachment-475950\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden wp-image-475950 size-full\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-05-prompt.jpg\" alt=\"Prompt asking a multi-step question of the LLM.\" width=\"800\" height=\"262\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-475950 size-full\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-05-prompt.jpg\" alt=\"Prompt asking a multi-step question of the LLM.\" width=\"800\" height=\"262\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-05-prompt-300x98.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-05-prompt-768x252.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-05-prompt.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><figcaption id=\"caption-attachment-475950\" class=\"wp-caption-text\">Prompt asking a multi-step question of the LLM.<\/figcaption><\/figure>\n<p>What we should notice about this prompt is that it will require the LLM to send and process show commands from two different network devices. Just like with the first example, I do NOT tell the LLM which command to run. I only ask for the information I need. There isn\u2019t a \u201ctool\u201d that knows the IOS commands. That knowledge is part of the LLM\u2019s training data.<\/p>\n<p>Let\u2019s see how it does with this prompt:<\/p>\n<figure id=\"attachment_475951\" aria-describedby=\"caption-attachment-475951\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"lazy lazy-hidden wp-image-475951 size-full\" data-lazy-type=\"image\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-06-response.jpg\" alt=\"The multi-step LLM response.\" width=\"800\" height=\"734\" srcset=\"\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><noscript><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-475951 size-full\" src=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-06-response.jpg\" alt=\"The multi-step LLM response.\" width=\"800\" height=\"734\" srcset=\"https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-06-response-300x275.jpg 300w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-06-response-768x705.jpg 768w, https:\/\/storage.googleapis.com\/blogs-images-new\/ciscoblogs\/1\/2025\/07\/netai-lmstudio-06-response.jpg 800w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\"\/><\/noscript><figcaption id=\"caption-attachment-475951\" class=\"wp-caption-text\">The LLM successfully executes the multi-step plan.<\/figcaption><\/figure>\n<p>And look at that, it was able to handle the multi-step procedure to answer my question.\u00a0 The LLM even explained what commands it was going to run, and how it was going to use the output.\u00a0 And if you scroll back up to the CML network diagram, you\u2019ll see that it correctly identifies interface Ethernet0\/2 as the switch port to which the host was connected.<\/p>\n<h2><strong><em>So what\u2019s next, Hank?<\/em><\/strong><\/h2>\n<p>Hopefully, you found this exploration of agentic AI tool creation and experimentation as interesting as I have. And maybe you\u2019re starting to see the possibilities for your own daily use. If you\u2019d like to try some of this out on your own, you can find everything you need on my netai-learning GitHub project.<\/p>\n<ol>\n<li>The mcp-pyats code for the MCP Server. You\u2019ll find both the simple \u201chello world\u201d example and a more developed work-in-progress tool that I\u2019m adding additional features to. Feel free to use either.<\/li>\n<li>The CML topology I used for this blog post. Though any network that is SSH reachable will work.<\/li>\n<li>The mcp-server-config.json file that you can reference for configuring LMStudio<\/li>\n<li>A \u201cSystem Prompt Library\u201d where I\u2019ve included the System Prompts for both a basic \u201cMr. Packets\u201d network assistant and the agentic AI tool. These aren\u2019t required for experimenting with NetAI use cases, but System Prompts can be useful to ensure the results you\u2019re after with LLM.<\/li>\n<\/ol>\n<h4><strong>A couple of \u201cgotchas\u201d I wanted to share that I encountered during this learning process, which I hope might save you some time:<\/strong><\/h4>\n<p>First, not all LLMs that claim to be \u201ctrained for tool use\u201d will work with MCP servers and tools. Or at least the ones I\u2019ve been building and testing. Specifically, I struggled with Llama 3.1 and Phi 4. Both seemed to indicate they were \u201ctool users,\u201d but they failed to call my tools. At first, I thought this was due to my code, but once I switched to Gemma 2, they worked immediately. (I also tested with Qwen3 and had good results.)<\/p>\n<p>Second, once you add the MCP Server to LMStudio\u2019s \u201cmcp.json\u201d configuration file, LMStudio initiates a connection and maintains an active session. This means that if you stop and restart the MCP server code, the session is broken, giving you an error in LMStudio on your next prompt submission. To fix this issue, you\u2019ll need to either close and restart LMStudio or edit the \u201cmcp.json\u201d file to delete the server, save it, and then re-add it. (There is a bug filed with LMStudio on this problem. Hopefully, they\u2019ll fix it in an upcoming release, but for now, it does make development a bit annoying.)<\/p>\n<p>As for me, I\u2019ll continue exploring the concept of NetAI and how AI agents and tools can make our lives as network engineers more productive. I\u2019ll be back here with my next blog once I have something new and interesting to share.<\/p>\n<p>In the meantime, how are you experimenting with agentic AI? Are you excited about the potential? Any suggestions for an LLM that works well with network engineering knowledge? Let me know in the comments below. Talk to you all soon!<\/p>\n<p style=\"text-align: center;\" data-ttstextid=\"27\">Sign up for\u00a0Cisco U.\u00a0| Join the\u202f\u00a0Cisco Learning Network\u202ftoday for free.<\/p>\n<blockquote data-ttstextid=\"28\">\n<h2 style=\"text-align: center;\" data-ttstextid=\"29\"><strong>Learn with Cisco<\/strong><\/h2>\n<h3 style=\"text-align: center;\" data-ttstextid=\"30\"><strong><a href=\"https:\/\/twitter.com\/LearningatCisco\" target=\"_blank\" rel=\"noopener\">X<\/a>\u202f|\u202fThreads\u00a0|\u00a0Facebook\u202f|\u202fLinkedIn\u202f|\u202fInstagram<\/strong><strong>\u202f|\u202fYouTube<\/strong><\/h3>\n<\/blockquote>\n<p style=\"text-align: center;\" data-ttstextid=\"31\">Use\u202f\u00a0<strong>#CiscoU\u00a0<\/strong>and\u00a0<strong>#CiscoCert<\/strong>\u202fto join the conversation.<\/p>\n<p>Share:<\/p>\n<p>\n  \t<\/div>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><script async defer src=\"https:\/\/platform.instagram.com\/en_US\/embeds.js\"><\/script><br \/>\n<br \/><p><a href=\"https:\/\/dmsretail.com\/online-workshops-list\/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-496\" src=\"https:\/\/dmsretail.com\/RetailNews\/wp-content\/uploads\/2022\/05\/RETAIL-ONLINE-TRAINING-728-X-90.png\" alt=\"Retail Online Training\" width=\"729\" height=\"91\" srcset=\"https:\/\/dmsretail.com\/RetailNews\/wp-content\/uploads\/2022\/05\/RETAIL-ONLINE-TRAINING-728-X-90.png 729w, https:\/\/dmsretail.com\/RetailNews\/wp-content\/uploads\/2022\/05\/RETAIL-ONLINE-TRAINING-728-X-90-300x37.png 300w\" sizes=\"auto, (max-width: 729px) 100vw, 729px\" \/><\/a><\/p><br \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey there, everyone, and welcome to the latest installment of \u201cHank shares his AI journey.\u201d \ud83d\ude42 Artificial Intelligence (AI) continues to be all the rage, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":15665,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-15664","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/posts\/15664","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/comments?post=15664"}],"version-history":[{"count":0,"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/posts\/15664\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/media\/15665"}],"wp:attachment":[{"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/media?parent=15664"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/categories?post=15664"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dmsretail.com\/RetailNews\/wp-json\/wp\/v2\/tags?post=15664"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}