{"id":12456,"date":"2025-12-12T15:10:39","date_gmt":"2025-12-12T06:10:39","guid":{"rendered":"https:\/\/sreake.com\/?p=12434"},"modified":"2026-02-10T16:14:52","modified_gmt":"2026-02-10T07:14:52","slug":"how-to-use-nvidia-nemo-agent-toolkit-2","status":"publish","type":"post","link":"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/","title":{"rendered":"Trying out NVIDIA NeMo Agent Toolkit"},"content":{"rendered":"\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_75 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Whats_NVIDIA_NeMo_Agent_Toolkit\" >What\u2019s NVIDIA NeMo Agent Toolkit?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#A_Sample_NAT_Workflow_Configuration\" >A Sample NAT Workflow Configuration<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#workflow\" >workflow<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#functions\" >functions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#embedders\" >embedders<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#retrievers\" >retrievers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#llms\" >llms<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#How_to_install_the_nat_CLI\" >How to install the nat CLI<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Installing_the_latest_version\" >Installing the latest version<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Installing_the_stable_version\" >Installing the stable version<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Running_the_nat_CLI\" >Running the nat CLI<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Creating_Custom_Functions\" >Creating Custom Functions<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Using_ADK_to_create_a_Google_Search_custom_function\" >Using ADK to create a Google Search custom function<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/sreake.com\/en\/blog\/how-to-use-nvidia-nemo-agent-toolkit-2\/#References\" >References<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Whats_NVIDIA_NeMo_Agent_Toolkit\"><\/span>What\u2019s NVIDIA NeMo Agent Toolkit?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>NVIDIA NeMo Agent Toolkit (let\u2019s call it NAT for short) is an open-source framework for creating AI agents and workflows, integrating various AI tools, frameworks and language models, and using observability libraries and profiling tools to evaluate agents.<\/p>\n\n\n\n<p>In this article, we\u2019re going to see what a sample NAT workflow configuration looks like, and run an agent using the <code>nat<\/code> CLI.<\/p>\n\n\n\n<p class=\"has-gray-100-background-color has-background\">\ud83d\udca1 NAT was formerly known as the NVIDIA Agent Intelligence Toolkit (or AI-Q Toolkit), which was renamed for better integration with the NVIDIA NeMo software suite.<br>If you\u2019re using the AI-Q Toolkit and wish to migrate to NAT, you can take a look at <a href=\"https:\/\/github.com\/NVIDIA\/NeMo-Agent-Toolkit\/blob\/develop\/docs\/source\/resources\/migration-guide.md\">the migration guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Sample_NAT_Workflow_Configuration\"><\/span>A Sample NAT Workflow Configuration<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>With NAT, you can specify your agent architecture by writing a YAML workflow configuration. Here\u2019s a sample configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>functions:\n  webpage_query:\n    _type: webpage_query\n    webpage_url: &lt;https:\/\/docs.smith.langchain.com&gt;\n    description: \"Search for information about LangSmith. For any questions about LangSmith, you must use this tool!\"\n    embedder_name: nv-embedqa-e5-v5\n    chunk_size: 512\n  current_datetime:\n    _type: current_datetime\n\nllms:\n  nim_llm:\n    _type: nim\n    model_name: meta\/llama-3.1-70b-instruct\n    temperature: 0.0\n\nembedders:\n  nv-embedqa-e5-v5:\n    _type: nim\n    model_name: nvidia\/nv-embedqa-e5-v5\n\nworkflow:\n  _type: react_agent\n  tool_names: &#91;webpage_query, current_datetime]\n  llm_name: nim_llm\n  verbose: true\n  parse_agent_response_max_retries: 3<\/code><\/pre>\n\n\n\n<p>Let\u2019s go through the configuration piece by piece.<\/p>\n\n\n\n<p><em>You can find more information in <a href=\"https:\/\/docs.nvidia.com\/nemo\/agent-toolkit\/1.2\/workflows\/workflow-configuration.html\">the NAT documentation<\/a>.<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"workflow\"><\/span>workflow<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>This contains the main workflow settings that will be passed to the <code>nat<\/code> CLI when running the agent:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>_type<\/code>: The workflow type.<\/li><li><code>tool_name<\/code>: The tools that the agent can use. We\u2019ll see how to define tools in the <code>functions<\/code> section.<\/li><li><code>llm_name<\/code>: The language model that the agent uses. We\u2019ll see how to define language models in the <code>llms<\/code> section<\/li><li><code>verbose<\/code>: Whether verbose logging is enabled.<\/li><li><code>parse_agent_response_max_retries<\/code>: The maximum amount of retries for the <a href=\"https:\/\/docs.nvidia.com\/nemo\/agent-toolkit\/1.1\/workflows\/about\/react-agent.html\">ReAct parsing framework<\/a>.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"functions\"><\/span>functions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>This contains the tools used in our workflow. Right now, we have a single <code>webpage_query<\/code> tool, written in Python for more flexibility.<\/p>\n\n\n\n<p>The tools defined here can be used in embedders and retrievers, which we will cover next.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"embedders\"><\/span>embedders<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>This provides a way to specify embedding models for our workflow. You can either use NVIDIA\u2019s own NIM, or any tool with support for embeddings.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"retrievers\"><\/span>retrievers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You can use retrievers to get external information for vector stores. Here too, you can either use NIM or any other retriever provider.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"llms\"><\/span>llms<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>This specifies what language models to use in our workflow. At the risk of sounding like a broken record, you can either use NIM or any other supported model.<\/p>\n\n\n\n<p>Here\u2019s a graph representation of the workflow architecture:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"760\" src=\"https:\/\/sreake.com\/wp-content\/uploads\/2025\/12\/image-1024x760.png\" alt=\"\" class=\"wp-image-12398\" srcset=\"https:\/\/sreake.com\/wp-content\/uploads\/2025\/12\/image-1024x760.png 1024w, https:\/\/sreake.com\/wp-content\/uploads\/2025\/12\/image-300x223.png 300w, https:\/\/sreake.com\/wp-content\/uploads\/2025\/12\/image-768x570.png 768w, https:\/\/sreake.com\/wp-content\/uploads\/2025\/12\/image.png 1406w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_to_install_the_nat_CLI\"><\/span>How to install the <code>nat<\/code> CLI<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You can run NAT agents using the <code>nat<\/code> CLI. Let\u2019s see how to install it.<\/p>\n\n\n\n<p><em>A word of warning: as NAT is still under development, the GitHub repository location and the <code>nat<\/code> CLI name itself are in constant flux. Please refer to the latest documentation alongside this article when running the <code>nat<\/code> CLI.<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Installing_the_latest_version\"><\/span>Installing the latest version<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You\u2019ll need to clone <a href=\"https:\/\/github.com\/NVIDIA\/NeMo-Agent-Toolkit\">the Github repository<\/a>\u2019s <code>development<\/code> branch and build the <code>nat<\/code> CLI from source. You can refer to <a href=\"https:\/\/github.com\/NVIDIA\/NeMo-Agent-Toolkit\/blob\/develop\/docs\/source\/quick-start\/installing.md#install-from-source\">the installation guide<\/a> for more information.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Installing_the_stable_version\"><\/span>Installing the stable version<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You can install the stable version of NAT using <code>uv<\/code> .<\/p>\n\n\n\n<p><em>Using <code>pip<\/code> directly can work, although we don\u2019t recommend that due to different NAT workflows needing different Python versions and packages, which can mess up your global Python installation.<\/em><\/p>\n\n\n\n<p>You can run the <code>uv add<\/code> command to add NAT to our project.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>uv add nvidia-nat<\/code><\/pre>\n\n\n\n<p>You can also add additional agent integrations!<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>uv add 'nvidia-nat&#91;langchain]' # Add LangChain integration<\/code><\/pre>\n\n\n\n<p>Make sure to activate the virtual environment for your project.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>source .\/.venv\/bin\/activate<\/code><\/pre>\n\n\n\n<p>If you can run the <code>nat<\/code> CLI, you\u2019re all set!<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>$ nat --version\nnat, version 1.3.0\n\n$ nat --help\nUsage: nat &#91;OPTIONS] COMMAND &#91;ARGS]...\n\n  Main entrypoint for the NAT CLI\n\nOptions:\n  --version                       Show the version and exit.\n  --log-level &#91;debug|info|warning|error|critical]\n                                  Set the logging level  &#91;default: INFO]\n  --help                          Show this message and exit.\n\nCommands:\n  configure     Configure NAT developer preferences.\n  eval          Evaluate a workflow with the specified dataset.\n  info          Provide information about the local NAT environment.\n  mcp           MCP-related commands.\n  object-store  Manage object store operations.\n  optimize      Optimize a workflow with the specified dataset.\n  registry      Utility to configure NAT remote registry channels.\n  run           Run a NAT workflow using the console front end.\n  serve         Run a NAT workflow using the fastapi front end.\n  sizing        Size GPU clusters for workflows with the specified options.\n  start         Run a NAT workflow using a front end configuration.\n  uninstall     Uninstall plugin packages from the local environment.\n  validate      Validate a configuration file\n  workflow      Interact with templated workflows.<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Running_the_nat_CLI\"><\/span>Running the <code>nat<\/code> CLI<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>We need an API key from NVIDIA (<code>NVIDIA_API_KEY<\/code> ) to run the <code>nat<\/code> CLI. Create your API key on <a href=\"https:\/\/build.nvidia.com\/\"><code>https:\/\/build.nvidia.com\/<\/code><\/a> , and put it in your <code>.env<\/code> file.<\/p>\n\n\n\n<p>(The <code>nat<\/code> CLI reads from the <code>.env<\/code> file by default.)<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>NVIDIA_API_KEY=&lt;YOUR API KEY HERE&gt;<\/code><\/pre>\n\n\n\n<p class=\"has-gray-100-background-color has-background\">\ud83d\udca1 This API key is meant for development, so don\u2019t use it in production!<\/p>\n\n\n\n<p>Let\u2019s create a <code>config.yaml<\/code> file and put our workflow configuration in there.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>functions:\n  wiki_search:\n    _type: wiki_search\n    max_results: 5\n  current_datetime:\n    _type: current_datetime\n\nllms:\n  nim_llm:\n    _type: nim\n    model_name: meta\/llama-3.1-70b-instruct\n    temperature: 0.0\n\nworkflow:\n  _type: react_agent\n  tool_names: &#91;wiki_search, current_datetime]\n  llm_name: nim_llm\n  verbose: true\n  parse_agent_response_max_retries: 3<\/code><\/pre>\n\n\n\n<p>Make sure to add the LangChain integration we talked about in the previous section.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>$ uv add 'nvidia-nat&#91;langchain]'<\/code><\/pre>\n\n\n\n<p class=\"has-gray-100-background-color has-background\">\ud83d\udca1 Running the <code>nat<\/code> CLI without the LangChain integration will get us an error: <code>ModuleNotFoundError: No module named 'langchain.schema\u2019<\/code>.<br>The LangChain integration is required to use functions like <a href=\"https:\/\/docs.nvidia.com\/nemo\/agent-toolkit\/latest\/api\/nat\/plugins\/langchain\/tools\/wikipedia_search\/index.html\">wiki_search<\/a>.<\/p>\n\n\n\n<p>You can now run the <code>nat<\/code> CLI!<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>$ nat run --config_file=.\/config.yaml --input \"What is LangSmith\"<\/code><\/pre>\n\n\n\n<p>You can see our agent searches for LangSmith information on Wikipedia, all through LangChain.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>2025-11-05 16:35:14 - INFO     - nat.cli.commands.start:192 - Starting NAT from config file: 'config.yaml'\n\nConfiguration Summary:\n--------------------\nWorkflow Type: react_agent\nNumber of Functions: 2\nNumber of Function Groups: 0\nNumber of LLMs: 1\nNumber of Embedders: 0\nNumber of Memory: 0\nNumber of Object Stores: 0\nNumber of Retrievers: 0\nNumber of TTC Strategies: 0\nNumber of Authentication Providers: 0\n\n2025-11-05 16:35:17 - INFO     - nat.agent.react_agent.agent:169 - \n------------------------------\n&#91;AGENT]\nAgent input: What is LangSmith\nAgent's thoughts: \nThought: I need to find more information about LangSmith to answer the question.\nAction: wiki_search\nAction Input: {\"question\": \"LangSmith\"}\n\n------------------------------\n2025-11-05 16:35:30 - INFO     - nat.agent.base:221 - \n------------------------------\n&#91;AGENT]\nCalling tools: wiki_search\nTool's input: {'question': 'LangSmith'}\nTool's response: \n&lt;Document source=\"https:\/\/en.wikipedia.org\/wiki\/LangChain\" page=\"\"\/>\nLangChain is a software framework that helps facilitate the integration of large language models (LLMs) into applications. As a language model integration framework, LangChain's use-cases largely overlap with those of language models in general, including document analysis and summarization, chatbots, and code analysis.\n\n\n== History ==\nLangChain was launched in October 2022 as an open source project by Harrison Chase, while working at machine learning startup Robust Intelligence. In April 2023, LangChain had incorporated and the new startup raised over $20 million in funding at a valuation of at least $200 million from venture firm Sequoia Capital, a week after announcing a $10 million seed investment from Benchmark.\nIn the third quarter of 2023, the LangChain Expression Language (LCEL) was introduced, which provides a declarative way to define chains of actions.\nIn October 2023 LangChain introduced LangServe, a deplo...(rest of response truncated)\n------------------------------\n2025-11-05 16:35:31 - INFO     - nat.agent.react_agent.agent:193 - \n------------------------------\n&#91;AGENT]\nAgent input: What is LangSmith\nAgent's thoughts: \nThought: I now know the final answer\nFinal Answer: LangSmith is a closed-source observability and evaluation platform for LLM applications, released by LangChain in February 2024.\n------------------------------\n2025-11-05 16:35:31 - INFO     - nat.front_ends.console.console_front_end_plugin:102 - --------------------------------------------------\nWorkflow Result:\n&#91;'LangSmith is a closed-source observability and evaluation platform for LLM applications, released by LangChain in February 2024.']\n--------------------------------------------------<\/code><\/pre>\n\n\n\n<p>The final answer in <code>Workflow Result<\/code> seems appropriate: <code>LangSmith is a closed-source observability and evaluation platform for LLM applications, released by LangChain in February 2024.<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Creating_Custom_Functions\"><\/span>Creating Custom Functions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>We can also create custom functions! This allows us to use frameworks like Agent Development Kit (ADK), or run tasks defined outside our workflow configuration.<\/p>\n\n\n\n<p>Let\u2019s create a <code>workflows<\/code> directory, and add the existing <code>text_file_ingest<\/code> document function.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>nat workflow create --workflow-dir workflows text_file_ingest <\/code><\/pre>\n\n\n\n<p>NAT creates a <code>text_file_ingest<\/code> workflow, with a <code>text_file_ingest.py<\/code> Python file containing our custom function.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>workflows\n\u2514\u2500\u2500 text_file_ingest\n    \u251c\u2500\u2500 configs -&gt; .\/workflows\/google_search\/src\/text_file_ingest\/configs\n    \u251c\u2500\u2500 data -&gt; .\/workflows\/google_search\/src\/text_file_ingest\/data\n    \u251c\u2500\u2500 pyproject.toml\n    \u2514\u2500\u2500 src\n        \u2514\u2500\u2500 text_file_ingest\n            \u251c\u2500\u2500 __init__.py\n            \u251c\u2500\u2500 __pycache__\n            \u251c\u2500\u2500 configs\n            \u251c\u2500\u2500 data\n            \u251c\u2500\u2500 text_file_ingest.py\n            \u2514\u2500\u2500 register.py<\/code><\/pre>\n\n\n\n<p>We\u2019ll skip over the details of the directory structure, but in short:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>configs<\/code> contains the workflow settings<\/li><li><code>data<\/code> contains the sample data used in the workflow<\/li><li><code>register.py<\/code> publishes the workflow<\/li><li><code>text_file_ingest.py<\/code> contains the main function body<\/li><\/ul>\n\n\n\n<p>You can modify any of the above files and rebuild the workflow with the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>nat workflow reinstall text_file_ingest<\/code><\/pre>\n\n\n\n<p>You also need to install your workflow as a Python package to make it callable.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>uv pip install -e workflows\/text_file_ingest<\/code><\/pre>\n\n\n\n<p class=\"has-gray-100-background-color has-background\">\ud83d\udeab You can also delete the workflow using <code>nat workflow delete text_file_ingest<\/code> . Be careful!<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Using_ADK_to_create_a_Google_Search_custom_function\"><\/span>Using ADK to create a Google Search custom function<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Let\u2019s apply what we\u2019ve learned so far, and make a custom function using Google Search through ADK. We\u2019ll call it <code>google_search<\/code> .<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>nat workflow create --workflow-dir workflows google_search<\/code><\/pre>\n\n\n\n<p>ADK has several <a href=\"https:\/\/google.github.io\/adk-docs\/tools\/built-in-tools\/#google-search\">built-in tools<\/a>, making it easy to use Google Search, as you can see in our custom Python function code. All we\u2019re doing is using the ADK Runner!<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>import logging\n\nfrom pydantic import Field\n\nfrom nat.builder.builder import Builder\nfrom nat.builder.framework_enum import LLMFrameworkEnum\nfrom nat.builder.function_info import FunctionInfo\nfrom nat.cli.register_workflow import register_function\nfrom nat.data_models.function import FunctionBaseConfig\n\nlogger = logging.getLogger(__name__)\n\nclass GoogleSearchFunctionConfig(FunctionBaseConfig, name=\"google_search\"):\n    \"\"\"\n    NAT function template. Please update the description.\n    \"\"\"\n    description: str = Field(description=\"Description of the Google Search function.\")\n    llm_name: str = Field(\"gemini-2.5-flash\")\n    user_id: str = Field(\"user1234\", description=\"User ID for the Google Search function.\")\n    session_id: str = Field(\"user1234\", description=\"Session ID for the Google Search function.\")\n\n@register_function(config_type=GoogleSearchFunctionConfig, framework_wrappers=&#91;LLMFrameworkEnum.LANGCHAIN])\nasync def google_search_function(config: GoogleSearchFunctionConfig, builder: Builder):\n    \"\"\"\n    Registers a function (addressable via `google_search` in the configuration).\n    This registration ensures a static mapping of the function type, `google_search`, to the `GoogleSearchFunctionConfig` configuration object.\n\n    Args:\n        config (GoogleSearchFunctionConfig): The configuration for the function.\n        builder (Builder): The builder object.\n\n    Returns:\n        FunctionInfo: The function info object for the function.\n    \"\"\"\n\n    from google.adk.agents import Agent\n    from google.adk.runners import Runner\n    from google.adk.sessions import InMemorySessionService\n    from google.adk.tools import google_search\n    from google.genai import types\n\n    APP_NAME=\"basic_search_agent\"\n\n    root_agent = Agent(\n        name=APP_NAME,\n        model=config.llm_name,\n        description=config.description,\n        instruction=\"I can answer your questions by searching the internet. Just ask me anything!\",\n        tools=&#91;google_search]\n    )\n\n    # Session and Runner\n    async def setup_session_and_runner():\n        session_service = InMemorySessionService()\n        session = await session_service.create_session(app_name=APP_NAME, user_id=config.user_id, session_id=config.session_id)\n        runner = Runner(agent=root_agent, app_name=APP_NAME, session_service=session_service)\n        return session, runner\n\n    # Agent Interaction\n    session, runner = await setup_session_and_runner()\n\n    async def call_agent_async(query) -&gt; str:\n        content = types.Content(role='user', parts=&#91;types.Part(text=query)])\n        events = runner.run_async(user_id=config.user_id, session_id=config.session_id, new_message=content)\n        final_response = \"\"\n\n        async for event in events:\n            if event.is_final_response():\n                final_response = event.content.parts&#91;0].text\n                print(\"Agent Response: \", final_response)\n\n        return final_response\n\n    async def _inner(query: str) -&gt; str:\n\n        return await call_agent_async(query)\n\n    yield FunctionInfo.from_fn(_inner, description=config.description)<\/code><\/pre>\n\n\n\n<p>To use ADK, we need to add the ADK integration package as a dependency to the workflow\u2019s <code>pyproject.toml<\/code> .<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>\"nvidia-nat&#91;adk]~=1.3\",<\/code><\/pre>\n\n\n\n<p>Build and install the workflow, and you\u2019ll be able to reference and use it!<\/p>\n\n\n\n<p>Be sure to log in using the <code>gcloud<\/code> CLI before using the workflow.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>gcloud auth application-default login<\/code><\/pre>\n\n\n\n<p>Here\u2019s our updated workflow configuration, with the <code>google_search<\/code> function referenced and enabled.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>functions:\n  google_search:\n    _type: google_search\n    description: \"Search the internet using Google Search.\"\n  current_datetime:\n    _type: current_datetime\n\nllms:\n  nim_llm:\n    _type: nim\n    model_name: meta\/llama-3.1-70b-instruct\n    temperature: 0.0\n\nworkflow:\n  _type: react_agent\n  tool_names: &#91;google_search, current_datetime]\n  llm_name: nim_llm\n  verbose: true\n  parse_agent_response_max_retries: 3<\/code><\/pre>\n\n\n\n<p>We can now run our updated workflow, and our agent is using ADK to perform Google searches.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>$ nat run --config_file=.\/config.yaml --input \"What is LangSmith\"\n\n...\n\n2025-11-11 15:15:55 - INFO     - google_adk.google.adk.models.google_llm:113 - Sending out request, model: gemini-2.5-flash, backend: GoogleLLMVariant.VERTEX_AI, stream: False\n2025-11-11 15:15:55 - INFO     - google_genai.models:6850 - AFC is enabled with max remote calls: 10.\n2025-11-11 16:33:42 - INFO     - google_adk.google.adk.models.google_llm:161 - Response received from the model.\nAgent Response: \n\n...\n\n------------------------------\n2025-11-11 15:16:03 - INFO     - nat.agent.react_agent.agent:193 - \n------------------------------\n&#91;AGENT]\nAgent input: What is LangSmith\nAgent's thoughts: \nThought: I now know the final answer\n\nFinal Answer: LangSmith is a comprehensive platform designed for developing, debugging, evaluating, and deploying applications built with large language models (LLMs). It provides a unified environment to manage the entire lifecycle of LLM applications, from local development to production, and offers features such as observability, debugging and tracing, evaluation, prompt testing and versioning, deployment, framework agnosticism, and compliance.\n------------------------------\n2025-11-11 15:16:03 - INFO     - nat.front_ends.console.console_front_end_plugin:102 - --------------------------------------------------\nWorkflow Result:\n&#91;'LangSmith is a comprehensive platform designed for developing, debugging, evaluating, and deploying applications built with large language models (LLMs). It provides a unified environment to manage the entire lifecycle of LLM applications, from local development to production, and offers features such as observability, debugging and tracing, evaluation, prompt testing and versioning, deployment, framework agnosticism, and compliance.']\n--------------------------------------------------<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>We\u2019ve just covered what NeMo Agent Toolkit is, and how to create our own functions using ADK!<\/p>\n\n\n\n<p>NeMo Agent Toolkit is designed to be CLI-first. Developers can create workflow functions, and users can create a workflow configuration to orchestrate and run these workflow functions.<\/p>\n\n\n\n<p>This allows for various deployment strategies. For example, you can use <a href=\"https:\/\/cloud.google.com\/workflows\">Google Cloud Workflows<\/a> to run NAT workflows as tasks!<\/p>\n\n\n\n<p>It still remains to be seen what the best way is forward for both developers and users. How does this affect your Git strategy for example?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"References\"><\/span>References<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/docs.nvidia.com\/nemo\/agent-toolkit\/latest\/tutorials\/create-a-new-workflow.html\">https:\/\/docs.nvidia.com\/nemo\/agent-toolkit\/latest\/tutorials\/create-a-new-workflow.html<\/a><\/li><li><a href=\"https:\/\/github.com\/NVIDIA\/NeMo-Agent-Toolkit\">https:\/\/github.com\/NVIDIA\/NeMo-Agent-Toolkit<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Welcome from the Sreake team! Learn what NVIDIA NeMo Agent Toolkit is, and how you can use it to create AI agents and workflows.<\/p>\n","protected":false},"author":45,"featured_media":12853,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_locale":"en_US","_original_post":"https:\/\/sreake.com\/?p=12397","footnotes":""},"categories":[17],"tags":[23],"class_list":["post-12456","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-enginner-blog","en-US"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/users\/45"}],"replies":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/comments?post=12456"}],"version-history":[{"count":1,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12456\/revisions"}],"predecessor-version":[{"id":12874,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12456\/revisions\/12874"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/media\/12853"}],"wp:attachment":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/media?parent=12456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/categories?post=12456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/tags?post=12456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}