From 8d6ed6008bd4526de183838db2b68c4c061af432 Mon Sep 17 00:00:00 2001 From: Jaidev Singh Chadha Date: Mon, 22 Jun 2026 13:58:54 -0700 Subject: [PATCH 1/5] Add Learning Path: build a CPU-orchestrated local AI agent with Ollama and Gemma --- assets/contributors.csv | 1 + .../ai-agent-cpu-orchestration/1-overview.md | 60 ++ .../ai-agent-cpu-orchestration/2-setup.md | 90 +++ .../ai-agent-cpu-orchestration/3-ollama.md | 106 +++ .../4-code-walkthrough.md | 150 ++++ .../5-run-and-examples.md | 114 +++ .../6-cpu-orchestration.md | 67 ++ .../ai-agent-cpu-orchestration/_index.md | 75 ++ .../ai-agent-cpu-orchestration/_next-steps.md | 8 + .../concierge_agent.py | 660 ++++++++++++++++++ 10 files changed, 1331 insertions(+) create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/1-overview.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/2-setup.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/3-ollama.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/4-code-walkthrough.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/5-run-and-examples.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/6-cpu-orchestration.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/_index.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/_next-steps.md create mode 100644 content/learning-paths/cross-platform/ai-agent-cpu-orchestration/concierge_agent.py diff --git a/assets/contributors.csv b/assets/contributors.csv index 7ea5309e90..7df5e1416c 100644 --- a/assets/contributors.csv +++ b/assets/contributors.csv @@ -2,6 +2,7 @@ author,company,github,linkedin,twitter,website Jason Andrews,Arm,jasonrandrews,jason-andrews-7b05a8,, Doug Anson,Arm,DougAnsonAustinTx,douganson,, Pareena Verma,Arm,pareenaverma,pareena-verma-7853607,, +Jaidev Singh Chadha,Arm,jaidev17,jaidevsinghchadha,, Ronan Synnott,Arm,,ronansynnott,, Florent Lebeau,Arm,,,, Brenda Strech,Remote.It,bstrech,bstrech,@remote_it,www.remote.it diff --git a/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/1-overview.md b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/1-overview.md new file mode 100644 index 0000000000..f7f9956f1b --- /dev/null +++ b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/1-overview.md @@ -0,0 +1,60 @@ +--- +title: Understand the agent and the CPU/GPU split +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## What you'll build + +In this Learning Path, you'll build and run a *local concierge agent*: a terminal application that answers research-style questions, such as finding restaurants, comparing products, or summarizing a topic, by searching the web, reading multiple pages, and writing a fact-checked summary. + +Everything runs on your own Arm machine. The agent uses a large language model (LLM) served locally by [Ollama](https://ollama.com/), so your prompts and the pages you browse never leave the device. The same code runs on an Apple silicon MacBook, an Arm Linux laptop, or an NVIDIA DGX Spark. + +The agent is interesting not just because it runs locally, but because of *how the work is divided*. A common assumption is that an AI agent is "just the model." In practice, the model is only one stage in a longer pipeline, and most of the surrounding work runs on the CPU. + +## The agentic loop + +Each time you ask the agent a question, it runs through a chain of steps rather than a single model call: + +```text +Your question + -> Decide what to search for (GPU: model reasoning) + -> Expand into several search queries (CPU: orchestration) + -> Run web searches in parallel (CPU: network I/O) + -> Choose which pages to open (GPU: model reasoning) + -> Scrape those pages in parallel (CPU: network I/O) + -> Rank, deduplicate, extract data (CPU: text processing) + -> Write a fact-checked summary (GPU: model reasoning) +``` + +The model is called several times, but between every model call the CPU does a large amount of orchestration: generating query variants, dispatching parallel network requests, merging and deduplicating results, scoring pages for relevance, and extracting structured data such as phone numbers and opening hours. + +## Why the CPU matters in an agentic workflow + +It's easy to focus only on token generation, because that's the visible "thinking" part. But in an agent, the CPU is responsible for turning a single user request into useful, structured context for the model: + +| Stage | Runs on | Example work | +|---|---|---| +| Reasoning and summarization | GPU | Choosing search terms, selecting URLs, writing the final answer | +| Orchestration | CPU | Expanding queries, scheduling parallel tasks, merging results | +| Web I/O | CPU | Calling the search API, downloading and parsing web pages | +| Text processing | CPU | TF-IDF ranking, deduplication, entity extraction, indexing | + +This division is a natural fit for Arm platforms. On an Apple silicon MacBook or an Arm Linux machine, the CPU handles all orchestration and I/O while the GPU accelerates the model. On an NVIDIA DGX Spark, the Arm CPU coordinates the workflow while the GPU runs inference. In every case, the model is only as good as the context the CPU prepares for it. + +## How the agent shows you the split + +The program is instrumented so you can see this division directly. As it runs, it prints: + +- `[CPU]` log lines (in cyan) for every orchestration and processing step +- `[GPU]` log lines (in yellow) for every model call +- A timing breakdown of CPU time versus GPU input-token processing and token generation +- A text-based timeline that visualizes when the CPU and GPU are each active + +By the end of this Learning Path, you'll be able to look at a single query and see exactly how much of the work happened on the CPU before and after the model produced its answer. + +## What's next + +In the next section, you'll set up your environment: create a Python virtual environment, install the required packages, and get a Serper API key for web search. diff --git a/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/2-setup.md b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/2-setup.md new file mode 100644 index 0000000000..cfa8b7eb95 --- /dev/null +++ b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/2-setup.md @@ -0,0 +1,90 @@ +--- +title: Set up your environment +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Set up your environment + +In this section, you'll prepare everything the agent needs before running it: a Serper API key for web search, a Python virtual environment, the required packages, and the agent script itself. + +These steps are identical on an Apple silicon MacBook, an Arm Linux machine, and an NVIDIA DGX Spark. + +## Get a Serper API key + +The agent searches the web through [Serper](https://serper.dev/), a Google Search API. The free tier is enough to complete this Learning Path. + +1. Go to [serper.dev](https://serper.dev/) and create a free account. +2. Open your dashboard and copy your API key. + +You'll set this key as an environment variable later in this section, so the agent can read it without the key being written into the code. + +{{% notice Note %}} +Never paste your API key directly into source code that you share or commit. Always read it from an environment variable, as shown below. +{{% /notice %}} + +## Create a project directory and virtual environment + +A virtual environment keeps the agent's dependencies isolated from your system Python, so you always run against the right package versions. + +Create and enter a project directory: + +```bash +mkdir concierge-agent +cd concierge-agent +``` + +Create and activate a virtual environment: + +```bash +python3 -m venv .venv +source .venv/bin/activate +``` + +Your shell prompt now shows `(.venv)`, which confirms the environment is active. + +## Install the required packages + +The agent uses `requests` for HTTP calls and `beautifulsoup4` to parse web pages. The remaining libraries it uses, such as `smtplib`, `json`, and `concurrent.futures`, are part of the Python standard library. + +Install the two packages: + +```bash +pip install requests beautifulsoup4 +``` + +## Set your Serper API key + +Export your API key as an environment variable in the same terminal session: + +```bash +export SERPER_API_KEY="your-serper-api-key" +``` + +{{% notice Tip %}} +This variable only lasts for the current terminal session. To keep it across sessions, add the same line to your shell profile, for example `~/.zshrc` on macOS or `~/.bashrc` on Linux. +{{% /notice %}} + +## Download the agent script + +Download the complete agent script, [concierge_agent.py](concierge_agent.py), into your project directory. You'll run it at the end of this Learning Path, and the next sections walk through how the important parts work. + +Download it directly from the command line: + +```bash +curl -O https://learn.arm.com/learning-paths/cross-platform/ai-agent-cpu-orchestration/concierge_agent.py +``` + +Confirm the file is in your project directory: + +```bash +ls concierge_agent.py +``` + +{{% notice Tip %}} +You can also save the file using the [concierge_agent.py](concierge_agent.py) link above, then move it into your `concierge-agent` directory. +{{% /notice %}} + +With the environment ready and the script in place, the next step is to serve a model locally with Ollama. diff --git a/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/3-ollama.md b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/3-ollama.md new file mode 100644 index 0000000000..cc277194c1 --- /dev/null +++ b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/3-ollama.md @@ -0,0 +1,106 @@ +--- +title: Serve a model locally with Ollama +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Run AI models locally with Ollama + +The agent's reasoning steps, such as choosing search terms, selecting URLs, and writing the final summary, are handled by a large language model. Instead of calling a cloud API, this Learning Path serves the model locally with [Ollama](https://ollama.com/). + +Ollama is a lightweight runtime that downloads open models, loads them into memory, and exposes a local HTTP API at `http://localhost:11434`. When the agent calls that endpoint, the model runs directly on your machine: the CPU and GPU on your MacBook, Arm Linux laptop, or NVIDIA DGX Spark. Nothing is sent to an external service. + +Running locally has three benefits that matter for an agent: + +- **Privacy**: your prompts and the web content the agent reads stay on the device. +- **Cost**: there are no per-token API charges, so you can run many queries freely. +- **Control**: you choose the exact model and keep it resident in memory for fast repeated calls. + +## Install Ollama + +Install Ollama for your operating system. + +{{< tabpane code=true >}} +{{< tab header="macOS" language="bash">}} +brew install ollama +{{< /tab >}} +{{< tab header="Linux" language="bash">}} +curl -fsSL https://ollama.com/install.sh | sh +{{< /tab >}} +{{< /tabpane >}} + +{{% notice Note %}} +On macOS you can also download the Ollama desktop app from [ollama.com/download](https://ollama.com/download). On an NVIDIA DGX Spark, follow the Linux instructions; Ollama uses the Blackwell GPU for inference automatically. +{{% /notice %}} + +## Start the Ollama server + +Start the Ollama background service, which hosts the local API the agent connects to: + +```bash +ollama serve +``` + +Leave this running in its own terminal. Open a second terminal for the remaining commands. + +{{% notice Tip %}} +On macOS, starting the Ollama desktop app already runs the server in the background, so you can skip `ollama serve`. +{{% /notice %}} + +## Pull the Gemma model + +This Learning Path uses [Gemma 3](https://ai.google.dev/gemma), Google's family of open models, in its 4-billion-parameter size (`gemma3:4b`). This size is a good default: it's capable enough for the agent's reasoning steps and small enough to run on a laptop. + +Download the model: + +```bash +ollama pull gemma3:4b +``` + +Confirm the model is available: + +```bash +ollama list +``` + +You'll see `gemma3:4b` in the list of installed models. + +## Choose a different model (optional) + +The agent reads the model name from the `OLLAMA_MODEL` environment variable, so you can switch models without editing the code. The default in the script is `gemma3:4b`. + +| Model | Size | Best for | +|---|---|---| +| `gemma3:4b` | 4B | Laptops and modest hardware; the default | +| `gemma3:27b` | 27B | High-memory systems such as DGX Spark, for stronger reasoning | + +To use a larger model on a DGX Spark, pull it and set the environment variable before running the agent: + +```bash +ollama pull gemma3:27b +export OLLAMA_MODEL="gemma3:27b" +``` + +{{% notice Note %}} +Larger models produce stronger summaries but use more memory and generate tokens more slowly. Start with `gemma3:4b` to confirm everything works, then experiment with larger models if your hardware allows. +{{% /notice %}} + +## Test the model + +Before wiring it into the agent, confirm the model responds: + +```bash +ollama run gemma3:4b +``` + +Enter a short prompt: + +```text +Summarize what a local AI agent does in one sentence. +``` + +Type `/bye` to exit the model session. + +With Ollama serving `gemma3:4b`, you're ready to look at how the agent code uses it. diff --git a/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/4-code-walkthrough.md b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/4-code-walkthrough.md new file mode 100644 index 0000000000..f2a5c01580 --- /dev/null +++ b/content/learning-paths/cross-platform/ai-agent-cpu-orchestration/4-code-walkthrough.md @@ -0,0 +1,150 @@ +--- +title: Walk through the agent code +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## How the code is organized + +The `concierge_agent.py` script you downloaded earlier is organized into four parts. This section walks through the important pieces so you understand what runs on the CPU, what runs on the GPU, and how the agent chains them together. + +| Part | Responsibility | Runs on | +|---|---|---| +| Part 1: Tools | Web search, page scraping, optional email | CPU | +| Part 1.5: Orchestration pipeline | Query expansion, parallelism, ranking, deduplication, extraction | CPU | +| Part 2: The brain | Calls the local Gemma model through Ollama | GPU | +| Part 3: The agentic chain | Ties everything together into one query workflow | CPU + GPU | + +## Part 1: The tools + +The tools are the agent's connection to the outside world. `search_web()` calls the Serper API and returns the top five results; `browse_website()` downloads a page and strips it down to clean text. Both run entirely on the CPU and both log their activity with `log_cpu()`: + +```python +def search_web(query: str) -> str: + """Use the Serper.dev API to perform a web search.""" + log_cpu(f"Searching web: '{query}'") + ... + +def browse_website(url: str) -> str: + """Scrape and clean the text content of a given URL.""" + log_cpu(f"Browsing website: '{url}'") + ... + return text[:8000] +``` + +`browse_website()` uses BeautifulSoup to remove `