library(ellmer)
# 查看支持的模型
models_google_gemini()
chat <- chat_google_gemini(
system_prompt = "You are a surfy dude who likes waves, tubes and statistics.",
#base_url = "https://generativelanguage.googleapis.com/v1beta/",
model = "gemini-2.5-flash",
params = NULL,
api_args = list(),
api_headers = character(),
echo = NULL
)
live_console(chat)
live_browser(chat)
chat$chat("How can I do a glm in R?")
chat$chat("请用400字简要介绍一下R包ragnar的目标、特点和主要功能函数?")9 AI工具包
9.1 简介
9.2 ellmer
9.2.1 准备和使用方法
准备工作环境:
第一,获得大模型的API Key,例如google Gemini的API Key。在环境变量中设置GOOGLE_API_KEY,添加到.Renviron文件。具体操作如下:
usethis::edit_r_environ()或者使用Sys.setenv(GEMINI_API_KEY = "你的真实API_KEY")设置系统层级的环境变量。对于Windows用户,可以在C:\Users\<username>\.Renviron文件中添加。如何查看自己的系统环境变量?可以运行Sys.getenv()命令。
添加以下内容:
GOOGLE_API_KEY="your_google_api_key_here"
第二,安装ellmer包:
install.packages("ellmer")9.2.2 调用工具和函数
library(ellmer)
# 创建Google Gemini聊天对象
chat <- ellmer::chat_google_gemini(model = "gemini-2.5-flash")
# 创建目标函数
get_current_time <- function(tz = "Asia/Shanghai") {
format(Sys.time(), tz = tz, usetz = TRUE)
}
# 把函数转换为工具
# 必须保持函数名与工具名一致
get_current_time <- tool(
get_current_time,
name = "get_current_time",
description = "获取当前时间",
arguments = list(
tz = type_string(
"当前日期的时区,默认为 `\"Asia/Shanghai\"` 时区。", # 必须与函数参数名一致,注意转义符
required = FALSE
)
)
)
# 也可以使用create_tool_def函数,让AI自己创建上述工具定义
# create_tool_def(get_current_time, chat)
# 测试函数
get_current_time()
# [1] "2025-11-24 15:39:17 CST"
# 把工具注册到聊天对象
chat$register_tool(get_current_time)
# 测试工具
chat$chat("现在是什么时间?请用中文回答。")
# [1] "2025-11-24 15:39:17 CST"chat过程如下:
> chat
<Chat Google/Gemini/gemini-2.5-flash turns=4 input=180 output=114 cost=$0.00>
── user ─────────────────────────────────────────────────────────────────────────────
现在是什么时间?请用中文回答。
── assistant [input=66 output=91 cost=$0.00] ────────────────────────────────────────
[tool request (get_current_time)]: get_current_time()
── user ─────────────────────────────────────────────────────────────────────────────
[tool result (get_current_time)]: 2025-11-24 15:40:43 CST
── assistant [input=114 output=23 cost=$0.00] ───────────────────────────────────────
现在是2025年11月24日15点40分43秒。
9.3 ragnar
(1)ragnar包简要介绍:
ragnar是由tidyverse团队开发的R包,旨在在R语言环境中实现RAG(检索增强生成,Retrieval-Augmented Generation)技术。该包的核心目标是为R用户提供一套完整的工具链,用于构建知识库、检索相关信息,并将检索结果与大型语言模型(LLM)集成,从而提升AI对话系统的准确性和可靠性。
主要优点:首先,ragnar与R生态系统深度集成,特别是与ellmer包无缝配合,可以轻松为Chat对象添加检索功能。其次,支持多种数据源摄取,包括网页、Markdown文档等,通过ragnar_find_links()等函数可以方便地收集和整理知识内容。第三,采用DuckDB作为存储后端,利用其向量相似度搜索(VSS)和BM25全文搜索双重检索机制,既支持语义相似度匹配,也支持关键词精确匹配,检索效果更佳。第四,提供了完整的文本处理流程,包括自动分块(markdown_chunk())、去重叠(chunks_deoverlap())等功能,确保检索结果的准确性和完整性。
主要缺点:该包需要依赖外部API服务(如OpenAI)进行文本嵌入向量化,这意味着用户需要配置API密钥并承担相应的使用成本。此外,对于超大规模数据集,可能存在性能瓶颈,需要合理设计存储和索引策略。目前包仍处于活跃开发阶段,部分功能可能不够稳定。
主要功能函数:核心函数包括ragnar_store_create()用于创建知识存储库并指定嵌入函数;ragnar_store_insert()用于将处理后的文本块插入存储;ragnar_store_build_index()用于构建检索索引以提升查询性能;ragnar_retrieve()是高级检索函数,整合了VSS和BM25两种搜索方式并自动去重叠;ragnar_retrieve_vss()和ragnar_retrieve_bm25()分别提供向量相似度搜索和全文搜索功能;ragnar_register_tool_retrieve()可以将检索功能注册为ellmer::Chat对象的工具,使LLM能够按需从知识库中检索相关信息。通过这些函数的组合使用,用户可以构建完整的RAG应用系统,实现基于知识库的智能问答功能。
VSS与BM25检索机制:ragnar包采用双重检索机制,结合了向量相似度搜索(VSS)和BM25全文搜索的优势。
VSS(向量相似度搜索):基于语义相似度的检索方法。首先通过嵌入模型(如
gemini-embedding-001)将文本转换为高维向量表示,然后计算查询向量与文档向量之间的余弦相似度或欧氏距离。优点:能够理解语义含义,支持同义词和概念匹配,即使查询词与文档中的词不完全一致也能找到相关内容(例如”汽车”和”车辆”)。缺点:需要预先计算嵌入向量,计算成本较高;对于精确的关键词匹配可能不如传统方法准确;需要依赖外部嵌入API服务。BM25(Best Matching 25):基于词频和逆文档频率(TF-IDF)改进的全文搜索算法。BM25通过统计查询词在文档中的出现频率、文档长度以及词在整个语料库中的稀有程度来计算相关性分数。优点:计算速度快,无需外部API;对精确关键词匹配效果好;能够处理拼写错误和词形变化;结果可解释性强。缺点:无法理解语义,只能匹配字面相同的词;对于同义词和概念扩展支持有限;需要精确的查询词才能获得好的结果。
混合检索的优势:
ragnar_retrieve()函数同时使用VSS和BM25两种方法,然后合并和去重叠结果。这种混合策略能够结合两种方法的优势:VSS捕获语义相似的内容,BM25确保精确的关键词匹配,从而提供更全面和准确的检索结果。特别适合处理包含专业术语、同义词丰富或需要语义理解的复杂查询场景。
(2)ragnar包安装和使用:
使用ragnar包前需要完成以下准备工作。首先,由于该包需要调用嵌入API服务,用户需要获取相应的API密钥。如果使用Google的嵌入模型,需要在环境变量中设置GOOGLE_API_KEY。可以通过usethis::edit_r_environ()打开.Renviron文件,添加GOOGLE_API_KEY="your_google_api_key_here"。其次,安装ragnar包。由于该包目前可能尚未发布到CRAN,通常需要从GitHub安装:
# 安装ragnar包
renv::install("tidyverse/ragnar")安装完成后,基本使用流程包括三个步骤:创建知识存储库、导入数据并构建索引、执行检索。创建存储库时需要指定存储位置和嵌入函数,例如使用Google的嵌入模型。然后可以通过ragnar_find_links()查找网页链接,使用read_as_markdown()和markdown_chunk()处理文档并分块,通过ragnar_store_insert()将文本块插入存储库。数据导入完成后,调用ragnar_store_build_index()构建索引以提升检索性能。检索时使用ragnar_retrieve()函数,该函数会自动整合向量相似度搜索和BM25全文搜索,并去除重叠结果。最后,可以通过ragnar_register_tool_retrieve()将检索功能注册到ellmer::Chat对象,使LLM能够在对话过程中自动从知识库检索相关信息,实现真正的RAG应用。
9.4 RAG构建和测试
基于本地知识库的RAG构建和测试:
- LLM模型:Google Gemini 2.5 Flash
- 资料类别:关于农业政策的本地pdf文件,文件夹
ai/pdfs - 本地数据库:
ai/agriculture-policy-ragnar.duckdb
场景1:首次构建(包含索引构建)
store <- ragnar_store_create(...)
ragnar_store_insert(store, chunks)
ragnar_store_build_index(store) # 构建索引并保存场景2:后续使用(索引已存在,直接使用)
store <- ragnar_store_connect(path_store) # 自动加载已有索引
chat <- ellmer::chat_google_gemini(...)
ragnar_register_tool_retrieve(chat, store) # 建立关联
chat$chat("问题") # 使用索引进行检索场景3:添加新文档(需要重建索引)
store <- ragnar_store_connect(path_store, read_only = FALSE)
ragnar_store_insert(store, new_chunks)
ragnar_store_build_index(store) # 重建索引以包含新文档RAG构建和测试步骤如下(以OECD国家农业政策为例):
9.4.1 步骤1:加载必要的包
library(ragnar)
library(ellmer)
library(fs)9.4.2 步骤2:创建知识存储库
首先创建知识存储库,指定存储位置和嵌入函数。这里使用Google Gemini API的嵌入模型进行文本嵌入。确保已设置GEMINI_API_KEY环境变量:
# 定义存储库位置
store_location <- "ai/agriculture-policy-ragnar.duckdb"
# 创建知识存储库,使用Google Gemini API嵌入模型
# 注意:确保已设置 GEMINI_API_KEY 环境变量
# 对于文档存储,使用 task_type = "RETRIEVAL_DOCUMENT"
store <- ragnar_store_create(
store_location,
embed = \(x) ragnar::embed_google_gemini(
x,
model = "gemini-embedding-001",
task_type = "RETRIEVAL_DOCUMENT",
batch_size = 20L
)
)说明: - model: 使用 "gemini-embedding-001" 作为嵌入模型(默认值) - task_type: 设置为 "RETRIEVAL_DOCUMENT" 用于文档嵌入,检索时使用 "RETRIEVAL_QUERY" - api_key: 自动从环境变量 GEMINI_API_KEY 读取 - batch_size: 批处理大小,默认20个文本块
9.4.3 步骤3:读取和处理PDF文件
遍历PDF文件夹中的所有PDF文件,直接使用read_as_markdown()读取并转换为Markdown文本,再进行分块处理(该流程与官方示例保持一致):
# 定义PDF文件目录
pdf_dir <- "ai/pdfs"
# 获取所有PDF文件路径
pdf_files <- dir_ls(pdf_dir, regexp = "\\.pdf$", type = "file")
# 遍历处理每个PDF文件
for (pdf_file in pdf_files) {
message("正在处理: ", pdf_file)
chunks <- pdf_file |>
read_as_markdown() |>
markdown_chunk() |>
dplyr::mutate(origin = as.character(pdf_file))
ragnar_store_insert(store, chunks)
}9.4.4 步骤4:构建索引
所有PDF文件处理完成后,构建索引以提升检索性能:
# 构建向量搜索索引
ragnar_store_build_index(store)
message("索引构建完成!")说明:ragnar_store_build_index() 在 DuckDB 中创建两种索引:
- 向量索引(VSS):用于快速计算向量相似度
- 全文索引(BM25):用于快速关键词搜索
9.4.5 步骤5:测试检索功能
测试检索功能,验证知识库是否正常工作:
# 测试查询
query <- "哈萨克斯塔农业政策的中长期规划有哪些?用200字概括主要政策内容要点。以段落形式呈现。"
# 检索相关文本块
relevant_chunks <- ragnar_retrieve(store, query, top_k = 5)
# 查看检索结果
relevant_chunks |>
dplyr::pull(text) |>
paste(collapse = "\n\n") |>
print()9.4.6 步骤6:与Google Gemini模型集成
将检索功能注册到ellmer::Chat对象,实现RAG问答功能:
# 创建Google Gemini聊天对象
chat <- ellmer::chat_google_gemini(
system_prompt = "你是一个农业政策专家助手。请基于提供的文档内容回答问题,并引用具体的文档来源。",
model = "gemini-2.5-flash"
)
# 将检索工具注册到聊天对象
ragnar_register_tool_retrieve(chat, store, top_k = 10)
# 进行问答测试
response <- chat$chat(query)
print(response)哈萨克斯坦农业政策的中长期规划主要围绕提高农业产出、畜牧业发展、水资源利用效率、农业附加值、出口活动以及农 业科技进步展开。
其中,2021-2030年哈萨克斯坦农工综合体发展概念设定了关键政策目标,并通过2024年的修正案,提升了农业加工的优先地位,增加了国家支持措施和激励资金,加强了种子产业发展和数字化技术改进。2013年批准的哈萨克斯坦共和国向“绿色经济”转型概念为实现环境可持续的经济增长提供了框架,重点关注水、土地和生物资源的有效管理。2024年6月通过的2024-2028年农业加工综合计划旨在增加食品生产和加工农产品出口,减少进口依赖,具体措施包括通过补贴确保原材料供应 、提供优惠贷款和利息补贴提高生产盈利能力、通过保护性措施提高国内加工产品的竞争力以及拓展出口市场。此外,2023年批准的哈萨克斯坦共和国到2060年实现碳中和战略也包含了农业和畜牧业管理实践,如作物多样化、改善灌溉和气候智能型农业,并推动农业废弃物生物能源生产
(来源: OECD_2025_Agricultural Policy Monitoring and Evaluation 2025.pdf,第1591、1592、1593、1601、1603、1604、1626、1627分块)。
9.4.7 步骤7:连接已有存储库(可选)
如果存储库已存在,可以直接连接而不需要重新构建:
# 连接已存在的存储库(只读模式)
# 注意:需要使用与创建时相同的嵌入函数配置
store <- ragnar_store_connect(
store_location,
read_only = TRUE,
embed = \(x) ragnar::embed_google_gemini(
x,
model = "gemini-embedding-001",
task_type = "RETRIEVAL_DOCUMENT",
batch_size = 20L
)
)
# 创建聊天对象并注册检索工具
chat <- ellmer::chat_google_gemini(
system_prompt = "你是一个农业政策专家助手。",
model = "gemini-2.5-flash"
)
ragnar_register_tool_retrieve(chat, store, top_k = 10)
# 进行问答
chat$chat("这些政策文件中提到了哪些具体的农业支持措施?")9.5 参考资料
博客文章:
RAG with Ollama and ragnar in R: A Practical Guide for R Programmers: https://www.spsanderson.com/steveondata/posts/2025-10-29/
Repost: Tidy RAG in R with ragnar: https://www.r-bloggers.com/2025/07/repost-tidy-rag-in-r-with-ragnar/
说明文档:
- ragnar documentation: https://ragnar.tidyverse.org/
- ellmer documentation: https://ellmer.tidyverse.org/
视频教程:
- R+AI: Use RAG from your database to gain insights into the R Consortium https://www.youtube.com/watch?v=h0ewziCZ0WI