Skip to content

Commit 523797a

Browse files
authored
f-ragent-post (#66)
* f-ragent-post * link checker * its still not tolstoy * tweak * tweak * some more
1 parent 6cff5b3 commit 523797a

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

.lycheeignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ support.rstudio.com
66
404
77
r-bloggers.com
88
krlmlr+r@mailbox.org
9+
https://jwt.io
10+
https://github.com/yihui/tinytex-releases/issues/19
911
^mailto:
1012
https://community.jitsi.org/t/how-can-i-add-extra-jvb-in-docker-meet/30911/36
1113
https://relational.fit.cvut.cz

posts/2025-02-07-r-agents/index.qmd

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
date: 2025-02-07
3+
layout: post
4+
image: michael-dziedzic-aQYgUYwnCsM-unsplash.jpg
5+
author: Christoph Sax
6+
title: 'Playing with AI Agents in R'
7+
categories:
8+
- R
9+
- LLM
10+
---
11+
12+
```{r}
13+
#| include: false
14+
knitr::opts_chunk$set(
15+
collapse = TRUE,
16+
comment = "#>"
17+
)
18+
```
19+
20+
## Intro
21+
22+
It's local LLM time! 🥳 What an adventure it has been since I first started [exploring local LLMs](https://blog.cynkra.com/posts/2024-07-27-llama3.1/). With the introduction of various new Llama models, we now have impressive small and large models that run seamlessly on consumer hardware. With deepseek R1, we have access to remarkably good MIT-licensed reasoning models that rival the top models in the industry.
23+
24+
And now, we've got a fully-specced M4 Mac Mini for our office, which runs all of this like a charm.
25+
26+
In this post, I will explore how we can use R to run agent models [through Ollama](https://ollama.com).
27+
28+
## What is an agent?
29+
30+
Unlike normal chats, agents can use tools to do tasks. Tools are pieces of software that can do anything, and it is up to the user to construct the agentic workflow they want. With R, we have a powerful language to configure these workflows and tell the tools what to do.
31+
32+
A typical agentic workflow looks like this:
33+
34+
1. You tell an LLM what you want in plain English and the tools it has available
35+
2. The LLM figures out what tools it needs to use
36+
3. The agent uses the tools to get the job done
37+
4. Iterate, improve or continue with other tasks
38+
5. Let the LLM explain what it did
39+
40+
## R and Ollama
41+
For the following experiments with agents, I'm using plain R and Ollama (which you have to install first, but it's [straightforward.](https://blog.cynkra.com/posts/2024-07-27-llama3.1/))
42+
43+
I know that there is the R package [ellmer](https://ellmer.tidyverse.org), and you can do many things that I am doing here with it.
44+
While [ellmer](https://ellmer.tidyverse.org) is a great package, I prefer to work directly with the Ollama API. In my opinion, this gives us more transparency into the agent mechanics.
45+
46+
My experiments with agents in R can be found in the [ragent](https://github.com/cynkra/ragent) repository on GitHub. To install the package, use:
47+
48+
```{r}
49+
#| eval: false
50+
remotes::install_github("cynkra/ragent")
51+
```
52+
53+
I will use diagrams to show the conversation flow and the tools that are used.
54+
55+
## A simple chat
56+
57+
Getting started is straightforward. In [llm_chat()](https://github.com/cynkra/ragent/blob/main/R/llm_chat.R), I've used the `httr2` package to wrap the Ollama API. You can use the function to perform normal chats:
58+
59+
```{r}
60+
#| eval: false
61+
library(ragent)
62+
llm_chat("What is the capital of France?")
63+
#> Paris is the capital of France.
64+
```
65+
66+
67+
```{mermaid}
68+
sequenceDiagram
69+
autonumber
70+
participant User
71+
participant LLM
72+
73+
User->>LLM: Question
74+
Note over LLM: No tools needed
75+
LLM-->>User: Direct response
76+
```
77+
78+
79+
No surprise here: The user asks a question (1) and the LLM answers (2). By default, I am using the [`llama3.2:3b`](https://ollama.com/library/llama3.2) model, because it's fast and good enough for this demo. But I can change it to any other, more powerful model that Ollama supports. E.g,:
80+
81+
```{r}
82+
#| eval: false
83+
llm_chat("What is the capital of France?", model = "deepseek-r1:14b")
84+
```
85+
86+
87+
## Structured output
88+
89+
The ollama API supports structured output. We can use this to tell the LLM to return a specific format. For example:
90+
91+
```{r}
92+
#| eval: false
93+
llm_chat("What is the capital of France?", format = list(
94+
type = "object",
95+
properties = list(
96+
country = list(type = "string"),
97+
capital = list(type = "string")
98+
),
99+
required = c("country", "capital")
100+
))
101+
#> $country
102+
#> [1] "France"
103+
#>
104+
#> $capital
105+
#> [1] "Paris"
106+
```
107+
108+
This structured response makes it easy to process the output programmatically in R, as it will be automatically converted to a list with named elements. It is often a good idea to add a system prompt to guide the LLM to the desired output.
109+
110+
111+
## A agent that can calculate
112+
113+
This is now a sweet setup for tinkering. We can use R to work with this output to do more complex things.
114+
115+
Note that LLMs are not really good at calculating. The small Llama model that I am using here messes this up:
116+
117+
```{r}
118+
#| eval: false
119+
llm_chat("What is 2.111^2.111")
120+
#> [1] "To calculate this, we can use the formula for squaring a binomial:\n\n(a + b)^2 = a^2 + 2ab + b^2\n\nIn this case, a = 2 and b = 1.111.\n\nSo, \n\n(2 + 1.111)^2 = \n(3.111)^2 = 9.377226\n2*3.111 = 6.222442\n6.222442 + 9.377226 = 15.600668\n\nTherefore, 2.111^2.111 ≈ 15.60"
121+
```
122+
123+
But we can tell the LLM to use a calculator tool to do the calculation in R. The result [looks like this](https://github.com/cynkra/ragent/blob/main/R/agent_calculator.R):
124+
125+
```{r}
126+
#| eval: false
127+
agent_calculator("What is 2.111^2.111")
128+
#> **Calculation Result:** 2.111^2.111 = 4.84166414903285
129+
```
130+
131+
132+
```{mermaid}
133+
sequenceDiagram
134+
autonumber
135+
participant User
136+
participant Agent
137+
participant Calculator
138+
139+
User->>Agent: Math question
140+
Note over Agent: Analyzes question<br/>Decides to use calculator
141+
Agent->>Calculator: Structured calculation request
142+
Calculator-->>Agent: Numerical result
143+
Note over Agent: Formats response
144+
Agent-->>User: Explained calculation
145+
```
146+
147+
Much better! This is an agent that:
148+
149+
1. Analyzes the question
150+
2. Decides to use the calculator tool
151+
3. Uses the calculator tool to calculate the result in R
152+
4. Returns the response to the user
153+
154+
## A smarter RAG
155+
156+
A simple RAG (Retrieval Augmented Generation) enhances LLM responses by first searching a knowledge base for relevant information. But our improved RAG goes a step further: after the initial search, the LLM formulates additional questions to gather more context, leading to more comprehensive answers.
157+
158+
In [our smarter RAG](https://github.com/cynkra/ragent/blob/main/R/agent_rag.R), we build an agent that:
159+
160+
- Search the knowledge base for relevant passages (2)
161+
- Ask the LLM to provide additional questions to search for (5)
162+
- Search the knowledge base for the additional questions (7)
163+
- Use the context to answer the question (10)
164+
165+
```{mermaid}
166+
sequenceDiagram
167+
autonumber
168+
participant User
169+
participant Agent
170+
participant RAG
171+
participant Docs
172+
173+
User->>Agent: Question about docs
174+
Note over Agent: Analyzes question
175+
Agent->>RAG: Initial search
176+
RAG->>Docs: Search in directory
177+
Docs-->>RAG: Initial passages
178+
RAG-->>Agent: Initial context
179+
Note over Agent: Formulates follow-up<br/>questions for context
180+
Agent->>RAG: Additional searches
181+
RAG->>Docs: Search with new questions
182+
Docs-->>RAG: Additional passages
183+
RAG-->>Agent: Combined context
184+
Note over Agent: Synthesizes all<br/>information
185+
Agent-->>User: Complete response<br/>with citations
186+
```
187+
188+
```{r}
189+
#| eval: false
190+
agent_rag("What is ggplot2 used for?", dir = "docs/")
191+
#> Based on the documentation:
192+
#> ggplot2 is a core package of the tidyverse used for visualization.
193+
#> [Source: tidyverse.md]
194+
```
195+
196+
This is just the beginning. We can build much more complex agents. For example, we could create a general agent that combines both the calculator and RAG capabilities. This agent would analyze each question and automatically choose the right approach - either searching the knowledge base or performing calculations.
197+
198+
## Conclusion
199+
200+
R is a powerful language for building AI agents. Its functional nature makes tools feel like Lego bricks that we can combine. The way R handles lists and data frames fits nicely with the JSON returned from the API, and the rich R ecosystem provides everything we need to build powerful agents. But what I found most useful is R's interactive workflow that allows me to watch and debug the workings of the LLMs and the tools step by step.
Loading

0 commit comments

Comments
 (0)