# Benchmark Source: https://ultrarag.openbmb.cn/pages/cn/api/benchmark ## `get_data` **签名** ```python theme={null} @app.tool(output="benchmark->q_ls,gt_ls") def get_data(benchmark: Dict[str, Any]) -> Dict[str, List[Any]] ``` **功能** * 多格式加载:支持从本地加载 `.jsonl`、`.json` 或 `.parquet` 格式的评测数据集。 * 动态字段映射:利用 `key_map` 将原始数据中的不同列名(如 `question`, `answer`)统一映射为标准化输出键(通常为 `q_ls` 和 `gt_ls`)。 * 数据预处理:内置支持随机打乱(`shuffle`)与数量截断(`limit`)。 * Demo 里用来接收用户输入,将其视作一条数据(`q_ls`)。 **输出格式(JSON)** ```json theme={null} { "q_ls": ["Question 1", "Question 2"], "gt_ls": [["Answer A1", "Answer A2"], ["Answer B"]] } ``` *** ## 参数配置 ```yaml servers/benchmark/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: name: nq path: data/sample_nq_10.jsonl key_map: q_ls: question gt_ls: golden_answers shuffle: false seed: 42 limit: -1 ``` 参数说明: | 参数 | 类型 | 说明 | | | --------- | ------- | ------------------------------------- | ------------------------------------------ | | `name` | str | 评测集名称,仅用于日志与标识(示例:`nq`) | | | `path` | str | 数据文件路径,支持 `.jsonl`、`.json`、`.parquet` | | | `key_map` | dict | 字段映射表,将原始字段映射为工具输出键 | | | | `q_ls` | str | 映射为 问题列表 的原始字段名(如文件中的 question 列) | | | `gt_ls` | str | 映射为 标准答案列表 的原始字段名(如文件中的 golden\_answers 列) | | `shuffle` | bool | 是否打乱样本顺序(默认 `false`) | | | `seed` | int | 随机种子(`shuffle=true` 时生效) | | | `limit` | int | 采样数据条数上限。默认为 -1(加载全部),正整数表示截取前 N 条 | | # CLI Source: https://ultrarag.openbmb.cn/pages/cn/api/cli ## help — 命令概览 ```bash theme={null} ultrarag --help ``` ```text theme={null} usage: ultrarag [-h] {build,run,show} ... UltraRAG CLI positional arguments: {build,run,show} build Build the configuration run Run the pipeline with the given configuration show Show ui interfaces options: -h, --help show this help message and exit ``` *** ## build — 构建配置 **用途**:基于 `pipeline.yaml` 自动生成统一的参数配置文件。 ```bash theme={null} ultrarag build [--log_level DEBUG|INFO|WARN|ERROR] ``` | 参数 | 描述 | | ------------- | ------------------------------------------ | | `` | Pipeline 配置文件路径,如 `examples/pipeline.yaml` | | `--log_level` | 日志级别,默认 `INFO` | *** ## run — 执行 Pipeline **用途**:启动 Pipeline 执行。 ```bash theme={null} ultrarag run [--param ] [--is_demo] [--log_level DEBUG|INFO|WARN|ERROR] ``` | 参数 | 描述 | | ---------------------- | ------------------------------- | | `` | 待执行的 `pipeline.yaml` 路径 | | `--param ` | 自定义参数文件路径,覆盖默认 `parameter/` 下文件 | | `--is_demo` | 启用演示模式 | | `--log_level` | 日志级别,默认 `INFO` | *** ## show ui — 启动 Web 控制界面 **用途**: 启动UI界面。 ```bash theme={null} ultrarag show ui [--host 127.0.0.1] [--port 5050] [--admin] [--log_level DEBUG|INFO|WARN|ERROR] ``` | 参数 | 描述 | | ------------- | ---------------------------------------- | | `--host` | 网页服务绑定 IP(默认 `127.0.0.1`) | | `--port` | 网页服务端口(默认 `5050`) | | `--admin` | 启动完整管理员 UI(含 Pipeline 构建器),默认仅启动 Chat 模式 | | `--log_level` | 日志级别,默认 `INFO` | 启动后访问 `http://:` 即可使用 UI。 # Corpus Source: https://ultrarag.openbmb.cn/pages/cn/api/corpus ## `build_text_corpus` **签名** ```python theme={null} @app.tool(output="parse_file_path,text_corpus_save_path->None") async def build_text_corpus(parse_file_path: str, text_corpus_save_path: str) -> None ``` **功能** * 支持 .txt / .md; * 支持 .docx(读取段落与表格内容); * 支持 .pdf / .xps / .oxps / .epub / .mobi / .fb2(经 pymupdf 纯文本抽取)。 * 目录模式下会递归处理。 **输出格式(JSONL)** ```json theme={null} {"id": "", "title": "", "contents": "<全文文本>"} ``` *** ## `build_image_corpus` **签名** ```python theme={null} @app.tool(output="parse_file_path,image_corpus_save_path->None") async def build_image_corpus(parse_file_path: str, image_corpus_save_path: str) -> None ``` **功能** * **仅支持 PDF**:以 144DPI 渲染每页为 JPG(RGB),并校验文件有效性。 * 目录模式下会递归处理。 **输出索引(JSONL)** ```json theme={null} {"id": 0, "image_id": "paper/page_0.jpg", "image_path": "image/paper/page_0.jpg"} ``` *** ## `mineru_parse` **签名** ```python theme={null} @app.tool(output="parse_file_path,mineru_dir,mineru_extra_params->None") async def mineru_parse( parse_file_path: str, mineru_dir: str, mineru_extra_params: Optional[Dict[str, Any]] = None ) -> None ``` **功能** * 调用 CLI `mineru` 对 PDF/目录进行结构化解析,输出到 `mineru_dir`。 *** ## `build_mineru_corpus` **签名** ```python theme={null} @app.tool(output="mineru_dir,parse_file_path,text_corpus_save_path,image_corpus_save_path->None") async def build_mineru_corpus( mineru_dir: str, parse_file_path: str, text_corpus_save_path: str, image_corpus_save_path: str ) -> None ``` **功能** * 汇总 MinerU 解析产物为 **文本语料 JSONL** 与 **图片索引 JSONL**。 **输出格式(JSONL)** * 文本: ```json theme={null} {"id": "", "title": "", "contents": ""} ``` * 图片: ```json theme={null} {"id": 0, "image_id": "paper/page_0.jpg", "image_path": "images/paper/page_0.jpg"} ``` *** ## `chunk_documents` **签名** ```python theme={null} @app.tool(output="raw_chunk_path,chunk_backend_configs,chunk_backend,tokenizer_or_token_counter,chunk_size,chunk_path,use_title->None") async def chunk_documents( raw_chunk_path: str, chunk_backend_configs: Dict[str, Any], chunk_backend: str = "token", tokenizer_or_token_counter: str = "character", chunk_size: int = 256, chunk_path: Optional[str] = None, use_title: bool = True, ) -> None ``` **功能** * 将输入文本语料(JSONL,含 `id/title/contents`)按所选后端切分为段落块: * Chunk Backend: 支持 `token` / `sentence` / `recursive`。 * Tokenizer: tokenizer\_or\_token\_counter 可选 `word`、`character` 或 `tiktoken` 编码名称(如 `gpt2`)。 * Chunk Size: 通过 `chunk_size` 控制块大小(overlap 默认为 size/4)。 * 可选在每个块首部附加文档标题(`use_title`)。 **输出格式(JSONL)** ```json theme={null} {"id": 0, "doc_id": "paper", "title": "paper", "contents": "切块后的文本"} ``` *** ## 参数配置 ```yaml servers/corpus/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # servers/corpus/parameter.yaml parse_file_path: data/UltraRAG.pdf text_corpus_save_path: corpora/text.jsonl image_corpus_save_path: corpora/image.jsonl # mineru mineru_dir: corpora/ mineru_extra_params: source: modelscope # chunking parameters raw_chunk_path: corpora/text.jsonl chunk_path: corpora/chunks.jsonl use_title: false chunk_backend: sentence # choices=["token", "sentence", "recursive"] tokenizer_or_token_counter: character chunk_size: 512 chunk_backend_configs: token: chunk_overlap: 50 sentence: chunk_overlap: 50 min_sentences_per_chunk: 1 delim: "['.', '!', '?', ';', '。', '!', '?', '\\n']" recursive: min_characters_per_chunk: 12 ``` 参数说明: | 参数 | 类型 | 说明 | | ---------------------------- | ---- | ---------------------------------------------------------- | | `parse_file_path` | str | 输入文件或目录路径 | | `text_corpus_save_path` | str | 文本语料输出路径(JSONL) | | `image_corpus_save_path` | str | 图片语料索引输出路径(JSONL) | | `mineru_dir` | str | MinerU 输出根目录 | | `mineru_extra_params` | dict | MinerU 额外参数,如 `source`、`layout` 等 | | `raw_chunk_path` | str | 切块输入文件路径(JSONL 格式) | | `chunk_path` | str | 切块输出路径 | | `use_title` | bool | 是否在每个切块开头附加文档标题 | | `chunk_backend` | str | 选择切块方式:`token`、`sentence`、`recursive` | | `tokenizer_or_token_counter` | str | 分词器或计数方式。可选:`word`, `character` 或 `tiktoken` 模型名(如 `gpt2`) | | `chunk_size` | int | 每个切块的目标大小 | | `chunk_backend_configs` | dict | 各切块方法的配置项(见下) | `chunk_backend_configs` 详细参数: | 后端类型 | 参数 | 说明 | | ------------- | -------------------------- | ------------------------- | | **token** | `chunk_overlap` | 块间重叠 token 数 | | **sentence** | `chunk_overlap` | 块间重叠数 | | | `min_sentences_per_chunk` | 每个切块包含的最少句子数 | | | `delim` | 句子分隔符列表(字符串形式的 Python 列表) | | **recursive** | `min_characters_per_chunk` | 递归切分时的最小字符单元 | # Custom Source: https://ultrarag.openbmb.cn/pages/cn/api/custom ## Search-R1 Tools ### `search_r1_query_extract` ```python theme={null} @app.tool(output="ans_ls->extract_query_list") def search_r1_query_extract(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:从模型回答中提取查询内容。 * **逻辑**:使用正则 `r"([^<]*)"` 提取最后一个 `` 标签内的内容。如果未找到,返回 "There is no query.";如果查询未以 `?` 结尾,自动补全。 ### `r1_searcher_query_extract` ```python theme={null} @app.tool(output="ans_ls->extract_query_list") def r1_searcher_query_extract(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:从 R1-Searcher 回答中提取查询。 * **逻辑**:使用正则 `r"<|begin_of_query|>([^<]*)"` 提取最后一个标签内容。 *** ## IRCoT & IterRetGen Tools ### `iterretgen_nextquery` ```python theme={null} @app.tool(output="q_ls,ret_psg->nextq_ls") def iterretgen_nextquery(q_ls: List[str], ans_ls: List[str | Any]) -> Dict[str, List[str]] ``` * **功能**:迭代检索生成。 * **逻辑**:`next_query = f"{q} {ans}"`。将原始问题与生成的回答拼接作为下一次检索的 Query。 ### `ircot_get_first_sent` ```python theme={null} @app.tool(output="ans_ls->q_ls") def ircot_get_first_sent(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:提取回答的第一句话(至句号或问号/感叹号结束)。 ### `ircot_extract_ans` ```python theme={null} @app.tool(output="ans_ls->pred_ls") def ircot_extract_ans(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:提取最终答案。 * **逻辑**:匹配 `so the answer is [...]` 后的内容。 *** ## Search-o1 Tools ### `search_o1_init_list` ```python theme={null} @app.tool(output="q_ls->total_subq_list,total_reason_list,total_final_info_list") def search_o1_init_list(q_ls: List[str]) -> Dict[str, List[Any]] ``` * **功能**:初始化 Search-o1 所需的累加列表(子问题、推理、最终信息),初始填充 ``。 ### `search_o1_combine_list` ```python theme={null} @app.tool(output="total_subq_list, extract_query_list, total_reason_list, extract_reason_list->total_subq_list, total_reason_list") def search_o1_combine_list(...) ``` * **功能**:将当前步骤提取的 Query 和 Reasoning 追加到总列表中。 ### `search_o1_query_extract` ```python theme={null} @app.tool(output="ans_ls->extract_query_list") def search_o1_query_extract(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:提取 `<|begin_search_query|>...<|end_search_query|>` 之间的内容。 ### `search_o1_reasoning_extract` ```python theme={null} @app.tool(output="ans_ls->extract_reason_list") def search_o1_reasoning_extract(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:提取 `<|begin_search_query|>` 之前的所有文本作为推理过程。 ### `search_o1_extract_final_information` ```python theme={null} @app.tool(output="ans_ls->extract_final_infor_list") def search_o1_extract_final_information(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:提取 `**Final Information**` 标记之后的内容。 *** ## Utility Tools ### `output_extract_from_boxed` ```python theme={null} @app.tool(output="ans_ls->pred_ls") def output_extract_from_boxed(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:从 LaTeX `\boxed{...}` 中提取答案。支持嵌套括号处理和格式清理。 ### `merge_passages` ```python theme={null} @app.tool(output="temp_psg,ret_psg->ret_psg") def merge_passages(temp_psg: List[str | Any], ret_psg: List[str | Any]) -> Dict[str, List[str | Any]] ``` * **功能**:将 `temp_psg` 列表追加到 `ret_psg` 列表中。 ### `evisrag_output_extract_from_special` ```python theme={null} @app.tool(output="ans_ls->pred_ls") def evisrag_output_extract_from_special(ans_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:从 `...` 标签提取答案。 ### `assign_citation_ids` / `assign_citation_ids_stateful` * `assign_citation_ids`: 为检索到的段落分配 `[1]`, `[2]` 形式的引用 ID。 * `assign_citation_ids_stateful`: 使用 `CitationRegistry` 类维护全局引用 ID(跨步骤去重)。 * `init_citation_registry`: 重置全局引用注册表。 *** ## SurveyCPM Tools ### `surveycpm_state_init` ```python theme={null} @app.tool(output="instruction_ls->state_ls,cursor_ls,survey_ls,step_ls,extend_time_ls,extend_result_ls,retrieved_info_ls,parsed_ls") def surveycpm_state_init(instruction_ls: List[str]) -> Dict[str, List] ``` * **功能**:初始化 SurveyCPM 状态机。 * **初始状态**:`state="search"`, `cursor="outline"`, `step=0`。 ### `surveycpm_parse_search_response` ```python theme={null} @app.tool(output="response_ls,surveycpm_hard_mode->keywords_ls,parsed_ls") def surveycpm_parse_search_response(response_ls: List[str], surveycpm_hard_mode: bool = True) -> Dict[str, List] ``` * **功能**:解析模型生成的搜索指令(JSON 或 XML 格式),提取关键词列表。 ### `surveycpm_process_passages` ```python theme={null} @app.tool(output="ret_psg_ls->retrieved_info_ls") def surveycpm_process_passages(ret_psg_ls: List[List[List[str]]]) -> Dict[str, List[str]] ``` * **功能**:处理检索段落,去重并限制数量(Top-K),拼接为字符串。 ### `surveycpm_after_init_plan` / `after_write` / `after_extend` * **功能**:解析 Agent 对不同阶段(初始化大纲、撰写内容、扩展计划)的响应。 * **逻辑**: * 调用 `surveycpm_parse_response` 验证格式和内容。 * 成功则更新 `survey_ls`(大纲结构)和 `cursor_ls`(当前光标位置)。 * 失败则保留原状态以便重试。 ### `surveycpm_update_state` ```python theme={null} @app.tool(output="state_ls,cursor_ls,extend_time_ls,extend_result_ls,step_ls,parsed_ls,surveycpm_max_step,surveycpm_max_extend_step->state_ls,extend_time_ls,step_ls") def surveycpm_update_state(...) ``` * **功能**:核心状态机逻辑。 * **状态转移**: * `search` -> `analyst-init_plan` (cursor="outline") * `search` -> `write` (cursor=section-X) * `write` -> `search` (继续写) 或 `analyst-extend_plan` (写完当前部分) * `analyst-extend_plan` -> `search` (扩展成功) 或 `done` (无扩展) * 超出最大步数 -> `done` ### `surveycpm_format_output` ```python theme={null} @app.tool(output="survey_ls,instruction_ls->ans_ls") def surveycpm_format_output(survey_ls: List[str], instruction_ls: List[str]) -> Dict[str, List[str]] ``` * **功能**:将最终的 Survey JSON 转换为 Markdown 格式。 * **处理**:自动处理标题层级(# ## ###)、引用格式化(`\cite{...}` 转 `[1]`)和文本清理。 *** ## 参数配置 ```yaml servers/custom/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} surveycpm_hard_mode: false surveycpm_max_step: 140 surveycpm_max_extend_step: 12 ``` | 参数 | 类型 | 说明 | | --------------------------- | ---- | ------------------------------------- | | `surveycpm_hard_mode` | bool | 是否启用 SurveyCPM 的严格解析模式(验证 JSON 字段完整性) | | `surveycpm_max_step` | int | 最大总执行步数,超过强制结束 | | `surveycpm_max_extend_step` | int | 最大扩展计划次数 | # Evaluation Source: https://ultrarag.openbmb.cn/pages/cn/api/evaluation ## `evaluate` **签名** ```python theme={null} @app.tool(output="pred_ls,gt_ls,metrics,save_path->eval_res") def evaluate( pred_ls: List[str], gt_ls: List[List[str]], metrics: List[str] | None, save_path: str, ) -> Dict[str, Any] ``` **功能** * 执行问答/生成类任务的自动指标评估。 * 支持指标:`acc`、`em`、`coverem`、`stringem`、`f1`、`rouge-1`、`rouge-2`、`rouge-l`。 * 结果自动保存为 `.json` 文件,并以 Markdown 表格形式打印。 *** ## `evaluate_trec` **签名** ```python theme={null} @app.tool(output="run_path,qrels_path,ir_metrics,ks,save_path->eval_res") def evaluate_trec( run_path: str, qrels_path: str, metrics: List[str] | None, ks: List[int] | None, save_path: str, ) ``` **功能** * 基于 `pytrec_eval` 进行 IR 检索指标评估。 * 读取标准 TREC 格式: * **qrels**:` ` * **run**:` Q0 ` * 支持指标:`mrr`、`map`、`recall@k`、`precision@k`、`ndcg@k`。 * 自动统计聚合结果并以表格输出。 *** ## `evaluate_trec_pvalue` **签名** ```python theme={null} @app.tool( output="run_new_path,run_old_path,qrels_path,ir_metrics,ks,n_resamples,save_path->eval_res" ) def evaluate_trec_pvalue( run_new_path: str, run_old_path: str, qrels_path: str, metrics: List[str] | None, ks: List[int] | None, n_resamples: int | None, save_path: str, ) ``` **功能** * 对两个 TREC 结果文件进行显著性比较,采用**双尾置换检验**计算 p-value。 * 默认重采样次数 `n_resamples=10000`。 * 输出均值、差异、p 值及显著性标识。 *** ## 参数配置 ```yaml servers/evaluation/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} save_path: output/evaluate_results.json # QA task metrics: [ 'acc', 'f1', 'em', 'coverem', 'stringem', 'rouge-1', 'rouge-2', 'rouge-l' ] # Retrieval task qrels_path: data/qrels.txt run_path: data/run_a.txt ks: [ 1, 5, 10, 20, 50, 100 ] ir_metrics: [ "mrr", "map", "recall", "ndcg", "precision" ] # significant run_new_path: data/run_a.txt run_old_path: data/run_b.txt n_resamples: 10000 ``` 参数说明: | 参数 | 类型 | 说明 | | -------------- | ---------- | ------------------------------------------------------- | | `save_path` | str | 评估结果保存路径(将自动附带时间戳) | | `metrics` | list\[str] | QA / 生成任务使用的指标集合 | | `qrels_path` | str | TREC 格式真值文件路径 | | `run_path` | str | 检索任务的结果文件 | | `ks` | list\[int] | 截断层级,用于计算 NDCG\@K、P\@K、Recall\@K 等 | | `ir_metrics` | list\[str] | 检索任务指标名称,支持 `mrr`, `map`, `recall`, `ndcg`, `precision` | | `run_new_path` | str | 新模型生成的 run 文件路径(显著性分析) | | `run_old_path` | str | 旧模型的 run 文件路径(显著性分析) | | `n_resamples` | int | 置换检验(Permutation Test)重采样次数 | # Generation Source: https://ultrarag.openbmb.cn/pages/cn/api/generation ## `generation_init` **签名** ```python theme={null} def generation_init( backend_configs: Dict[str, Any], sampling_params: Dict[str, Any], extra_params: Optional[Dict[str, Any]] = None, backend: str = "vllm", ) -> None ``` **功能** * 初始化推理后端与采样参数。 * 支持 `vllm`, `openai`, `hf` 三种后端。 * `extra_params` 可用于传递 `chat_template_kwargs` 或其他特定后端的参数。 *** ## `generate` **签名** ```python theme={null} async def generate( prompt_ls: List[Union[str, Dict[str, Any]]], system_prompt: str = "", ) -> Dict[str, List[str]] ``` **功能** * 纯文本对话生成。 * 自动处理列表中的 Prompt,支持字符串或 OpenAI 格式的字典。 **输出格式(JSON)** ```json theme={null} {"ans_ls": ["answer for prompt_0", "answer for prompt_1", "..."]} ``` *** ## `multimodal_generate` **签名** ```python theme={null} async def multimodal_generate( multimodal_path: List[List[str]], prompt_ls: List[Union[str, Dict[str, Any]]], system_prompt: str = "", image_tag: Optional[str] = None, ) -> Dict[str, List[str]] ``` **功能** * 文图多模态对话生成。 * `multimodal_path`: 对应每个 Prompt 的图片路径列表(支持本地路径或 URL)。 * `image_tag`: 如果指定(如 ``),则将图片插入到 Prompt 中该标签的位置;否则默认追加到 Prompt 末尾。 **输出格式(JSON)** ```json theme={null} {"ans_ls": ["answer with images for prompt_0", "..."]} ``` *** ## `multiturn_generate` **签名** ```python theme={null} async def multiturn_generate( messages: List[Dict[str, str]], system_prompt: str = "", ) -> Dict[str, List[str]] ``` **功能** * 多轮对话生成。 * 仅支持单次调用的生成,不处理批量 Prompt。 **输出格式(JSON)** ```json theme={null} {"ans_ls": ["assistant response"]} ``` *** ## `vllm_shutdown` **签名** ```python theme={null} def vllm_shutdown() -> None ``` **功能** * 显式关闭 vLLM 引擎并释放显存资源。 * 仅在使用 `vllm` 后端时有效。 *** ## 参数配置 ```yaml servers/generation/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # servers/generation/parameter.yaml backend: vllm # options: vllm, openai backend_configs: vllm: model_name_or_path: openbmb/MiniCPM4-8B gpu_ids: "2,3" gpu_memory_utilization: 0.9 dtype: auto trust_remote_code: true openai: model_name: MiniCPM4-8B base_url: http://localhost:8000/v1 api_key: "abc" concurrency: 8 retries: 3 base_delay: 1.0 hf: model_name_or_path: openbmb/MiniCPM4-8B gpu_ids: '2,3' trust_remote_code: true batch_size: 8 sampling_params: temperature: 0.7 top_p: 0.8 max_tokens: 2048 extra_params: chat_template_kwargs: enable_thinking: false system_prompt: "" image_tag: null ``` 参数说明: | 参数 | 类型 | 说明 | | ----------------- | ---- | ---------------------------------------------- | | `backend` | str | 指定生成后端,可选 `vllm`、`openai` 或 `hf`(Transformers) | | `backend_configs` | dict | 各后端模型及运行环境配置 | | `sampling_params` | dict | 采样参数,用于控制生成多样性与长度 | | `extra_params` | dict | 额外参数,如 `chat_template_kwargs` | | `system_prompt` | str | 全局系统提示,将作为 `system` 消息加入上下文 | | `image_tag` | str | 图像占位符标签(如需) | `backend_configs` 详细说明: | 后端 | 参数 | 说明 | | ---------- | ------------------------ | ------------------------- | | **vllm** | `model_name_or_path` | 模型名称或路径 | | | `gpu_ids` | 使用的 GPU ID(如 `"0,1"`) | | | `gpu_memory_utilization` | GPU 显存占用比例(0–1) | | | `dtype` | 数据类型(如 `auto`、`bfloat16`) | | | `trust_remote_code` | 是否信任远程代码 | | **openai** | `model_name` | OpenAI 模型名称或自建兼容模型 | | | `base_url` | API 接口地址 | | | `api_key` | API 密钥 | | | `concurrency` | 最大并发请求数 | | | `retries` | API 重试次数 | | | `base_delay` | 每次重试基础等待时间(秒) | | **hf** | `model_name_or_path` | Transformers 模型路径 | | | `gpu_ids` | GPU ID(同上) | | | `trust_remote_code` | 是否信任远程代码 | | | `batch_size` | 每次推理批量大小 | `sampling_params` 详细说明: | 参数 | 类型 | 说明 | | ------------- | ----- | ------------------- | | `temperature` | float | 控制随机性,越高生成越多样 | | `top_p` | float | nucleus sampling 阈值 | | `max_tokens` | int | 生成最大词元数 | # Prompt Source: https://ultrarag.openbmb.cn/pages/cn/api/prompt ## QA Prompts ### `qa_boxed` **签名** ```python theme={null} @app.prompt(output="q_ls,template->prompt_ls") def qa_boxed( q_ls: List[str], template: str | Path ) -> List[PromptMessage] ``` **功能** 基础问答 Prompt。 加载指定 Jinja2 模板,将问题列表中的每个问题渲染为 Prompt。 模板变量: `{{ question }}` ### `qa_boxed_multiple_choice` **签名** ```python theme={null} @app.prompt(output="q_ls,choices_ls,template->prompt_ls") def qa_boxed_multiple_choice( q_ls: List[str], choices_ls: List[List[str]], template: str | Path, ) -> List[PromptMessage] ``` **功能** 多选问答 Prompt。 自动将选项列表格式化为 "A: ..., B: ..." 的形式并注入模板。 模板变量: `{{ question }}`, `{{ choices }}` ### `qa_rag_boxed` **签名** ```python theme={null} @app.prompt(output="q_ls,ret_psg,template->prompt_ls") def qa_rag_boxed( q_ls: List[str], ret_psg: List[str | Any], template: str | Path ) -> list[PromptMessage] ``` **功能** 标准 RAG Prompt。 将检索到的段落列表拼接后注入模板。 模板变量: `{{ question }}`, `{{ documents }}` ### `qa_rag_boxed_multiple_choice` **签名** ```python theme={null} @app.prompt(output="q_ls,choices_ls,ret_psg,template->prompt_ls") def qa_rag_boxed_multiple_choice( q_ls: List[str], choices_ls: List[List[str]], ret_psg: List[List[str]], template: str | Path, ) -> List[PromptMessage] ``` **功能** 带检索上下文的多选问答 Prompt。 模板变量: `{{ question }}`, `{{ documents }}`, `{{ choices }}` *** ## RankCoT Prompts ### `RankCoT_kr` **签名** ```python theme={null} @app.prompt(output="q_ls,ret_psg,kr_template->prompt_ls") def RankCoT_kr( q_ls: List[str], ret_psg: List[str | Any], template: str | Path, ) -> list[PromptMessage] ``` **功能** RankCoT 第一阶段:知识检索 (Knowledge Retrieval) Prompt。 模板变量: `{{ question }}`, `{{ documents }}` ### `RankCoT_qa` **签名** ```python theme={null} @app.prompt(output="q_ls,kr_ls,qa_template->prompt_ls") def RankCoT_qa( q_ls: List[str], kr_ls: List[str], template: str | Path, ) -> list[PromptMessage] ``` **功能** RankCoT 第二阶段:基于思维链的问答 Prompt。 模板变量: `{{ question }}`, `{{ CoT }}` (此处 CoT 通常为上一阶段生成的知识) *** ## IRCoT Prompts ### `ircot_next_prompt` **签名** ```python theme={null} @app.prompt(output="memory_q_ls,memory_ret_psg,template->prompt_ls") def ircot_next_prompt( memory_q_ls: List[List[str | None]], memory_ret_psg: List[List[List[str]] | None], template: str | Path, ) -> List[PromptMessage] ``` **功能** IRCoT (Interleaved Retrieval CoT) 迭代 Prompt 生成。 根据历史轮次的检索结果和思维链,构建下一轮的 Prompt。支持单轮与多轮历史拼接。 模板变量: `{{ documents }}`, `{{ question }}`, `{{ cur_answer }}` *** ## WebNote Prompts ### `webnote_init_page` **签名** ```python theme={null} @app.prompt(output="q_ls,plan_ls,webnote_init_page_template->prompt_ls") def webnote_init_page( q_ls: List[str], plan_ls: List[str], template: str | Path, ) -> List[PromptMessage] ``` **功能** WebNote Agent:初始化笔记页面。 模板变量: `{{ question }}`, `{{ plan }}` ### `webnote_gen_plan` **签名** ```python theme={null} @app.prompt(output="q_ls,webnote_gen_plan_template->prompt_ls") def webnote_gen_plan( q_ls: List[str], template: str | Path, ) -> List[PromptMessage] ``` **功能** WebNote Agent:生成搜索计划。 模板变量: `{{ question }}` ### `webnote_gen_subq` **签名** ```python theme={null} @app.prompt(output="q_ls,plan_ls,page_ls,webnote_gen_subq_template->prompt_ls") def webnote_gen_subq( q_ls: List[str], plan_ls: List[str], page_ls: List[str], template: str | Path, ) -> List[PromptMessage] ``` **功能** WebNote Agent:生成子问题。 模板变量: `{{ question }}`, `{{ plan }}`, `{{ page }}` ### `webnote_fill_page` **签名** ```python theme={null} @app.prompt(output="q_ls,plan_ls,page_ls,subq_ls,psg_ls,webnote_fill_page_template->prompt_ls") def webnote_fill_page( q_ls: List[str], plan_ls: List[str], page_ls: List[str], subq_ls: List[str], psg_ls: List[Any], template: str | Path, ) -> List[PromptMessage] ``` **功能** WebNote Agent:根据检索结果填充笔记。 模板变量: `{{ question }}`, `{{ plan }}`, `{{ sub_question }}`, `{{ docs_text }}`, `{{ page }}` ### `webnote_gen_answer` **签名** ```python theme={null} @app.prompt(output="q_ls,page_ls,webnote_gen_answer_template->prompt_ls") def webnote_gen_answer( q_ls: List[str], page_ls: List[str], template: str | Path, ) -> List[PromptMessage] ``` **功能** WebNote Agent:基于笔记生成最终答案。 模板变量: `{{ question }}`, `{{ page }}` *** ## Search-R1 & R1-Searcher ### `search_r1_gen` **签名** ```python theme={null} @app.prompt(output="prompt_ls,ans_ls,ret_psg,search_r1_gen_template->prompt_ls") def search_r1_gen( prompt_ls: List[PromptMessage], ans_ls: List[str], ret_psg: List[str | Any], template: str | Path, ) -> List[PromptMessage] ``` **功能** 适用于 R1 风格的生成 Prompt。 截取 Top-3 检索段落注入上下文。 模板变量: `{{ history }}`, `{{ answer }}`, `{{ passages }}` ### `r1_searcher_gen` **签名** ```python theme={null} @app.prompt(output="prompt_ls,ans_ls,ret_psg,r1_searcher_gen_template->prompt_ls") def r1_searcher_gen( prompt_ls: List[PromptMessage], ans_ls: List[str], ret_psg: List[str | Any], template: str | Path, ) -> List[PromptMessage] ``` **功能** 适用于 R1 Searcher 的生成 Prompt。 截取 Top-5 检索段落。 模板变量: `{{ history }}`, `{{ answer }}`, `{{ passages }}` *** ## Search-o1 Prompts ### `search_o1_init` **签名** ```python theme={null} @app.prompt(output="q_ls,searcho1_reasoning_template->prompt_ls") def search_o1_init( q_ls: List[str], template: str | Path, ) -> List[PromptMessage] ``` **功能** Search-O1 初始推理 Prompt。 模板变量: `{{ question }}` ### `search_o1_reasoning_indocument` **签名** ```python theme={null} @app.prompt(output="extract_query_list,ret_psg,total_reason_list,searcho1_refine_template->prompt_ls") def search_o1_reasoning_indocument( extract_query_list: List[str], ret_psg: List[List[str]], total_reason_list: List[List[str]], template: str | Path, ) -> List[PromptMessage] ``` **功能** Search-O1 推理细化 Prompt。 将历史推理步骤(首步 + 末尾3步)与当前检索文档合并,用于下一步推理。 模板变量: `{{ prev_reasoning }}`, `{{ search_query }}`, `{{ document }}` ### `search_o1_insert` **签名** ```python theme={null} @app.prompt(output="q_ls,total_subq_list,total_final_info_list,searcho1_reasoning_template->prompt_ls") def search_o1_insert( q_ls: List[str], total_subq_list: List[List[str]], total_final_info_list: List[List[str]], template: str | Path, ) -> List[PromptMessage] ``` **功能** Search-O1 格式化插入 Prompt。 在 Prompt 中显式插入 `<|begin_search_query|>` 和搜索结果标记,构造完整的思维链上下文。 *** ## EVisRAG & Multi-branch Prompts ### `gen_subq` **签名** ```python theme={null} @app.prompt(output="q_ls,ret_psg,gen_subq_template->prompt_ls") def gen_subq( q_ls: List[str], ret_psg: List[str | Any], template: str | Path, ) -> List[PromptMessage] ``` **功能** Loop/Branch Demo:基于文档生成子问题。 模板变量: `{{ question }}`, `{{ documents }}` ### `evisrag_vqa` **签名** ```python theme={null} @app.prompt(output="q_ls,ret_psg,evisrag_template->prompt_ls") def evisrag_vqa( q_ls: List[str], ret_psg: List[str | Any], template: str | Path ) -> list[PromptMessage] ``` **功能** 多模态 VQA RAG Prompt。 根据检索到的图片数量,在 Prompt 中自动重复插入 `` Token。 模板变量: `{{ question }}` (含自动注入的 image tokens) *** ## SurveyCPM Prompts ### `surveycpm_search` **签名** ```python theme={null} @app.prompt(output="instruction_ls,survey_ls,cursor_ls,surveycpm_search_template->prompt_ls") def surveycpm_search( instruction_ls: List[str], survey_ls: List[str], cursor_ls: List[str | None], surveycpm_search_template: str | Path, ) -> List[PromptMessage] ``` **功能** Survey Agent:决定下一步搜索内容。 解析 JSON 格式的大纲,生成当前大纲的文本描述。 模板变量: `{{ user_query }}`, `{{ current_outline }}`, `{{ current_instruction }}` ### `surveycpm_init_plan` **签名** ```python theme={null} @app.prompt(output="instruction_ls,retrieved_info_ls,surveycpm_init_plan_template->prompt_ls") def surveycpm_init_plan( instruction_ls: List[str], retrieved_info_ls: List[str], surveycpm_init_plan_template: str | Path, ) -> List[PromptMessage] ``` **功能** Survey Agent:初始化大纲规划。 模板变量: `{{ user_query }}`, `{{ current_information }}` ### `surveycpm_write` **签名** ```python theme={null} @app.prompt(output="instruction_ls,survey_ls,cursor_ls,retrieved_info_ls,surveycpm_write_template->prompt_ls") def surveycpm_write( instruction_ls: List[str], survey_ls: List[str], cursor_ls: List[str | None], retrieved_info_ls: List[str], surveycpm_write_template: str | Path, ) -> List[PromptMessage] ``` **功能** Survey Agent:撰写具体章节内容。 模板变量: `{{ user_query }}`, `{{ current_survey }}`, `{{ current_instruction }}`, `{{ current_information }}` ### `surveycpm_extend_plan` **签名** ```python theme={null} @app.prompt(output="instruction_ls,survey_ls,surveycpm_extend_plan_template->prompt_ls") def surveycpm_extend_plan( instruction_ls: List[str], survey_ls: List[str], surveycpm_extend_plan_template: str | Path, ) -> List[PromptMessage] ``` **功能** Survey Agent:扩展或修改大纲计划。 模板变量: `{{ user_query }}`, `{{ current_survey }}` *** ## 参数配置 ```yaml servers/prompt/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # QA template: prompt/qa_boxed.jinja # RankCoT kr_template: prompt/RankCoT_knowledge_refinement.jinja qa_template: prompt/RankCoT_question_answering.jinja # Search-R1 search_r1_gen_template: prompt/search_r1_append.jinja # R1-Searcher r1_searcher_gen_template: prompt/r1_searcher_append.jinja # Search-o1 searcho1_reasoning_template: prompt/search_o1_reasoning.jinja searcho1_refine_template: prompt/search_o1_refinement.jinja # For other prompts, please add parameters here as needed # Take webnote as an example: webnote_gen_plan_template: prompt/webnote_gen_plan.jinja webnote_init_page_template: prompt/webnote_init_page.jinja webnote_gen_subq_template: prompt/webnote_gen_subq.jinja webnote_fill_page_template: prompt/webnote_fill_page.jinja webnote_gen_answer_template: prompt/webnote_gen_answer.jinja # SurveyCPM surveycpm_search_template: prompt/surveycpm_search.jinja surveycpm_init_plan_template: prompt/surveycpm_init_plan.jinja surveycpm_write_template: prompt/surveycpm_write.jinja surveycpm_extend_plan_template: prompt/surveycpm_extend_plan.jinja ``` | 参数 | 说明 | | ------------- | ---------------------- | | `template` | 基础 QA 模板路径 | | `kr_template` | RankCoT 知识精炼模板路径 | | `qa_template` | RankCoT 问答模板路径 | | `*_template` | 对应各模块功能的 Jinja2 模板文件路径 | # Reranker Source: https://ultrarag.openbmb.cn/pages/cn/api/reranker ## `reranker_init` **签名** ```python theme={null} async def reranker_init( model_name_or_path: str, backend_configs: Dict[str, Any], batch_size: int, gpu_ids: Optional[object] = None, backend: str = "infinity", ) -> None ``` **功能** * 初始化重排后端与模型 *** ## `reranker_rerank` **签名** ```python theme={null} async def reranker_rerank( query_list: List[str], passages_list: List[List[str]], top_k: int = 5, query_instruction: str = "", ) -> Dict[str, List[Any]] ``` **功能** * 对候选段落进行**重排**: **输出格式(JSON)** ```json theme={null} { "rerank_psg": [ ["best passage for q0", "..."], ["best passage for q1", "..."] ] } ``` *** ## 参数配置 ```yaml servers/reranker/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} model_name_or_path: openbmb/MiniCPM-Reranker-Light backend: sentence_transformers # options: infinity, sentence_transformers, openai backend_configs: infinity: bettertransformer: false pooling_method: auto device: cuda model_warmup: false trust_remote_code: true sentence_transformers: device: cuda trust_remote_code: true openai: model_name: text-embedding-3-small base_url: "https://api.openai.com/v1" api_key: "" gpu_ids: 0 top_k: 5 batch_size: 16 query_instruction: "" ``` 参数说明: | 参数 | 类型 | 说明 | | -------------------- | ------- | ---------------------------------------------------- | | `model_name_or_path` | str | 模型路径或名称(本地或 HuggingFace 仓库) | | `backend` | str | 选择后端类型:`infinity`、`sentence_transformers` 或 `openai` | | `backend_configs` | dict | 各后端的专属参数设置 | | `gpu_ids` | str/int | 指定 GPU ID(可多卡,如 `"0,1"`) | | `top_k` | int | 返回的重排结果数 | | `batch_size` | int | 每批处理的样本数量 | | `query_instruction` | str | 查询前缀提示,用于 prompt 工程或 query 修饰 | `backend_configs` 详细说明: | 后端 | 参数 | 说明 | | -------------------------- | ------------------- | -------------------------- | | **infinity** | `device` | 设备类型(cuda / cpu) | | | `bettertransformer` | 是否启用加速推理 | | | `pooling_method` | 向量池化策略 | | | `model_warmup` | 是否预热模型 | | | `trust_remote_code` | 是否信任远程代码(HuggingFace 模型必需) | | **sentence\_transformers** | `device` | 设备类型(cuda / cpu) | | | `trust_remote_code` | 是否信任远程代码 | | **openai** | `model_name` | API 模型名称 | | | `base_url` | API 访问地址 | | | `api_key` | OpenAI API 密钥 | # Retriever Source: https://ultrarag.openbmb.cn/pages/cn/api/retriever ## `retriever_init` **签名** ```python theme={null} async def retriever_init( model_name_or_path: str, backend_configs: Dict[str, Any], batch_size: int, corpus_path: str, gpu_ids: Optional[object] = None, is_multimodal: bool = False, backend: str = "sentence_transformers", index_backend: str = "faiss", index_backend_configs: Optional[Dict[str, Any]] = None, is_demo: bool = False, collection_name: str = "", ) -> None ``` **功能** * 初始化检索服务。 * Embedding Backend (backend): 负责将文本/图像转换为向量 (Infinity, SentenceTransformers, OpenAI, BM25)。 * Index Backend (index\_backend): 负责向量的存储与检索 (FAISS, Milvus)。 * Demo Mode: 若 is\_demo=True,强制使用 OpenAI + Milvus 配置,忽略部分参数。 *** ## `retriever_embed` **签名** ```python theme={null} async def retriever_embed( embedding_path: Optional[str] = None, overwrite: bool = False, is_multimodal: bool = False, ) -> None ``` **功能** * (非 Demo 模式) 批量计算语料库的向量表示,并保存为 .npy 文件。 * 仅适用于 Dense Retriever 后端(BM25 不支持)。 *** ## `retriever_index` **签名** ```python theme={null} async def retriever_index( embedding_path: str, overwrite: bool = False, collection_name: str = "", corpus_path: str = "" ) -> None ``` **功能** * 构建检索索引。 * FAISS: 读取 embedding\_path (.npy) 构建本地索引文件。 * Milvus / Demo: 读取 corpus\_path (.jsonl),生成向量并插入到指定的 collection\_name 中。 *** ## `retriever_search` **签名** ```python theme={null} async def retriever_search( query_list: List[str], top_k: int = 5, query_instruction: str = "", collection_name: str = "", ) -> Dict[str, List[List[str]]] ``` **功能** * 对单条或多条查询进行检索。 * 自动处理查询向量化(添加 query\_instruction)并在指定 collection\_name (针对 Milvus) 或默认索引中查找 Top-K。 **输出格式(JSON)** ```json theme={null} {"ret_psg": [["passage 1", "passage 2"], ["..." ]]} ``` *** ## `retriever_batch_search` **签名** ```python theme={null} async def retriever_batch_search( batch_query_list: List[List[str]], top_k: int = 5, query_instruction: str = "", collection_name: str = "", ) -> Dict[str, List[List[List[str]]]] ``` **功能** * etriever\_search 的批处理版本,接受嵌套列表输入。 **输出格式(JSON)** ```json theme={null} {"ret_psg_ls": [[["psg 1-1"], ["psg 1-2"]], [["psg 2-1"]]]} ``` *** ## `bm25_index` **签名** ```python theme={null} async def bm25_index( overwrite: bool = False, ) -> None ``` **功能** * 当 `backend="bm25"` 时,构建 BM25 稀疏索引并保存。 *** ## `bm25_search` **签名** ```python theme={null} async def bm25_search( query_list: List[str], top_k: int = 5, ) -> Dict[str, List[List[str]]] ``` **功能** * 基于 BM25 算法进行关键词检索。 **输出格式(JSON)** ```json theme={null} {"ret_psg": [["passage 1", "passage 2"], ["..." ]]} ``` *** ## `retriever_deploy_search` **签名** ```python theme={null} async def retriever_deploy_search( retriever_url: str, query_list: List[str], top_k: int = 5, query_instruction: str = "", ) -> Dict[str, List[List[str]]] ``` **功能** * 作为客户端,调用部署在 retriever\_url 的远程检索服务进行查询。 **输出格式(JSON)** ```json theme={null} {"ret_psg": [["passage 1", "passage 2"], ["..." ]]} ``` *** ## `retriever_exa_search` **签名** ```python theme={null} async def retriever_exa_search( query_list: List[str], top_k: Optional[int] | None = 5, retrieve_thread_num: Optional[int] | None = 1, ) -> Dict[str, List[List[str]]] ``` **功能** * 调用 **Exa** Web 检索(需要 `EXA_API_KEY`)。 **输出格式(JSON)** ```json theme={null} {"ret_psg": [["snippet 1", "snippet 2"], ["..." ]]} ``` *** ## `retriever_tavily_search` **签名** ```python theme={null} async def retriever_tavily_search( query_list: List[str], top_k: Optional[int] | None = 5, retrieve_thread_num: Optional[int] | None = 1, ) -> Dict[str, List[List[str]]] ``` **功能** * 调用 **Tavily** Web 检索(需要 `TAVILY_API_KEY`)。 **输出格式(JSON)** ```json theme={null} {"ret_psg": [["snippet 1", "snippet 2"], ["..." ]]} ``` *** ## `retriever_zhipuai_search` **签名** ```python theme={null} async def retriever_zhipuai_search( query_list: List[str], top_k: Optional[int] | None = 5, retrieve_thread_num: Optional[int] | None = 1, ) -> Dict[str, List[List[str]]] ``` **功能** * 调用 **智谱AI** `web_search`(需要 `ZHIPUAI_API_KEY`)。 **输出格式(JSON)** ```json theme={null} {"ret_psg": [["snippet 1", "snippet 2"], ["..." ]]} ``` *** ## 参数配置 ```yaml servers/retriever/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} model_name_or_path: openbmb/MiniCPM-Embedding-Light corpus_path: data/corpus_example.jsonl embedding_path: embedding/embedding.npy collection_name: wiki # Embedding Backend Configuration backend: sentence_transformers # options: infinity, sentence_transformers, openai, bm25 backend_configs: infinity: bettertransformer: false pooling_method: auto model_warmup: false trust_remote_code: true sentence_transformers: trust_remote_code: true sentence_transformers_encode: normalize_embeddings: false encode_chunk_size: 256 q_prompt_name: query psg_prompt_name: document psg_task: null q_task: null openai: model_name: text-embedding-3-small base_url: "https://api.openai.com/v1" api_key: "abc" bm25: lang: en save_path: index/bm25 # Index Backend Configuration index_backend: faiss # options: faiss, milvus index_backend_configs: faiss: index_use_gpu: True index_chunk_size: 10000 index_path: index/index.index milvus: uri: index/milvus_demo.db # Local file for Lite, or http://host:port token: null id_field_name: id vector_field_name: vector text_field_name: contents index_params: index_type: AUTOINDEX metric_type: IP batch_size: 16 top_k: 5 gpu_ids: "1" query_instruction: "" is_multimodal: false overwrite: false retrieve_thread_num: 1 retriever_url: "http://127.0.0.1:64501" is_demo: false ``` 参数说明: | 参数 | 类型 | 说明 | | ----------------------- | ---- | --------------------------------------------------------- | | `model_name_or_path` | str | 检索模型路径或名称(如 HuggingFace 模型 ID) | | `corpus_path` | str | 输入语料 JSONL 文件路径 | | `embedding_path` | str | 向量文件保存路径(`.npy`) | | `collection_name` | str | Milvus 集合名称 | | `backend` | str | 选择检索后端:`infinity`、`sentence_transformers`、`openai`、`bm25` | | `index_backend` | str | 索引后端:`faiss`, `milvus` | | `backend_configs` | dict | 各后端的参数配置(见下表) | | `index_backend_configs` | dict | 各索引后端的参数配置(见下表) | | `batch_size` | int | 向量生成或检索的批大小 | | `top_k` | int | 返回的候选段落数量 | | `gpu_ids` | str | 指定可见 GPU 设备,如 `"0,1"` | | `query_instruction` | str | 查询前缀(instruction-tuning 模型使用) | | `is_multimodal` | bool | 是否启用多模态嵌入(如图像) | | `overwrite` | bool | 若已存在嵌入或索引文件是否覆盖 | | `retrieve_thread_num` | int | 外部 Web 检索(Exa/Tavily/Zhipu)并发线程数 | | `retriever_url` | str | 部署 retriever server 的 url | | `is_demo` | bool | 演示模式开关(强制使用 OpenAI+Milvus,简化配置) | `backend_configs` 子项: | 后端 | 参数 | 类型 | 说明 | | -------------------------- | ------------------------------ | ---- | --------------------------------------- | | **infinity** | `bettertransformer` | bool | 是否启用高效推理优化 | | | `pooling_method` | str | 池化方式(如 `auto`, `mean`) | | | `model_warmup` | bool | 是否预加载模型到显存 | | | `trust_remote_code` | bool | 是否信任远程代码(适用于自定义模型) | | **sentence\_transformers** | `trust_remote_code` | bool | 是否信任远程模型代码 | | | `sentence_transformers_encode` | dict | 编码详细参数,见下表 | | **openai** | `model_name` | str | OpenAI 模型名称(如 `text-embedding-3-small`) | | | `base_url` | str | API 基地址 | | | `api_key` | str | OpenAI API 密钥 | | **bm25** | `lang` | str | 语言(决定停用词与分词器) | | | `save_path` | str | BM25 稀疏索引的保存目录 | `sentence_transformers_encode` 参数: | 参数 | 类型 | 说明 | | ---------------------- | ---- | ------------------------- | | `normalize_embeddings` | bool | 是否归一化向量 | | `encode_chunk_size` | int | 编码块大小(避免显存溢出) | | `q_prompt_name` | str | 查询模板名 | | `psg_prompt_name` | str | 段落模板名 | | `q_task` | str | 任务描述(针对特定模型需要指定 Task 的情况) | | `psg_task` | str | 任务描述(针对特定模型需要指定 Task 的情况) | `index_backend_configs` 参数: | 后端 | 参数 | 类型 | 说明 | | ------ | ------------------- | ---- | ---------------------------------- | | faiss | index\_use\_gpu | bool | 是否使用 GPU 构建和检索索引 | | | index\_chunk\_size | int | 构建索引时的分批大小 | | | index\_path | str | FAISS 索引文件的保存路径(.index) | | milvus | uri | str | Milvus 连接地址(本地文件路径即启用 Milvus Lite) | | | token | str | 认证 Token(如需要) | | | id\_field\_name | str | 主键字段名(默认 id) | | | vector\_field\_name | str | 向量字段名(默认 vector) | | | text\_field\_name | str | 文本内容字段名(默认 contents) | | | id\_max\_length | int | 字符串主键的最大长度 | | | text\_max\_length | int | 文本字段的最大长度(超过截断) | | | metric\_type | str | 距离度量方式(如 IP 内积, L2 欧式距离) | | | index\_params | Dict | 索引构建参数(如 index\_type: AUTOINDEX) | | | search\_params | Dict | 检索参数(如 nprobe 等) | | | index\_chunk\_size | int | 插入数据时的批处理大小 | # Router Source: https://ultrarag.openbmb.cn/pages/cn/api/router ## `route1` / `route2` **签名** ```python theme={null} @app.tool(output="query_list") def route1(query_list: List[str]) -> Dict[str, List[Dict[str, str]]] def route2(query_list: List[str]) -> Dict[str, List[Dict[str, str]]] ``` **功能** * 基础路由示例。 * `route1`: 如果查询内容为 "1",状态设为 "state1",否则 "state2"。 * `route2`: 强制状态设为 "state2"。 *** ## `ircot_check_end` **签名** ```python theme={null} @app.tool(output="ans_ls->ans_ls") def ircot_check_end(ans_ls: List[str]) -> Dict[str, List[Dict[str, str]]] ``` **功能** * IRCoT 流程检查。 * 检查回答中是否包含 `"so the answer is"`(忽略大小写)。 * 包含则标记状态为 `"complete"`,否则为 `"incomplete"`。 *** ## `search_r1_check` **签名** ```python theme={null} @app.tool(output="ans_ls->ans_ls") def search_r1_check(ans_ls: List[str]) -> Dict[str, List[Dict[str, str]]] ``` **功能** * 检查 Search-R1 生成是否结束。 * 依据:文本中包含 `<|endoftext|>` 或 `<|im_end|>`。 * 满足条件标记为 `"complete"`,否则 `"incomplete"`。 *** ## `webnote_check_page` **签名** ```python theme={null} @app.tool(output="page_ls->page_ls") def webnote_check_page(page_ls: List[str]) -> Dict[str, List[Dict[str, str]]] ``` **功能** * WebNote 流程检查。 * 若页面内容包含 `"to be filled"`(忽略大小写),标记为 `"incomplete"`,否则 `"complete"`。 *** ## `r1_searcher_check` **签名** ```python theme={null} @app.tool(output="ans_ls->ans_ls") def r1_searcher_check(ans_ls: List[str]) -> Dict[str, List[Dict[str, str]]] ``` **功能** * 检查 R1-Searcher 生成是否结束。 * 依据:文本中包含 `<|endoftext|>`、`<|im_end|>` 或 ``。 * 满足条件标记为 `"complete"`,否则 `"incomplete"`。 *** ## `search_o1_check` **签名** ```python theme={null} @app.tool(output="ans_ls,q_ls,total_subq_list,total_reason_list,total_final_info_list->ans_ls,q_ls,total_subq_list,total_reason_list,total_final_info_list") def search_o1_check( ans_ls: List[str], q_ls: List[str], total_subq_list: List[List[Any]], total_reason_list: List[List[Any]], total_final_info_list: List[List[Any]], ) -> Dict[str, List[Dict[str, Any]]] ``` **功能** * Search-o1 流程状态检查。 * 检查回答中的特殊标记: * 若包含 `<|end_search_query|>`:状态设为 `"retrieve"`(继续检索)。 * 若包含 `<|im_end|>` 或其他情况:状态设为 `"stop"`(停止检索,输出答案)。 * 将所有关联列表(`q_ls`, `subq`, `reason`, `info`)同步更新状态。 *** ## `check_model_state` **签名** ```python theme={null} @app.tool(output="ans_ls->ans_ls") def check_model_state(ans_ls: List[str]) -> Dict[str, List[Dict[str, str]]] ``` **功能** * 通用模型状态检查。 * 若回答中包含 `` 标签,标记状态为 `"continue"`,否则 `"stop"`。 *** ## `surveycpm_state_router` **签名** ```python theme={null} @app.tool(output="state_ls,cursor_ls,survey_ls,step_ls,extend_time_ls,extend_result_ls->state_ls,cursor_ls,survey_ls,step_ls,extend_time_ls,extend_result_ls") def surveycpm_state_router( state_ls: List[str], cursor_ls: List[str | None], survey_ls: List[str], step_ls: List[int], extend_time_ls: List[int], extend_result_ls: List[str], ) -> Dict[str, List[Dict[str, Any]]] ``` **功能** * SurveyCPM 专用路由。 * 这是一个 Pass-through 工具,它将所有输入的列表元素(状态、光标、大纲等)打包成带有 `"state"` 字段的字典。 * 目的:使 UltraRAG 框架能够根据 `state` 字段自动分发数据到对应的 Pipeline 分支。 # AgentCPM-Report Source: https://ultrarag.openbmb.cn/pages/cn/demo/deepresearch AgentCPM-Report 是一款由 [THUNLP](https://nlp.csai.tsinghua.edu.cn)、中国人民大学 [RUCBM](https://github.com/RUCBM) 和 [ModelBest](https://modelbest.cn/en) 联合研发的开源大语言模型智能体。 该模型基于 [MiniCPM4.1](https://github.com/OpenBMB/MiniCPM)(80亿参数)基座构建,能够接受用户指令,自主进行深度调研并生成长篇报告。 核心亮点: * **卓越的洞察力与全面性**:作为一款 8B 参数量的端侧模型,AgentCPM-Report 在深度调研报告生成任务上展现了惊人的潜力,其表现已赶超部分闭源商用智能体系统。它重新定义了小规模智能体的性能天花板,尤其在洞察力 (Insight) 指标上取得了 SOTA 结果。 * **轻量化与本地化部署**:模型支持在个人计算机上进行敏捷部署。通过结合 UltraRAG 等框架,用户可以构建规模化的本地知识库,生成比通用大模型更专业、更深入的报告。这种轻量级与本地化的特性,为处理隐私数据或私域数据的深度报告写作提供了安全可靠的基础。 本文档旨在介绍如何在 UltraRAG 框架中配置和使用 AgentCPM-Report。 为了获得最佳生成效果,我们强烈推荐下载并使用配套的专有模型 [AgentCPM-Report](https://huggingface.co/openbmb/AgentCPM-Report)。 ## 1. Pipeline 结构概览 AgentCPM-Report Pipeline 采用基于状态机(State Machine)的动态循环架构,系统在初始化后进入核心循环,由智能路由(Router)根据当前任务进展自主决策下一步行动——在信息搜集(Search)、初始规划(Analyst-Init)、内容撰写(Write)和计划扩展(Analyst-Extend)四个分支间灵活切换,通过不断的“检索-规划-写作”迭代,直至完成所有调研任务并输出最终的格式化报告。 ```yaml examples/AgentCPM-Report.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # AgentCPM-Report Demo for UltraRAG UI # MCP Server servers: benchmark: servers/benchmark generation: servers/generation retriever: servers/retriever prompt: servers/prompt router: servers/router custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data: output: q_ls: instruction_ls - retriever.retriever_init - generation.generation_init - custom.surveycpm_init_citation_registry - custom.surveycpm_state_init - loop: times: 140 steps: - branch: router: - router.surveycpm_state_router branches: search: - prompt.surveycpm_search: output: prompt_ls: search_prompt_ls - generation.generate: input: prompt_ls: search_prompt_ls output: ans_ls: search_response_ls - custom.surveycpm_parse_search_response: input: response_ls: search_response_ls - retriever.retriever_batch_search: input: batch_query_list: keywords_ls - custom.surveycpm_process_passages_with_citation - custom.surveycpm_update_state analyst-init_plan: - prompt.surveycpm_init_plan: output: prompt_ls: init_plan_prompt_ls - generation.generate: input: prompt_ls: init_plan_prompt_ls output: ans_ls: init_plan_response_ls - custom.surveycpm_after_init_plan: input: response_ls: init_plan_response_ls - custom.surveycpm_update_state write: - prompt.surveycpm_write: output: prompt_ls: write_prompt_ls - generation.generate: input: prompt_ls: write_prompt_ls output: ans_ls: write_response_ls - custom.surveycpm_after_write: input: response_ls: write_response_ls - custom.surveycpm_update_state analyst-extend_plan: - prompt.surveycpm_extend_plan: output: prompt_ls: extend_prompt_ls - generation.generate: input: prompt_ls: extend_prompt_ls output: ans_ls: extend_response_ls - custom.surveycpm_after_extend: input: response_ls: extend_response_ls - custom.surveycpm_update_state done: [] - custom.surveycpm_format_output: output: ans_ls: final_survey_ls ``` ## 2. 编译Pipeline文件 执行以下命令编译该工作流: ```shell theme={null} ultrarag build examples/AgentCPM-Report.yaml ``` ## 3. 配置运行参数 修改 `examples/parameter/AgentCPM-Report_parameter.yaml`。 想要调整调研深度? 请在 `custom` 配置中按需调整:增加 `surveycpm_max_step` 以延长研究时间,提高 `surveycpm_max_extend_step` 以获得更详实的扩写内容。若对质量有极高要求,请务必开启 `surveycpm_hard_mode`(硬核模式)。 ```yaml examples/parameter/AgentCPM-Report_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false custom: surveycpm_hard_mode: false # [!code --] surveycpm_hard_mode: true # [!code ++] surveycpm_max_extend_step: 12 surveycpm_max_step: 140 generation: backend: vllm # [!code --] backend: openai # [!code ++] backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/AgentCPM-Report trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 # [!code --] base_url: http://localhost:65506/v1 # [!code ++] concurrency: 8 model_name: MiniCPM4-8B # [!code --] model_name: AgentCPM-Report # [!code ++] retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/AgentCPM-Report trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' # [!code --] system_prompt: '你是一个专业的UltraRAG问答助手。请一定记住使用中文回答问题。' # [!code ++] prompt: surveycpm_extend_plan_template: prompt/surveycpm_extend_plan.jinja surveycpm_init_plan_template: prompt/surveycpm_init_plan.jinja surveycpm_search_template: prompt/surveycpm_search.jinja surveycpm_write_template: prompt/surveycpm_write.jinja retriever: backend: sentence_transformers # [!code --] backend: openai # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 # [!code --] base_url: http://localhost:65504/v1 # [!code ++] model_name: text-embedding-3-small # [!code --] model_name: qwen-embedding # [!code ++] sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light query_instruction: '' # [!code --] query_instruction: 'Query: ' # [!code ++] top_k: 5 # [!code --] top_k: 20 # [!code ++] ``` ## 4. 效果演示 配置完成后,在 UltraRAG UI 中启动 AgentCPM-Report Pipeline。 由于万字综述的生成涉及大量并发检索与多轮推理,耗时通常在 10 分钟以上。您可以利用 UI 的[后台运行](/pages/cn/ui/start)功能,任务完成后再回来查看最终报告。 # LightResearch Source: https://ultrarag.openbmb.cn/pages/cn/demo/lightresearch LightResearch 是一个轻量级的深度研究(Deep Research)实现。它通过自动化生成调研计划、多轮迭代检索、子问题拆解以及长篇综述生成,模拟专家级的调研分析过程。 ## 1. Pipeline 结构概览 ```yaml examples/LightResearch.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # LightResearch Demo for UltraRAG UI # MCP Server servers: benchmark: servers/benchmark generation: servers/generation retriever: servers/retriever prompt: servers/prompt router: servers/router custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - custom.init_citation_registry - prompt.webnote_gen_plan - generation.generate: output: ans_ls: plan_ls - prompt.webnote_init_page - generation.generate: output: ans_ls: page_ls - loop: times: 10 steps: - branch: router: - router.webnote_check_page branches: incomplete: - prompt.webnote_gen_subq - generation.generate: output: ans_ls: subq_ls - retriever.retriever_search: input: query_list: subq_ls output: ret_psg: psg_ls - custom.assign_citation_ids_stateful: input: ret_psg: psg_ls output: ret_psg: psg_ls - prompt.webnote_fill_page - generation.generate: output: ans_ls: page_ls complete: [] - prompt.webnote_gen_answer - generation.generate ``` ## 2. 编译Pipeline文件 执行以下命令编译该复杂工作流 ```shell theme={null} ultrarag build examples/LightResearch.yaml ``` ## 3. 配置运行参数 修改 `examples/parameter/LightResearch_parameter.yaml`。 ```yaml examples/parameter/LightResearch_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false generation: backend: vllm # [!code --] backend: openai # [!code ++] backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 # [!code --] base_url: http://localhost:65503/v1 # [!code ++] concurrency: 8 model_name: MiniCPM4-8B # [!code --] model_name: qwen3-32b # [!code ++] retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' # [!code --] system_prompt: '你是一个专业的UltraRAG问答助手。请一定记住使用中文回答问题。' # [!code ++] prompt: webnote_fill_page_template: prompt/webnote_fill_page.jinja # [!code --] webnote_fill_page_template: prompt/webnote_fill_page_citation.jinja # [!code ++] webnote_gen_answer_template: prompt/webnote_gen_answer.jinja # [!code --] webnote_gen_answer_template: prompt/webnote_gen_report.jinja # [!code ++] webnote_gen_plan_template: prompt/webnote_gen_plan.jinja webnote_gen_subq_template: prompt/webnote_gen_subq.jinja webnote_init_page_template: prompt/webnote_init_page.jinja retriever: backend: sentence_transformers # [!code --] backend: openai # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 # [!code --] base_url: http://localhost:65504/v1 # [!code ++] model_name: text-embedding-3-small # [!code --] model_name: qwen-embedding # [!code ++] sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light query_instruction: '' # [!code --] query_instruction: 'Query: ' # [!code ++] top_k: 5 ``` ## 4. 效果演示 配置完成后,在 UltraRAG UI 中启动 LightResearch Pipeline。 与标准 RAG 不同,你会观察到系统在给出最终回答前,会经历多轮自主思考与检索过程,最终生成一份包含多级标题、详实论据且带有准确引用的深度综述。 # LLM Source: https://ultrarag.openbmb.cn/pages/cn/demo/llm 为了在 UltraRAG UI 中快速演示大语言模型(LLM)能力,我们提供了一个预置的 Pipeline。在正式运行前,请完成 Pipeline 的编译与参数配置。 ## 1. Pipeline 结构概览 ```yaml examples/LLM.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # LLM Demo for UltraRAG UI # MCP Server servers: benchmark: servers/benchmark prompt: servers/prompt generation: servers/generation # MCP Client Pipeline pipeline: - benchmark.get_data - prompt.qa_boxed - generation.generation_init - generation.generate ``` ## 2. 编译Pipeline文件 在终端执行以下命令进行编译: ```shell theme={null} ultrarag build examples/LLM.yaml ``` ## 3. 配置运行参数 根据你的环境需求,修改 `examples/parameter/LLM_parameter.yaml`。以下示例展示了如何将后端从 `vLLM` 切换为 `OpenAI API` 标准接口,并调整了模型名称与系统提示词。 ```yaml examples/parameter/LLM_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false generation: backend: vllm # [!code --] backend: openai # [!code ++] backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 # [!code --] base_url: http://localhost:65503/v1 # [!code ++] concurrency: 8 model_name: MiniCPM4-8B # [!code --] model_name: qwen3-32b # [!code ++] retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' # [!code --] system_prompt: '你是一个专业的UltraRAG问答助手。请一定记住使用中文回答问题。' # [!code ++] prompt: template: prompt/qa_boxed.jinja # [!code --] template: prompt/qa_simple.jinja # [!code ++] ``` ## 4. 效果演示 配置完成后,启动 UltraRAG UI,在界面中选择 LLM Pipeline 即可开始交互。 # RAG Source: https://ultrarag.openbmb.cn/pages/cn/demo/rag 为了在 UltraRAG UI 中深度体验检索增强生成(RAG)能力,我们提供了一个标准化的 RAG Pipeline。该流程集成了文档检索、引用标注及增强生成的完整链路。 ## 1. Pipeline 结构概览 ```yaml examples/RAG.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # RAG Demo for UltraRAG UI # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - retriever.retriever_search - custom.assign_citation_ids - prompt.qa_rag_boxed - generation.generate ``` ## 2. 编译Pipeline文件 在终端执行以下命令进行编译: ```shell theme={null} ultrarag build examples/RAG.yaml ``` ## 3. 配置运行参数 修改 `examples/parameter/RAG_parameter.yaml`。在 RAG 场景中,除了配置 LLM 生成后端外,还需要重点配置 Embedding 检索后端。 ```yaml examples/parameter/RAG_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false generation: backend: vllm # [!code --] backend: openai # [!code ++] backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 # [!code --] base_url: http://localhost:65503/v1 # [!code ++] concurrency: 8 model_name: MiniCPM4-8B # [!code --] model_name: qwen3-32b # [!code ++] retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' # [!code --] system_prompt: '你是一个专业的UltraRAG问答助手。请一定记住使用中文回答问题。' # [!code ++] prompt: template: prompt/qa_boxed.jinja # [!code --] template: prompt/qa_rag_citation.jinja # [!code ++] retriever: backend: sentence_transformers # [!code --] backend: openai # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 # [!code --] base_url: http://localhost:65504/v1 # [!code ++] model_name: text-embedding-3-small # [!code --] model_name: qwen-embedding # [!code ++] sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light query_instruction: '' # [!code --] query_instruction: 'Query: ' # [!code ++] top_k: 5 # [!code --] top_k: 20 # [!code ++] ``` ## 4. 效果演示 配置完成后,启动 UltraRAG UI,在界面中选择 RAG Pipeline,并选取对应的知识库。您将看到 LLM 如何结合检索到的文档片段给出更精准、带引用的回答。 # 案例分析 Source: https://ultrarag.openbmb.cn/pages/cn/develop_guide/case_study UltraRAG 提供了便捷的 Case Study 可视化机制,帮助科研人员快速检查与分析所构建的 Pipeline 是否按预期工作。 在运行完 Pipeline 后,系统会在 output 文件夹下自动生成一份 memory 日志文件。 只需执行以下命令,即可启动 Case Study 可视化网页: ```shell theme={null} python ./script/case_study.py \ --data output/memory_nq_rag_branch_20251014_152438.json \ --host 127.0.0.1 \ --port 8070 \ --title "Case Study Viewer" ``` 请根据实际情况调整文件路径、端口号等参数。 启动成功后,可通过浏览器访问对应地址,进入 Case Study Viewer 界面。该界面以直观的可视化方式展示 Pipeline 各阶段的输入与输出,便于逐步审查推理链条与中间状态。 在页面中,可逐条切换不同的 Case,直观对比 `输入问题、检索结果与模型输出` 的对应关系,从而更高效地定位潜在问题、优化 Pipeline 设计,并验证整个推理流程是否符合预期。 # 代码集成 Source: https://ultrarag.openbmb.cn/pages/cn/develop_guide/code_integration 通过 **ToolCall** 和 **PipelineCall** 两种方式,你可以在本地代码中直接调用 UltraRAG 的能力。 ## ToolCall 当你只需要 UltraRAG 的某个功能(例如数据加载、编码、检索等),不需要运行完整 Pipeline 时,可通过 `ToolCall` 以函数方式进行调用。 `ToolCall` 需要先使用 `initialize` 指定要启用的 Server。 `server_root` 推荐使用绝对路径,例如 `/home/user/project/UltraRAG/servers`。 ```python script/api_usage_example.py theme={null} from ultrarag.api import initialize, ToolCall initialize(["benchmark"], server_root="servers") benchmark_param_dict = { "key_map":{ "gt_ls": "golden_answers", "q_ls": "question" }, "limit": -1, "seed": 42, "name": "nq", "path": "data/sample_nq_10.jsonl", } benchmark = ToolCall.benchmark.get_data(benchmark_param_dict) ``` 使用方式与普通 Python 函数一致,按需传入对应参数即可。 ```python script/api_usage_example.py theme={null} from ultrarag.api import initialize, ToolCall initialize(["benchmark", "retriever"], server_root="servers") benchmark_param_dict = { "key_map":{ "gt_ls": "golden_answers", "q_ls": "question" }, "limit": -1, "seed": 42, "name": "nq", "path": "data/sample_nq_10.jsonl", } benchmark = ToolCall.benchmark.get_data(benchmark_param_dict) query_list = benchmark['q_ls'] retriever_init_param_dict = { "model_name_or_path": "Qwen/Qwen3-Embedding-0.6B", } ToolCall.retriever.retriever_init( **retriever_init_param_dict ) result = ToolCall.retriever.retriever_search( query_list=query_list, top_k=5, ) retrieve_passages = result['ret_psg'] ``` 只需传入你希望修改的参数,其他参数会自动从 Server 的默认参数文件补全。 ## PipelineCall 如果你希望在本地直接运行一整个 UltraRAG Pipeline,并获得全部步骤的执行结果,可以使用 `PipelineCall`。 你需要先通过 UltraRAG 的 `build` 功能生成对应 Pipeline 的 `pipeline_parameter.yaml` 与参数文件。 ```python script/api_usage_example.py theme={null} from ultrarag.api import PipelineCall result = PipelineCall( pipeline_file="examples/rag_deploy.yaml", parameter_file="examples/parameter/rag_deploy_parameter.yaml", ) final_step_result = result['final_result'] all_steps_result = result['all_results'] ``` `final_result` 为 Pipeline 最后一个步骤的运行结果,`all_steps_result` 则包含所有步骤的运行结果。 # 评测数据 Source: https://ultrarag.openbmb.cn/pages/cn/develop_guide/dataset 我们整理并预处理了当前 RAG 研究中最常用的公开评测数据集和语料库,并已在 [ModelScope](https://modelscope.cn/datasets/UltraRAG/UltraRAG_Benchmark) 和 [Huggingface](https://huggingface.co/datasets/UltraRAG/UltraRAG_Benchmark) 上同步发布。 用户可直接下载使用,无需额外清洗或转换,即可与 UltraRAG 的评测管线无缝对接。 ## Benchmark 下表汇总了当前已支持的任务类型及对应数据集的统计信息: | 任务类型 | 数据集名称 | 原始数据数量 | 评测采样数量 | | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------ | :----- | :----- | | QA | [NQ](https://huggingface.co/datasets/google-research-datasets/nq_open) | 3,610 | 1,000 | | QA | [TriviaQA](https://nlp.cs.washington.edu/triviaqa/) | 11,313 | 1,000 | | QA | [PopQA](https://huggingface.co/datasets/akariasai/PopQA) | 14,267 | 1,000 | | QA | [AmbigQA](https://huggingface.co/datasets/sewon/ambig_qa) | 2,002 | 1,000 | | QA | [MarcoQA](https://huggingface.co/datasets/microsoft/ms_marco/viewer/v2.1/validation) | 55,636 | 1,000 | | QA | [WebQuestions](https://huggingface.co/datasets/stanfordnlp/web_questions) | 2,032 | 1,000 | | VQA | [MP-DocVQA](https://huggingface.co/datasets/openbmb/VisRAG-Ret-Test-MP-DocVQA) | 591 | 591 | | VQA | [ChartQA](https://huggingface.co/datasets/openbmb/VisRAG-Ret-Test-ChartQA) | 63 | 63 | | VQA | [InfoVQA](https://huggingface.co/datasets/openbmb/VisRAG-Ret-Test-InfoVQA) | 718 | 718 | | VQA | [PlotQA](https://huggingface.co/datasets/openbmb/VisRAG-Ret-Test-PlotQA) | 863 | 863 | | Multi-hop QA | [HotpotQA](https://huggingface.co/datasets/hotpotqa/hotpot_qa) | 7,405 | 1,000 | | Multi-hop QA | [2WikiMultiHopQA](https://www.dropbox.com/scl/fi/heid2pkiswhfaqr5g0piw/data.zip?e=2\&file_subpath=%2Fdata\&rlkey=ira57daau8lxfj022xvk1irju) | 12,576 | 1,000 | | Multi-hop QA | [Musique](https://drive.google.com/file/d/1tGdADlNjWFaHLeZZGShh2IRcpO6Lv24h/view) | 2,417 | 1,000 | | Multi-hop QA | [Bamboogle](https://huggingface.co/datasets/chiayewken/bamboogle) | 125 | 125 | | Multi-hop QA | [StrategyQA](https://huggingface.co/datasets/tasksource/strategy-qa) | 2,290 | 1,000 | | Multi-hop VQA | [SlideVQA](https://huggingface.co/datasets/openbmb/VisRAG-Ret-Test-SlideVQA) | 556 | 556 | | Multiple-choice | [ARC](https://huggingface.co/datasets/allenai/ai2_arc) | 3,548 | 1,000 | | Multiple-choice | [MMLU](https://huggingface.co/datasets/cais/mmlu) | 14,042 | 1,000 | | Multiple-choice VQA | [ArXivQA](https://huggingface.co/datasets/openbmb/VisRAG-Ret-Test-ArxivQA) | 816 | 816 | | Long-form QA | [ASQA](https://huggingface.co/datasets/din0s/asqa) | 948 | 948 | | Fact-verification | [FEVER](https://fever.ai/dataset/fever.html) | 13,332 | 1,000 | | Dialogue | [WoW](https://huggingface.co/datasets/facebook/kilt_tasks) | 3,054 | 1,000 | | Slot-filling | [T-REx](https://huggingface.co/datasets/facebook/kilt_tasks) | 5,000 | 1,000 | **数据格式规范** 为了确保与 UltraRAG 各模块完全兼容,建议用户将测试数据统一存储为 .jsonl 文件,并遵循以下格式规范。 非选择题数据格式: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} { "id": 0, "question": "where does the karate kid 2010 take place", "golden_answers": ["China", "Beijing", "Beijing, China"], "meta_data": {} } ``` 选择题数据格式: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} { "id": 0, "question": "Mast Co. converted from the FIFO method for inventory valuation to the LIFO method for financial statement and tax purposes. During a period of inflation would Mast's ending inventory and income tax payable using LIFO be higher or lower than FIFO? Ending inventory Income tax payable", "golden_answers": ["A"], "choices": ["Lower Lower", "Higher Higher", "Lower Higher", "Higher Lower"], "meta_data": {"subject": "professional_accounting"} } ``` ## Corpus UltraRAG 提供了多源、高质量的标准化语料库,涵盖文本与图像两种模态,便于构建多场景 RAG 系统。 以下为当前已收录语料的统计信息: | 语料库名称 | 文档数量 | | :-------- | :--------- | | Wiki-2018 | 21,015,324 | | Wiki-2024 | 30,463,973 | | MP-DocVQA | 741 | | ChartQA | 500 | | InfoVQA | 459 | | PlotQA | 9,593 | | SlideVQA | 1,284 | | ArXivQA | 8,066 | **数据格式规范** 文本语料格式: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} { "id": "15106858", "contents": "Arrowhead Stadium 1970s practice would eventually spread to the other NFL stadiums as the 1970s progressed, finally becoming mandatory league-wide in the 1978 season (after being used in Super Bowl XII), and become almost near-universal at the lower levels of football. On January 20, 1974, Arrowhead Stadium hosted the Pro Bowl. Due to an ice storm and brutally cold temperatures the week leading up to the game, the game's participants worked out at the facilities of the San Diego Chargers. On game day, the temperature soared to 41 F, melting most of the ice and snow that accumulated during the week. The AFC defeated the NFC, 15–13." } ``` 图像语料格式: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} { "id": 0, "image_id": "37313.jpeg", "image_path": "image/37313.jpg" } ``` # 代码调试 Source: https://ultrarag.openbmb.cn/pages/cn/develop_guide/debug 为了更高效地开发与调试 UltraRAG,你可以使用 VSCode 的内置调试功能运行指定的 Pipeline 配置文件,并对执行过程进行断点调试。 ## 步骤一:编译并配置参数 以 examples/rag\_full.yaml 为例,首先执行 Pipeline 编译 并完成参数配置。该过程与[快速开始](/pages/cn/getting_started/quick_start)一致,唯一区别是此处无需执行运行命令。 ## 步骤二:创建调试配置文件 在项目根目录下创建 `.vscode/launch.json` 文件,并写入以下内容: ```json .vscode/launch.json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" highlight="11" theme={null} { "configurations": [ { "name": "UltraRAG Debug", "type": "debugpy", "request": "launch", "program": "${workspaceFolder}/src/ultrarag/client.py", "console": "integratedTerminal", "args": [ "run", "${workspaceFolder}/examples/rag_full.yaml" ], "cwd": "${workspaceFolder}", } ] } ``` 如果你想调试其他 Pipeline,只需将 args 中的路径替换为对应的 YAML 文件路径。 ## 步骤三:启动调试 1. 打开 VSCode 左侧的调试面板(快捷键 Ctrl+Shift+D)。 2. 在调试配置中选择 UltraRAG Debug。 3. 点击绿色 ▶ 启动按钮,即可在 VSCode 内集成终端中运行并调试。 你可以在任意 Python 文件中设置断点,以逐步观察执行流程和变量状态。 # 并行实验 Source: https://ultrarag.openbmb.cn/pages/cn/develop_guide/parallel 在实验过程中,我们常常需要对同一个 Pipeline 使用不同的超参数配置进行并行或批量试验。UltraRAG 提供了灵活的参数文件机制,支持在不修改主 Pipeline 的情况下快速切换配置。 ## 步骤一:编译 Pipeline 与常规运行流程一致,首先编译 Pipeline: ```shell theme={null} ultrarag build examples/rag_full.yaml ``` 步骤二:运行 在生成的参数文件中修改相应字段后,直接运行以下命令即可执行: ```shell theme={null} ultrarag run examples/rag_full.yaml ``` 步骤三:创建新的参数文件 若你希望在同一个 Pipeline 上测试不同参数组合,可以新建一份参数文件,例如`examples/parameter/rag_full_parameter_new.yaml`(文件名可自定义)。 随后运行命令时,通过 `--param` 参数指定使用该配置文件: ```shell theme={null} ultrarag run examples/rag_full.yaml --param examples/parameter/rag_full_parameter_new.yaml ``` 这样,系统将使用新的参数文件执行相同的 Pipeline,从而轻松实现多组实验的并行与批量对比。 # 环境部署 Source: https://ultrarag.openbmb.cn/pages/cn/getting_started/installation UltraRAG 提供了两种安装方式:本地源码安装(推荐使用 `uv` 进行包管理)和 Docker 容器部署 ## 源码安装 我们强烈推荐使用 [uv](https://github.com/astral-sh/uv) 来管理 Python 环境与依赖,它能极大地提升安装速度。 **准备环境** 如果您尚未安装 uv,请先执行: ```shell theme={null} ## 直接安装 pip install uv ## 下载 curl -LsSf https://astral.sh/uv/install.sh | sh ``` **下载源码** ```shell theme={null} git clone https://github.com/OpenBMB/UltraRAG.git --depth 1 cd UltraRAG ``` **安装依赖** 请根据您的使用场景,选择一种模式安装依赖: **A:创建新环境** 使用 `uv sync` 自动创建虚拟环境并同步依赖: * 核心依赖:如果您只需运行基础核心功能,如只使用 UltraRAG UI: ```shell theme={null} uv sync ``` * 全量安装:如果您希望完整体验 UltraRAG 的检索、生成、语料处理及评测功能,请运行: ```shell theme={null} uv sync --all-extras ``` * 按需安装:如果您只需运行定模块,按需保留对应 `--extra`,例如: ```shell theme={null} uv sync --extra retriever # 仅检索模块 uv sync --extra generation # 仅生成模块 ``` 安装完成后,激活虚拟环境: ```shell theme={null} # Windows CMD .venv\Scripts\activate.bat # Windows Powershell .venv\Scripts\Activate.ps1 # macOS / Linux source .venv/bin/activate ``` **B:安装至已有环境** 如果您希望将 UltraRAG 安装到当前已激活的 Python 环境中,请使用 `uv pip`: ```shell theme={null} # 核心依赖 uv pip install -e . # 全量安装 uv pip install -e ".[all]" # 按需安装 uv pip install -e ".[retriever]" ``` ## Docker 容器部署 如果您不想配置本地 Python 环境,可以使用 Docker 一键启动。 **获取代码与镜像** ```shell theme={null} # 1. 下载代码 git clone https://github.com/OpenBMB/UltraRAG.git --depth 1 cd UltraRAG # 2. 准备镜像 (二选一) # 选项 A:从 Docker Hub 拉取 docker pull hdxin2002/ultrarag:v0.3.0-base-cpu # 基础版 (CPU) docker pull hdxin2002/ultrarag:v0.3.0-base-gpu # 基础版 (GPU) docker pull hdxin2002/ultrarag:v0.3.0 # 完整版 (GPU) # 选项 B:本地构建 docker build -t ultrarag:v0.3.0 . ``` **启动容器** ```shell theme={null} # 启动容器(已自动映射 5050 端口) docker run -it --gpus all -p 5050:5050 ``` 容器启动后会自动运行 UltraRAG UI,您可以直接在浏览器访问 `http://localhost:5050` 使用。 ## 验证安装 安装完成后,运行以下示例命令来检查环境是否正常: ```shell theme={null} ultrarag run examples/sayhello.yaml ``` 看到以下输出即代表安装成功: ``` Hello, UltraRAG v3! ``` # 项目简介 Source: https://ultrarag.openbmb.cn/pages/cn/getting_started/introduction ## UltraRAG UltraRAG 是首个基于 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) 架构设计的轻量级 RAG 开发框架,专为科研探索与工业原型设计打造。它将 RAG 中的核心组件(如 [Retriever](/pages/cn/rag_servers/retriever)、[Generation](/pages/cn/rag_servers/generation) 等)标准化封装为独立的 MCP Server,实现了基于函数级 Tool 接口的灵活扩展。配合 MCP Client 的流程调度能力,开发者能够通过 YAML 配置实现对复杂控制结构(如条件、循环等)的精确编排。此外,系统支持算法逻辑向对话演示界面的无缝迁移,极大地优化了复杂 RAG 系统的开发全链路效率。

**核心蓝图**:用户通过 YAML 编写的任务逻辑,定义了各组件的执行顺序与业务逻辑,实现推理流程的配置化。 **指挥中枢**:负责解析 Pipeline 配置,统一协调各 Server 间工具的调用与数据传递,确保流程精准执行。 **能力载体**:将核心功能标准化封装为独立服务,支持通过简单接口实现新模块的快速扩展与灵活组合。 **视觉门户**:将 YAML 定义的逻辑一键转化为直观的对话界面,显著提升了系统的调试效率与演示效果。 ## Why UltraRAG? RAG 系统正经历从静态链式串联向自主推理体系的范式演进,愈发依赖模型的主动推理、动态检索与条件决策。然而,传统框架在应对多轮交互与动态更新时,往往面临灵活性不足、模块深度耦合、结构松散等瓶颈,导致研究者难以高效复现与横向对比。 UltraRAG 旨在打破这一僵局,为开发者提供一套标准化、解耦且极简的开发新范式: **推理编排**:原生支持串行、循环与条件分支等控制结构。开发者仅需编写 YAML 配置文件,即可在数十行代码内实现复杂的迭代式 RAG 逻辑。 **原子化 Server**:基于 MCP 架构将功能解耦为独立 Server。新功能仅需以函数级 Tool 形式注册,即可无缝接入流程,实现极高的复用性。 **科研提效**:内置标准化评测流程,开箱即用主流科研 [Benchmark](/pages/cn/develop_guide/dataset)。通过统一指标管理与基线集成,大幅提升实验的可复现性与对比效率。 **一键交付**:告别繁琐的 UI 开发。仅需一行命令,即可将 Pipeline 逻辑瞬间转化为可交互的对话式 Web UI,缩短从算法到演示的距离。 # 快速开始 Source: https://ultrarag.openbmb.cn/pages/cn/getting_started/quick_start 本节将帮助你快速了解如何基于 UltraRAG 运行一个完整的 RAG Pipeline。UltraRAG 的使用流程主要包括以下三个阶段: * 编写 Pipeline 配置文件 * 编译 Pipeline 并调整参数 * 运行 Pipeline 此外,你还可以通过可视化工具对运行结果进行分析与评估。 如果尚未安装 UltraRAG,请先参考 [环境部署](/pages/cn/getting_started/installation)。 如需了解更完整的 RAG 开发实践,请查看完整文档。 ## Step 1:编写 Pipeline 配置文件 请确保当前工作目录位于 UltraRAG 根目录下 在`examples`文件夹中创建并编写你的 Pipeline 配置文件,例如: ```yaml examples/rag_full.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # Vanilla RAG with Corpus Indexing Demo # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` UltraRAG 的 Pipeline 配置文件需要包含以下两个部分: * `servers`:声明当前流程所依赖的各个模块(Server)。例如,检索阶段需要使用 `retriever` Server。 * `pipeline`:定义各 Server 中功能函数(Tool)的调用顺序。本示例展示了从数据加载、检索编码与索引构建,到生成与评测的完整流程。 ## Step 2:编译 Pipeline 并调整参数 在运行代码前,首先需要配置运行所需的参数。UltraRAG 提供了快捷的 build 指令,可自动生成当前 Pipeline 所依赖的完整参数文件。 系统会读取各个 Server 的 parameter.yaml 文件,解析本次流程中涉及的全部参数项,并统一汇总生成到一个独立的配置文件中。执行以下命令: ```shell theme={null} ultrarag build examples/rag_full.yaml ``` 执行后,终端将输出如下内容: 系统会在`examples/parameters/`文件夹下生成对应的参数配置文件。打开文件后,可根据实际情况修改相关参数,例如: ```yaml examples/parameters/rag_full_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false custom: {} evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json generation: backend: vllm backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: 'abc' base_delay: 1.0 base_url: http://localhost:8000/v1 concurrency: 8 model_name: MiniCPM4-8B retries: 3 vllm: dtype: auto gpu_ids: 5 gpu_memory_utilization: 0.5 model_name_or_path: openbmb/MiniCPM4-8B # [!code --] model_name_or_path: Qwen/Qwen3-8B # [!code ++] trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: template: prompt/qa_boxed.jinja # [!code --] template: prompt/qa_rag_boxed.jinja # [!code ++] retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: 'abc' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl embedding_path: embedding/embedding.npy gpu_ids: '5' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] overwrite: false query_instruction: '' top_k: 5 ``` 你可以根据实际情况修改参数,例如: * 将 template 调整为RAG模版 prompt/qa\_rag\_boxed.jinja; * 替换检索器与生成器的 model\_name\_or\_path 为本地下载的模型路径; * 若在多 GPU 环境下运行,可修改 gpu\_ids 以匹配可用设备。 ## Step 3:运行 Pipeline 当参数配置完成后,即可一键运行完整流程。执行以下命令: ```shell theme={null} ultrarag run examples/rag_full.yaml ``` 系统将依次执行配置文件中定义的各个 Server 与 Tool,并在终端中实时输出运行日志与进度信息: 运行结束后,结果(如生成内容、评测报告等)将自动保存在对应的输出路径中,如本例中`output/memory_nq_rag_full_20251010_145420.json`可直接用于后续分析与可视化展示。 ## Step 4:可视化分析 Case Study 完成流程运行后,可通过内置的可视化工具快速分析生成结果。执行以下命令启动 Case Study Viewer: ```shell theme={null} python ./script/case_study.py \ --data output/memory_nq_rag_full_20251010_145420.json \ --host 127.0.0.1 \ --port 8080 \ --title "Case Study Viewer" ``` 运行成功后,终端会显示访问地址。打开浏览器并输入该地址,即可进入 Case Study Viewer 界面,对结果进行交互式浏览与分析。 界面示例如下所示: ## 小结 至此,你已完成从 Pipeline 配置、参数编译 到 流程运行与可视化分析 的完整 RAG 实践流程。 UltraRAG 通过模块化的 MCP 架构与统一的评测体系,使得 RAG 系统的构建、运行与分析更加高效、直观、可复现。 你可以在此基础上: * 替换不同的模型或检索器,探索多种组合效果; * 自定义新的 Server 与 Tool,扩展系统功能; * 利用评测模块快速对比实验结果,开展系统性研究。 # 更新日志 Source: https://ultrarag.openbmb.cn/pages/cn/getting_started/update **2026-1-23** 拒绝“盲盒”开发,让每一行推理逻辑都清晰可见。 **2026-1-12** 提升了系统稳定性,修复了 Search-o1 等实现Bug。 **2025-11-25** 提供 ToolCall 和 PipelineCall 功能,直接本地代码直接调用。 **2025-11-13** 解耦检索与索引架构并支持 Milvus/Faiss,全面提升稳定性与灵活性。 **2025-10-22** RAG Servers 全面升级——重构文档解析与知识库构建流程,强化多模态 RAG 能力,支持更多后端框架。 **2025-08-28** 基于 MCP 的低代码 RAG 框架,助力研究者以更高效的方式构建复杂流程,实现创新性研发。 # WebNote Source: https://ultrarag.openbmb.cn/pages/cn/pipeline/light_deepresearch 我们为该 Demo 录制了一期讲解视频:[📺 bilibili](https://www.bilibili.com/video/BV1p8JfziEwM/?spm_id_from=333.337.search-card.all.click)。 ## 什么是DeepResearch Deep Research(也称为 Agentic Deep Research)是指大语言模型(LLM)协同工具(如搜索、浏览器、代码执行、记忆存储等),以“多轮推理→检索→验证→融合”的闭环方式,完成复杂任务的研究型智能代理。 不同于单次检索的 RAG(Retrieval-Augmented Generation),Deep Research 更像人的专家思路——先制定计划,再不断探索、调整方向、核实信息,最终输出结构完整、有出处的报告。 ## 前置准备 在本次开发中,我们将基于 UltraRAG 框架 完成示例。考虑到大多数小伙伴可能没有算力服务器,我们全程在一台 MacBook Air (M2) 上实现,确保环境轻量、易于复现。 ### API准备 * 检索 API:我们采用 [Tavily Web Search](https://www.tavily.com/),初次注册即可免费获得 1000 次调用额度。 * LLM API:你可以根据自己的习惯选择任意大模型服务。本教程中,我们使用 gpt-5-nano 作为示例 ### API设置 我们提供了两种方式传入 API Key:环境变量和显式参数。其中推荐使用 环境变量,更安全,也能避免 API Key 在日志中泄漏。 在 UltraRAG 根目录下,将模板文件 `.env.dev` 重命名为 `.env`, 并填写你的密钥信息,例如: ``` LLM_API_KEY="your llm key" TAVILY_API_KEY="your retriever key" ``` UltraRAG 会在启动时自动读取该文件并加载相关配置。 ## Pipeline介绍 在本示例中,我们将实现一个轻量级的 Deep Research Pipeline。它具备以下基本功能: * Plan 制定:模型先根据用户问题制定解决方案的计划; * 子问题生成与检索:将大问题分解为可检索的子问题,并调用 Web 搜索工具获取相关资料; * 报告整理与填充:逐步完善研究报告的内容; * 推理与最终生成:在报告完成后,模型给出最终答案。 流程图如下所示: 该 pipeline 主要分为两个阶段: 1. **初始化阶段:** 模型会根据用户问题生成一份 plan,并据此构造出初始的报告 page。 2. **迭代填充阶段:** * 系统会检查当前报告 page 是否已填充完整。 * 判断标准为:page 中是否仍存在 "to be filled" 字符串。 * 如果报告尚未完成,模型会结合用户问题、plan 与当前 page,生成一个新的子问题并触发 Web 检索。 * 检索到的文档会被用于更新 page,然后进入下一轮检查。 * 这个过程会持续迭代,直到 page 被填满。 最后,模型会基于用户问题与最终报告 page,生成完整的答案。 这个示例的代码实现非常简洁,主要依赖 router 与 prompt tool 的自定义扩展。感兴趣的小伙伴可以直接查看源码。以下是完整的 pipeline 定义: ```yaml examples/webnote_websearch.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark generation: servers/generation retriever: servers/retriever prompt: servers/prompt router: servers/router # MCP Client Pipeline pipeline: - benchmark.get_data - generation.generation_init - prompt.webnote_gen_plan - generation.generate: output: ans_ls: plan_ls - prompt.webnote_init_page - generation.generate: output: ans_ls: page_ls - loop: times: 10 steps: - branch: router: - router.webnote_check_page branches: incomplete: - prompt.webnote_gen_subq - generation.generate: output: ans_ls: subq_ls - retriever.retriever_tavily_search: input: query_list: subq_ls output: ret_psg: psg_ls - prompt.webnote_fill_page - generation.generate: output: ans_ls: page_ls complete: [] - prompt.webnote_gen_answer - generation.generate ``` ## 运行 ### 构建问题数据 首先,在 data 文件夹下新建一个名为 sample\_light\_ds.jsonl 的文件,并写入你要研究的问题。例如: ```json data/sample_light_ds.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "question": "介绍一下提瓦特大陆", "golden_answers": [], "meta_data": {}} ``` ### 构建参数配置文件 执行以下命令生成 pipeline 对应的参数文件: ```shell theme={null} ultrarag build examples/webnote_websearch.yaml ``` 根据实际情况对参数进行修改,例如: ```yaml examples/parameter/webnote_websearch_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq # [!code --] path: data/sample_nq_10.jsonl # [!code --] name: ds # [!code ++] path: data/sample_light_ds.jsonl # [!code ++] seed: 42 shuffle: false generation: backend: vllm # [!code --] backend: openai # [!code ++] backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 # [!code --] base_url: https://api.openai.com/v1 # [!code ++] concurrency: 8 model_name: MiniCPM4-8B # [!code --] model_name: gpt-5-nano # [!code ++] retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 # [!code --] system_prompt: '' prompt: webnote_fill_page_template: prompt/webnote_fill_page.jinja webnote_gen_answer_template: prompt/webnote_gen_answer.jinja webnote_gen_plan_template: prompt/webnote_gen_plan.jinja webnote_gen_subq_template: prompt/webnote_gen_subq.jinja webnote_init_page_template: prompt/webnote_init_page.jinja retriever: retrieve_thread_num: 1 top_k: 5 ``` ### 启动 在运行前,不要忘记设置你的 API Key: ```shell theme={null} ultrarag examples/webnote_websearch.yaml ``` 运行完成后,你可以通过 Case Study Viewer 可视化地查看生成内容: ```shell theme={null} python ./script/case_study.py \ --data output/memory_ds_light_deepresearch_20250909_152727.json \ --host 127.0.0.1 \ --port 8070 \ --title "Case Study Viewer" ``` 这样即可在浏览器中打开结果页面,直观地分析 pipeline 的执行过程与生成内容。 # Vanilla RAG Source: https://ultrarag.openbmb.cn/pages/cn/pipeline/rag 我们为该 Demo 录制了一期讲解视频:[📺 bilibili](https://www.bilibili.com/video/BV1B9apz4E7K/?share_source=copy_web\&vd_source=7035ae721e76c8149fb74ea7a2432710)。 ## 什么是RAG? > 想象你在参加一次开卷考试。你本人就是大语言模型,具备理解题目和写答案的能力。\ > 但你不可能记住所有知识点。这时,允许你带一本教材或参考书进考场——这就是检索。\ > 当你翻书找到相关内容,再结合自己的理解去写答案,这样答案既准确又有根据。\ > 这就是 RAG —— 检索增强生成。 RAG(Retrieval-Augmented Generation,检索增强生成)是一种让大语言模型(LLM)在“生成”之前,先去“检索”相关文档或知识库,再结合这些信息生成回答的技术。 ### 流程 **检索阶段**:根据用户问题,从文档库中找到最相关的内容(比如知识库、网页等);\\ **生成阶段**:把检索到的内容作为上下文,输入给 LLM,让它基于这些信息生成回答\\ ### 作用 * 提升准确度、降低“幻觉” * 无需重训模型,也能保持时效性和专业性 * 增强可信度 ## 语料库编码与索引 在使用 RAG 之前,需要先将原始文档转化为 向量表示,并建立 检索索引。这样,当用户提问时,系统才能在大规模语料库中快速找到最相关的内容。 * **编码(Embedding)**:把自然语言文本转化为向量,让计算机可以用数学方式比较语义相似度。 * **索引(Indexing)**:把这些向量组织起来,比如用 FAISS,这样检索时才能在几百万条文档中瞬间找到最相关的若干条。 ### 示例语料(Wiki 文本) ```json data/corpus_example.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": "2066692", "contents": "Truman Sports Complex The Harry S. Truman Sports...."} {"id": "15106858", "contents": "Arrowhead Stadium 1970s...."} ``` 这是典型的 Wiki 语料,其中 id 是文档的唯一标识符,contents 是实际的文本内容。后续我们会对 contents 做向量化并建立索引。 ### 编写编码、索引Pipeline ```yaml examples/corpus_index.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: retriever: servers/retriever # MCP Client Pipeline pipeline: - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index ``` 这里定义了一个最小的三步流程:初始化 → 编码 → 建索引。 ### 编译Pipeline文件 ```shell theme={null} ultrarag build examples/corpus_index.yaml ``` ### 修改参数文件 ```yaml examples/parameters/corpus_index_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl embedding_path: embedding/embedding.npy gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] overwrite: false ``` ### 运行Pipeline文件 ```shell theme={null} ultrarag run examples/corpus_index.yaml ``` 编码与索引阶段通常涉及大规模语料处理,耗时较长。建议使用 `screen` 或 `nohup` 将任务挂载至后台运行,例如: ```shell theme={null} nohup ultrarag run examples/corpus_index.yaml > log.txt 2>&1 & ``` 运行成功后,就会得到对应的语料向量和索引文件,后续 RAG Pipeline 就可以直接使用它们来完成检索。 ## 搭建RAG Pipeline 当语料库的索引准备完成后,下一步就是将 检索器 和 大语言模型(LLM) 组合起来,搭建一个完整的 RAG Pipeline。这样,问题可以经过检索找到相关文档,再交由模型生成最终回答。 ### 检索流程 ### 生成流程 ### 数据格式(以 NQ 数据集为例) ```json data/sample_nq_10.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "question": "when was the last time anyone was on the moon", "golden_answers": ["14 December 1972 UTC", "December 1972"], "meta_data": {}} {"id": 1, "question": "who wrote he ain't heavy he's my brother lyrics", "golden_answers": ["Bobby Scott", "Bob Russell"], "meta_data": {}} {"id": 2, "question": "how many seasons of the bastard executioner are there", "golden_answers": ["one", "one season"], "meta_data": {}} {"id": 3, "question": "when did the eagles win last super bowl", "golden_answers": ["2017"], "meta_data": {}} {"id": 4, "question": "who won last year's ncaa women's basketball", "golden_answers": ["South Carolina"], "meta_data": {}} ``` 每条样本包含问题、标准答案(golden\_answers)和附加信息(meta\_data),后续会作为输入与评测基准。 ### 编写RAG Pipeline ```yaml examples/rag.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 整个流程依次完成: 1. 读取数据 → 2. 初始化检索器并搜索 → 3. 启动 LLM 服务 → 4. 拼接 Prompt → 5. 生成回答 → 6. 提取结果 → 7. 评测性能。 ### 编译 Pipeline 文件 ```shell theme={null} ultrarag build examples/rag.yaml ``` ### 修改参数文件(指定数据集、模型与检索配置) ```yaml examples/parameters/rag_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false custom: {} evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json generation: backend: vllm backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 concurrency: 8 model_name: MiniCPM4-8B retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B # [!code --] model_name_or_path: Qwen/Qwen3-8B # [!code ++] trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: template: prompt/qa_boxed.jinja # [!code --] template: prompt/qa_rag_boxed.jinja # [!code ++] retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] query_instruction: '' top_k: 5 ``` ### 运行Pipeline文件 ```shell theme={null} ultrarag run examples/rag.yaml ``` ### 查看生成结果 使用可视化脚本快速浏览模型输出 ```shell theme={null} python ./script/case_study.py \ --data output/memory_nq_rag_full_20251010_145420.json \ --host 127.0.0.1 \ --port 8080 \ --title "Case Study Viewer" ``` # Search-o1 Source: https://ultrarag.openbmb.cn/pages/cn/pipeline/search_o1 ## 简介 Search-o1 提出一种将大规模推理模型与 **自主检索增强生成(Agentic RAG)** 和 **文档内推理(Reason-in-Documents)** 结合的框架。当模型在推理过程中遇到知识空缺时,会主动检索外部信息、进行精炼,并将结果注入推理链,从而提升科学、数学、编程等复杂任务中的推理准确性与稳健性。 论文链接:[Arxiv](https://arxiv.org/abs/2501.05366)。 ### 流程 简而言之,Search-o1 先以原始问题开展推理;一旦识别信息缺口,即生成子问题并触发检索;随后对召回应答进行精炼,提取关键信息回注入推理过程,直到形成可置信的最终答案。 ## 复现 ### 编写Pipeline 基于上面的逻辑,可以写出如下 Pipeline: ```yaml examples/search_o1.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # Search-o1 Demo # MCP Servers servers: benchmark: servers/benchmark generation: servers/generation retriever: servers/retriever prompt: servers/prompt evaluation: servers/evaluation router: servers/router custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - custom.search_o1_init_list - prompt.search_o1_init - generation.generate - loop: times: 10 steps: - branch: router: - router.search_o1_check branches: retrieve: - custom.search_o1_query_extract - retriever.retriever_search: input: query_list: extract_query_list - custom.search_o1_reasoning_extract - custom.search_o1_combine_list - prompt.search_o1_reasoning_indocument - generation.generate - custom.search_o1_extract_final_information - custom.search_o1_combine_final_information - prompt.search_o1_insert - generation.generate stop: [] - custom.output_extract_from_boxed - evaluation.evaluate ``` ### 编译Pipeline文件 ```shell theme={null} ultrarag build examples/search_o1.yaml ``` ### 修改参数文件 ```yaml examples/parameters/search_o1_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false custom: {} evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json generation: backend: vllm backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 concurrency: 8 model_name: MiniCPM4-8B retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B # [!code --] model_name_or_path: Qwen/QwQ-32B # [!code ++] trust_remote_code: true extra_params: chat_template_kwargs: # [!code --] enable_thinking: false # [!code --] top_k: 20 # [!code ++] repetition_penalty: 1.05 # [!code ++] include_stop_str_in_output: true # [!code ++] stop: # [!code ++] - <|im_end|> # [!code ++] - <|end_search_query|> # [!code ++] sampling_params: max_tokens: 2048 # [!code --] max_tokens: 32768 # [!code ++] temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: searcho1_reasoning_template: prompt/search_o1_reasoning.jinja searcho1_refine_template: prompt/search_o1_refinement.jinja retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] query_instruction: '' top_k: 5 ``` ### 运行Pipeline文件 ```shell theme={null} ultrarag run examples/search_o1.yaml ``` # VisRAG Source: https://ultrarag.openbmb.cn/pages/cn/pipeline/visrag ## 简介 在日常使用中,我们常常遇到这样的场景:购买了新设备,却不清楚某些功能如何设置, 而翻阅说明书既耗时又低效。此时,如果有一个智能助手能直接回答问题,将极大提升体验。 例如,某位用户购买了 尼康 Z7 相机,想了解其“电子减震功能在哪些场景不可用”。 直接询问 LLM 得到的回答如下: ``` 尼康Z7的电子减震功能主要用于在拍摄静物、人像等需要稳定画面的场景中提供帮助。然而,在某些特定场景下,电子减震功能是不可用的。根 据尼康官方文档和常见使用场景,电子减震功能在以下情况下不可用: 1. 拍摄运动物体:由于电子减震功能会根据相机的移动调整快门速度,因此当拍摄运动物体时,电子减震功能会变得不稳定,无法正常工作。 2. 使用长时间曝光:在长时间曝光拍摄时,相机的抖动会变得明显,电子减震功能无法有效补偿这种抖动。 3. 使用低光环境下的长曝光:在低光环境下拍摄长曝光时,相机的抖动会更加明显,电子减震功能无法有效补偿这种抖动。 因此,尼康Z7的电子减震功能在拍摄运动物体、使用长时间曝光、使用低光环境下的长曝光等场景下是不可用的。 ``` 可以看到,模型虽然能生成语义流畅的回答,但由于缺乏真实文档支撑,往往会出现“似是而非”的结果。 为了解决这一问题,UltraRAG 基于 [VisRAG](https://arxiv.org/abs/2410.10594) 实现了一种多模态检索增强 Pipeline。 它不再依赖繁琐的文本解析,而是直接将“相关文档的截图”输入给视觉语言模型,从而实现基于视觉语义的真实文档问答。 ## 构建个人知识库 以“尼康使用说明书”为例。你可以 [点击此处下载](https://download.nikonimglib.com/archive4/ywJ4K00fa2Lr05vv5OS00pV5Hg36/Z7Z6UM_TH\(Sc\)07.pdf) PDF 文件。 我们使用 UltraRAG 的 Corpus Server 将该 PDF 直接转换为图像语料库: ```yaml examples/build_image_corpus.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: corpus: servers/corpus # MCP Client Pipeline pipeline: - corpus.build_image_corpus ``` 执行以下命令: ```shell theme={null} ultrarag build examples/build_image_corpus.yaml ``` 修改参数如下: ```yaml examples/parameters/build_image_corpus_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} corpus: image_corpus_save_path: corpora/image.jsonl parse_file_path: data/UltraRAG.pdf # [!code --] parse_file_path: data/nikon.pdf # [!code ++] ``` 运行 Pipeline: ```shell theme={null} ultrarag run examples/build_image_corpus.yaml ``` 执行完成后,将自动生成图像语料文件: ```json corpora/image.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "image_id": "nikon/page_0.jpg", "image_path": "image/nikon/page_0.jpg"} {"id": 1, "image_id": "nikon/page_1.jpg", "image_path": "image/nikon/page_1.jpg"} {"id": 2, "image_id": "nikon/page_2.jpg", "image_path": "image/nikon/page_2.jpg"} {"id": 3, "image_id": "nikon/page_3.jpg", "image_path": "image/nikon/page_3.jpg"} ... ``` 接下来,使用 Retriever Server 对图像语料进行向量化编码与索引: ```yaml examples/corpus_index.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: retriever: servers/retriever # MCP Client Pipeline pipeline: - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index ``` 执行以下命令: ```shell theme={null} ultrarag build examples/corpus_index.yaml ``` 修改参数: ```yaml examples/parameters/corpus_index_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document # [!code --] psg_task: null # [!code --] q_prompt_name: query # [!code --] q_task: null # [!code --] psg_prompt_name: null # [!code ++] psg_task: retrieval # [!code ++] q_prompt_name: query # [!code ++] q_task: retrieval # [!code ++] trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl # [!code --] corpus_path: corpora/image.jsonl # [!code ++] embedding_path: embedding/embedding.npy gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false # [!code --] is_multimodal: true # [!code ++] model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: jinaai/jina-embeddings-v4 # [!code ++] overwrite: false ``` 运行索引构建: ```shell theme={null} ultrarag run examples/corpus_index.yaml ``` ## VisRAG 准备用户查询文件: ```json data/test.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "question": "尼康Z7的电子减震功能在哪些场景不可用?", "golden_answers": [], "meta_data": {}} ``` 定义 VisRAG Pipeline: ```yaml examples/visrag.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_search - generation.generation_init - prompt.qa_boxed - generation.multimodal_generate: input: multimodal_path: ret_psg ``` 执行以下命令: ```shell theme={null} ultrarag build examples/visrag.yaml ``` 修改参数: ```yaml examples/parameters/visrag_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq # [!code --] path: data/sample_nq_10.jsonl # [!code --] name: test # [!code ++] path: data/test.jsonl # [!code ++] seed: 42 shuffle: false generation: backend: vllm backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 concurrency: 8 model_name: MiniCPM4-8B retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B # [!code --] model_name_or_path: openbmb/MiniCPM-V-4 # [!code ++] trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false image_tag: null sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: template: prompt/qa_boxed.jinja # [!code --] template: prompt/visrag.jinja # [!code ++] retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document # [!code --] psg_task: null # [!code --] q_prompt_name: query # [!code --] q_task: null # [!code --] psg_prompt_name: null # [!code ++] psg_task: retrieval # [!code ++] q_prompt_name: query # [!code ++] q_task: retrieval # [!code ++] trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl # [!code --] corpus_path: corpora/image.jsonl # [!code ++] gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false # [!code --] model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] is_multimodal: true # [!code ++] model_name_or_path: jinaai/jina-embeddings-v4 # [!code ++] query_instruction: '' top_k: 5 ``` 运行该Pipeline: ```shell theme={null} ultrarag run examples/visrag.yaml ``` 执行以下命令启动 Case Study Viewer: ```shell theme={null} python ./script/case_study.py \ --data output/memory_test_visrag_20251015_163425.json \ --host 127.0.0.1 \ --port 8070 \ --title "Case Study Viewer" ``` 系统会自动展示检索到的说明书页面截图: 模型生成的回答将基于真实图像内容,示例如下: ``` 尼康Z7的电子减震功能在以下场景不可用: 1. 画面尺寸为1920×1080时。 2. 120p、1920×1080、100p或1920×1080(慢动作)时。 这些信息可以从图像中的文字部分找到,具体位于描述尼康Z7电子减震功能的段落中。 ``` 通过视觉语义增强,系统能更准确地回答用户问题,尤其适用于说明书、教材、报表等多模态场景。 # 分支结构 Source: https://ultrarag.openbmb.cn/pages/cn/rag_client/branch 在复杂的推理任务中,往往需要根据模型的中间输出或当前状态来决定后续流程是否继续执行。例如对模型的生成内容进行判断: * 若模型生成的是新的查询,则进入下一轮检索; * 若模型已输出最终答案,则终止流程。 为实现上述能力,UltraRAG 提供了分支结构,用于构建具备条件跳转逻辑的可控推理流程。 Router Server 是分支结构的搭档,它负责对当前状态进行判断并返回状态标签,驱动流程走向。 若你尚未了解如何实现 Router Tool,请参考 [Router Server](/pages/cn/rag_servers/router)。 ## 使用示例 ```yaml examples/rag_branch.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="22-37" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom router: servers/router # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - retriever.retriever_search - loop: times: 10 steps: - prompt.check_passages - generation.generate - branch: router: - router.check_model_state branches: continue: - prompt.gen_subq - generation.generate: output: ans_ls: subq_ls - retriever.retriever_search: input: query_list: subq_ls output: ret_psg: temp_psg - custom.merge_passages stop: [] - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 在分支结构中,Pipeline 使用以下关键字来定义动态流程的控制逻辑: * `branch`:声明一个分支结构的起点; * `router`:指定用于判断分支逻辑的 Router Tool,该工具需返回一个状态标签(如 incomplete / complete); * `branches`:定义每个状态对应的执行步骤序列。键为状态标签,必须与 Router Tool 返回的 state 值一致;值为该状态下需要执行的步骤列表(可为空,表示流程终止)。 # 数据流动 Source: https://ultrarag.openbmb.cn/pages/cn/rag_client/data_and_params 在 UltraRAG 中,Pipeline 通过变量名实现数据绑定:每个工具在注册时都会声明自身的输入参数与输出变量,而 Pipeline 在执行时,会依靠这些变量名在各步骤之间传递与共享数据。 这种机制简单直观,便于构建顺序化的数据流。但在多轮调用或复杂控制结构中,可能会出现变量名冲突或数据覆盖的问题。为此,UltraRAG 提供了参数重写机制,允许开发者在 Pipeline 灵活重命名变量而无需修改源码。 ## 数据如何流动? 每个工具在注册时都会声明自身的输入与输出变量名,从而确定数据流的入口与出口。例如: ```python Class Like Example icon="python" highlight={4} theme={null} def __init__(self, mcp_inst): mcp_inst.tool( self.retriever_search, output="q_ls,top_k->ret_psg", ) def retriever_search(self, q_ls, top_k) -> ... ... return {"ret_psg": ...} ``` ```python Decorate Like Example icon="python" highlight={2} theme={null} @app.tool( output="q_ls,top_k->ret_psg" ) def retriever_search(q_ls, top_k) -> ... ... return {"ret_psg": ...} ``` 这里的定义表示: * 工具接收两个输入变量:`q_ls` 和 `top_k` * 工具返回一个输出变量:`ret_psg` 如果你多次调用同一个工具(如 retriever\_search),并希望传入不同的数据变量(例如第一次为 q\_ls,第二次为 subq\_ls), 就需要一种方式告诉 Pipeline:这些变量其实是 **“同义词”**。 ## 参数重命名机制 为了解决变量名冲突与绑定歧义问题,UltraRAG 提供了灵活的 参数重命名机制。 你可以直接在 pipeline.yaml 中使用 `input:` 与 `output:` 字段, 显式指定参数与变量的映射关系——无需修改 Server 内部代码,即可完成数据绑定重定向。 ```yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} - module.tool: input: 函数形参名: Pipeline里的变量名 output: Tool输出键: Pipeline里的变量名 ``` 这套机制遵循“按名称显式绑定”原则: `input:` 映射函数的入参名,`output:` 映射工具注册时定义的输出键。 最简单的方式:在函数定义与工具注册时保持输入、输出参数名一致,可直接避免区分上述两种绑定规则。 ### 示例1:输入变量重命名 假设工具函数声明如下: ```python icon="python" theme={null} async def retriever_search( self, query_list: List[str], top_k: Optional[int] | None = None, query_instruction: str = "", use_openai: bool = False, ) -> Dict[str, List[List[str]]]: ``` 可以在 Pipeline 中显式重命名输入变量: ```yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} - retriever.retriever_search: input: query_list: sub_q_ls ``` 这里,工具原本期望接收名为 `query_list` 的输入参数,但我们通过 `input:` 将其映射为 Pipeline 中的变量 `sub_q_ls`,从而实现无缝绑定。 输入参数映射是根据函数声明中的参数名进行的。 ### 示例2:输出变量重命名 假设该工具在注册时定义如下: ```python icon="python" theme={null} mcp_inst.tool( self.retriever_search, output="q_ls,top_k,query_instruction,use_openai->ret_psg", ) ``` 可以在 Pipeline 中重写输出变量名: ```yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} - retriever.retriever_search: output: ret_psg: round1_result ``` 此时,无论函数内部返回变量名为何,只要注册时指定了输出键为 `ret_psg`, 该结果都会被映射为 `round1_result`,供后续步骤使用。 输出变量映射是根据工具注册时指定的输出键进行的。 如果下游模块依赖该输出结果: ```python icon="python" theme={null} @app.prompt(output="q_ls,ret_psg,template->prompt_ls") def qa_rag_boxed( q_ls: List[str], ret_psg: List[str | Any], template: str | Path ) -> list[PromptMessage]: ``` 则可以在 Pipeline 中显式完成输入重定向: ```yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} - prompt.qa_rag_boxed: input: ret_psg: round1_result ``` 这样,`qa_rag_boxed` 原本期望的输入 `ret_psg` 就会从上一步的 `round1_result` 中读取,实现数据传递。 ### 示例3:同时重写输入输出 ```yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} - retriever.retriever_search: input: q_ls: round1_query output: ret_psg: round1_result ``` 这种写法在循环结构中尤为常见——每一轮检索都可使用新的输入与输出变量,避免命名冲突。 合理使用参数重命名,可以在不修改源码的情况下让你的 RAG 流程在多轮迭代、动态分支等复杂场景下保持整洁与可控。 # 循环结构 Source: https://ultrarag.openbmb.cn/pages/cn/rag_client/loop 在多轮推理、多跳问答或多轮检索等任务中,单次执行流程往往无法获得理想的最终答案。此时可以使用循环结构,对特定模块进行重复执行,从而实现信息的逐步迭代与结果的持续优化。 ## 使用示例 ```yaml examples/rag_loop.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="16-28" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - retriever.retriever_search - loop: times: 3 steps: - prompt.gen_subq - generation.generate: output: ans_ls: subq_ls - retriever.retriever_search: input: query_list: subq_ls output: ret_psg: temp_psg - custom.merge_passages - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 在循环结构中,Pipeline 使用以下关键字来定义需要重复执行的工具模块: * `loop`:声明一个循环块,表示其内部的步骤将被重复执行; * `times`:指定循环的最大迭代次数; * `steps`:定义每一轮循环中需要执行的工具调用序列。 如果希望动态控制循环终止条件,可结合 分支结构(branch) 与 Router Server 使用,详见[分支结构](/pages/cn/rag_client/branch)。 # 模块复用 Source: https://ultrarag.openbmb.cn/pages/cn/rag_client/multi_agents 在许多实际场景中,你可能希望在同一个 Pipeline 中使用多个不同的 Retriever 或 Generation 模块,以执行不同的逻辑任务,例如混合检索或多智能体系统。 实际上,这只需要为相同的模块设置不同的参数即可完成。 为此,UltraRAG 提供了一种简单灵活的机制 —— 通过为同一个 Server 模块配置不同的别名,即可实现模块的复用与独立调用。 ## 使用示例 ### Step 1:配置别名 Server 在 `pipeline.yaml` 中,你可以在 `servers` 字段下为同一个路径定义多个别名: ```yaml examples/hybrid_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="4,5" theme={null} # MCP Server servers: benchmark: servers/benchmark dense: servers/retriever bm25: servers/retriever custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - dense.retriever_init - bm25.retriever_init - dense.retriever_search: output: ret_psg: dense_psg - bm25.bm25_search: output: ret_psg: sparse_psg - custom.merge_passages: input: ret_psg: dense_psg temp_psg: sparse_psg ``` 在该示例中,dense 和 bm25 都指向同一个模块路径 servers/retriever,但会作为两个独立的 Server 实例被构建与调用。 ### Step 2:在 Pipeline 中分别调用 在 Pipeline 定义部分,你可以像调用不同模块一样使用它们的别名: ```yaml examples/hybrid_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="11-18" theme={null} # MCP Server servers: benchmark: servers/benchmark dense: servers/retriever bm25: servers/retriever custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - dense.retriever_init - bm25.retriever_init - dense.retriever_search: output: ret_psg: dense_psg - bm25.bm25_search: output: ret_psg: sparse_psg - custom.merge_passages: input: ret_psg: dense_psg temp_psg: sparse_psg ``` 这样,UltraRAG 会在运行时自动区分这两个实例: 每个别名都对应独立的参数文件、运行上下文和缓存空间,从而实现多模块并行、互不干扰的调用。 # 流程控制 Source: https://ultrarag.openbmb.cn/pages/cn/rag_client/pipeline ## Pipeline 简介 在 UltraRAG 中,Pipeline 是用于定义“推理任务如何执行”的流程脚本,它就像一份“任务计划表”,用于明确系统每一步需要执行的操作。 你可以通过 Pipeline 将不同模块(Server)中的功能(Tool)灵活组合,从而构建出一个完整、可复现、可控的 RAG 推理流程。例如: * 加载数据 → 检索文档 → 构造 prompt → 调用大模型 → 评估结果; * 或者在多轮生成中,根据模型中间的表现决定是否重新检索或提前停止生成。 通过一份 YAML 文件,即可定义并运行完整的 RAG 推理流程。 ## 编写规范 在 UltraRAG 中,Pipeline 以 YAML 文件的形式编写,用于定义完整的任务执行流程。一个 Pipeline 文件通常由两个顶层结构组成: * `servers`:声明当前流程中所使用的所有 MCP Server 模块。每个 Server 对应一个功能模块(如检索、生成、评测等),键为模块名称,值为其在项目中的路径。 * `pipeline`:定义任务的执行逻辑。其中每一项表示一个执行步骤或流程控制节点,支持串行、循环与分支判断等控制结构。 ```yaml examples/rag_full.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` # 串型结构 Source: https://ultrarag.openbmb.cn/pages/cn/rag_client/serial 串型结构 是 Pipeline 中最基础、也最常用的执行方式。多个步骤按顺序依次执行,前一步的输出(若有)可以作为下一步的输入,也可以独立执行。构建一个标准的 RAG 工作流通常仅依靠串型结构即可完成,从数据加载到结果评估都能清晰衔接。 ## 使用示例 ```yaml examples/rag.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 在串型结构中,Pipeline 的每一行都表示一次对某个 Tool 的调用,其基本语法为: ```yaml theme={null} - server_name.tool_name ``` * `server_name`:调用的模块名称,必须在 servers 部分中提前声明; * `tool_name`:该模块中通过 @tool(...) 或 @prompt(...) 装饰器注册的函数名称。 这种结构适用于大多数单轮问答或推理任务,也是理解更复杂流程(如循环、分支)前的基础。 # Benchmark Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/benchmark ## 作用 Benchmark Server 用于加载评测数据集,常用于基准测试、问答任务或生成任务中的数据配置阶段。 我们强烈推荐将数据预处理为`.jsonl`格式。 示例数据: ```json data/sample_nq_10.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "question": "when was the last time anyone was on the moon", "golden_answers": ["14 December 1972 UTC", "December 1972"], "meta_data": {}} {"id": 1, "question": "who wrote he ain't heavy he's my brother lyrics", "golden_answers": ["Bobby Scott", "Bob Russell"], "meta_data": {}} {"id": 2, "question": "how many seasons of the bastard executioner are there", "golden_answers": ["one", "one season"], "meta_data": {}} {"id": 3, "question": "when did the eagles win last super bowl", "golden_answers": ["2017"], "meta_data": {}} {"id": 4, "question": "who won last year's ncaa women's basketball", "golden_answers": ["South Carolina"], "meta_data": {}} ``` ## 使用示例 ### 基本用法 ```yaml examples/load_data.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark # MCP Client Pipeline pipeline: - benchmark.get_data ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/load_data.yaml ``` 根据实际情况修改相应字段: ```yaml examples/parameters/load_data_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false ``` 运行以下命令执行该 Pipeline: ```shell theme={null} ultrarag run examples/load_data.yaml ``` 运行完成后,系统将自动加载并输出数据样本信息,为后续的检索与生成任务提供输入支持。 ### 新增加载数据集字段 在某些情况下,我们可能不仅需要加载 `query` 与 `ground_truth` 字段,还希望使用数据集中的其他信息,如已检索的 `passage`。 此时,可以通过修改 Benchmark Server 的代码,新增需要返回的字段。 你可以用相同方式扩展其他字段(例如 cot、retrieved\_passages 等),只需在装饰器输出与 key\_map 中同步添加对应键名即可。 如果你有生成好的结果(如 pred 字段),可以配合 [Evaluation Server](/pages/cn/rag_servers/evaluation) 一同使用,实现快速评估。 以下示例演示如何在 `get_data` 函数中新增 `id_ls` 字段: ```python servers/prompt/src/benchmark.py icon="python" theme={null} @app.tool(output="benchmark->q_ls,gt_ls") # [!code --] @app.tool(output="benchmark->q_ls,gt_ls,id_ls") # [!code ++] def get_data( benchmark: Dict[str, Any], ) -> Dict[str, List[Any]]: ``` 然后,运行以下命令重新编译 Pipeline: ```shell theme={null} ultrarag build examples/load_data.yaml ``` 在生成的参数文件中,添加字段 `id_ls` 并指定其在原始数据中的对应键名: ```yaml examples/parameters/load_data_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question id_ls: id # [!code ++] limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false ``` 完成修改后,重新运行 Pipeline 即可加载包含 id 的数据样本。 # Corpus Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/corpus ## 作用 Corpus Server 是 UltraRAG 中用于处理原始语料文档的核心组件。它支持从多种数据源中解析、提取并标准化文本或图像内容,并提供多种切块策略,将原始文档转换为可直接用于后续检索与生成的格式。 Corpus Server 的主要功能包括: * 文档解析:支持多种文件类型(如 .pdf、.txt、.md、.docx等)的内容提取。 * 语料构建:将解析后的内容保存为标准化的 .jsonl 结构,每行对应一个独立文档。 * 图像转换:支持将 PDF 页面转换为图像语料,保留版面与视觉结构信息。 * 文本切块:提供 Token、Sentence、Recursive等多种切分策略。 示例数据: 文本模态: ```json data/corpus_example.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": "2066692", "contents": "Truman Sports Complex The Harry S. Truman Sports...."} {"id": "15106858", "contents": "Arrowhead Stadium 1970s...."} ``` 图像模态: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "image_id": "UltraRAG/page_0.jpg", "image_path": "image/UltraRAG/page_0.jpg"} {"id": 1, "image_id": "UltraRAG/page_1.jpg", "image_path": "image/UltraRAG/page_1.jpg"} {"id": 2, "image_id": "UltraRAG/page_2.jpg", "image_path": "image/UltraRAG/page_2.jpg"} ``` ## 文档解析示例 ### 文本解析 Corpus Server 支持多种文本解析格式,包括 `.pdf、.txt、.md、.docx、.xps、.oxps、.epub、.mobi、.fb2` 等。 ```yaml examples/build_text_corpus.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: corpus: servers/corpus # MCP Client Pipeline pipeline: - corpus.build_text_corpus ``` 编译 Pipeline: ```shell theme={null} ultrarag build examples/build_text_corpus.yaml ``` 根据实际情况修改相应字段: ```yaml examples/parameters/build_text_corpus_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} corpus: parse_file_path: data/UltraRAG.pdf text_corpus_save_path: corpora/text.jsonl ``` 其中`parse_file_path` 可以是单个文件,也可以是文件夹路径——当指定为文件夹时,系统会自动遍历其中所有可解析文件并批量读取。 运行 Pipeline: ```shell theme={null} ultrarag run examples/build_text_corpus.yaml ``` 执行成功后,系统会自动解析文本并输出标准化语料文件,示例如下: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": "UltraRAG", "title": "UltraRAG", "contents": "xxxxx"} ``` ### PDF转图像 在多模态 RAG 场景中,[一类方法](https://arxiv.org/abs/2410.10594)是将文档页面直接转换为图像,并以完整图像形式进行检索与生成。 这种方式的优势在于能够保留文档的排版、格式与视觉结构,从而使检索和理解更贴近真实阅读场景。 ```yaml examples/build_image_corpus.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: corpus: servers/corpus # MCP Client Pipeline pipeline: - corpus.build_image_corpus ``` 编译 Pipeline: ```shell theme={null} ultrarag build examples/build_image_corpus.yaml ``` 根据实际情况修改相应字段: ```yaml examples/parameters/build_image_corpus_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} corpus: image_corpus_save_path: corpora/image.jsonl parse_file_path: data/UltraRAG.pdf ``` 同样地,`parse_file_path` 参数既可指定为单个文件,也可为文件夹路径。当设置为文件夹时,系统会自动遍历并处理其中的所有文件。 运行 Pipeline: ```shell theme={null} ultrarag run examples/build_image_corpus.yaml ``` 执行成功后,系统将保存生成的图像语料文件,每条记录包含图像标识符与相对路径,生成的 .jsonl 文件可直接作为多模态检索或生成任务的输入。输出示例如下: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "image_id": "UltraRAG/page_0.jpg", "image_path": "image/UltraRAG/page_0.jpg"} {"id": 1, "image_id": "UltraRAG/page_1.jpg", "image_path": "image/UltraRAG/page_1.jpg"} {"id": 2, "image_id": "UltraRAG/page_2.jpg", "image_path": "image/UltraRAG/page_2.jpg"} ``` ### MinerU解析 [MinerU](https://github.com/opendatalab/MinerU) 是业界广受好评的 PDF 解析框架,支持高精度的文本与版面结构提取。 UltraRAG 将 MinerU 无缝集成为内置工具,可直接在 Pipeline 中调用,实现一站式的 PDF → 文本 + 图像 语料构建。 ```yaml examples/build_mineru_corpus.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: corpus: servers/corpus # MCP Client Pipeline pipeline: - corpus.mineru_parse - corpus.build_mineru_corpus ``` 编译 Pipeline: ```shell theme={null} ultrarag build examples/build_mineru_corpus.yaml ``` 根据实际情况修改相应字段: ```yaml examples/parameters/build_mineru_corpus_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} corpus: image_corpus_save_path: corpora/image.jsonl # 图像语料保存路径 mineru_dir: corpora/ # MinerU 解析结果保存目录 mineru_extra_params: source: modelscope # 模型下载源(默认为 Hugging Face,可选 modelscope) parse_file_path: data/UltraRAG.pdf # 要解析的文件或文件夹路径 text_corpus_save_path: corpora/text.jsonl # 文本语料保存路径 ``` 同样地,`parse_file_path` 参数既可为单个文件,也可为文件夹路径。 运行 Pipeline(首次执行时需下载 MinerU 模型,速度较慢): ```shell theme={null} ultrarag run examples/build_mineru_corpus.yaml ``` 执行成功后,系统将自动输出对应的 文本语料 与 图像语料 文件,其格式与 `build_text_corpus` 和 `build_image_corpus` 一致,可直接用于多模态检索与生成任务。 ## 文档切块示例 UltraRAG 集成了 [chonkie](https://docs.chonkie.ai/common/welcome) 文档切块库,并内置三种主流切块策略:`Token Chunker`,`Sentence Chunker`以及`Recursive Chunker`,可灵活应对不同类型的文本结构。 * `Token Chunker`:按分词器、单词或字符进行分块,适用于一般文本。 * `Sentence Chunker`:按句子边界切分,保证语义完整性。 * `Recursive Chunker`:适用于结构良好的长文档(如书籍、论文),能自动按层级划分内容。 ```yaml examples/corpus_chunk.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: corpus: servers/corpus # MCP Client Pipeline pipeline: - corpus.chunk_documents ``` 编译 Pipeline: ```shell theme={null} ultrarag build examples/corpus_chunk.yaml ``` 根据实际情况修改相应字段: ```yaml examples/parameters/corpus_chunk_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" # 是否将标题附加到每个 chunk 开头 theme={null} corpus: chunk_backend: token # 切块策略,可选 token / sentence / recursive chunk_backend_configs: recursive: min_characters_per_chunk: 12 # 每块最小长度,防止过短 sentence: chunk_overlap: 50 # 相邻块重叠字符数 delim: '[''.'', ''!'', ''?'', ''\n'']' # 句子分隔符 min_sentences_per_chunk: 1 # 每块最少句子数 token: chunk_overlap: 50 # 相邻块重叠 token 数 chunk_path: corpora/chunks.jsonl # 输出切块后语料的保存路径 chunk_size: 256 # 每块最大 token 数 raw_chunk_path: corpora/text.jsonl # 原始文本语料路径 tokenizer_or_token_counter: character # 使用的分词器 use_title: false # 是否将标题附加到每个 chunk 开头 ``` 运行 Pipeline: ```shell theme={null} ultrarag run examples/corpus_chunk.yaml ``` 执行完成后,系统将输出标准化的切块语料文件,可直接用于后续检索与生成模块。 输出示例如下: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "doc_id": "UltraRAG", "title": "UltraRAG", "contents": "xxxxx"} {"id": 1, "doc_id": "UltraRAG", "title": "UltraRAG", "contents": "xxxxx"} {"id": 2, "doc_id": "UltraRAG", "title": "UltraRAG", "contents": "xxxxx"} ``` 你可以在同一 Pipeline 中同时调用解析工具与切块工具,以构建属于你自己的个性化知识库。 # Custom Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/custom ## 作用 Custom Server 用于存放那些无法归入标准模块(如 Retriever、Generation、Evaluation 等)的自定义工具函数。 它为开发者提供了一个灵活的扩展空间,可用于实现各种与核心 RAG 模块配合的逻辑组件,例如: * 数据清洗与预处理 * 关键词提取或特征构造 * 特定任务逻辑(如答案抽取、格式化、过滤等) Custom Server 是你的自由工具箱——任何不属于核心 Server 的功能逻辑,都可以在这里定义与复用。 ## 实现示例 下面以一个常见示例 output\_extract\_from\_boxed 为例,展示如何自定义并注册一个 Tool。 ```python servers/custom/src/custom.py icon="python" theme={null} @app.tool(output="ans_ls->pred_ls") def output_extract_from_boxed(ans_ls: List[str]) -> Dict[str, List[str]]: def extract(ans: str) -> str: start = ans.rfind(r"\boxed{") if start == -1: content = ans.strip() else: i = start + len(r"\boxed{") brace_level = 1 end = i while end < len(ans) and brace_level > 0: if ans[end] == "{": brace_level += 1 elif ans[end] == "}": brace_level -= 1 end += 1 content = ans[i : end - 1].strip() content = re.sub(r"^\$+|\$+$", "", content).strip() content = re.sub(r"^\\\(|\\\)$", "", content).strip() if content.startswith(r"\text{") and content.endswith("}"): content = content[len(r"\text{") : -1].strip() content = content.strip("()").strip() content = content.replace("\\", " ") content = content.replace(" ", " ") return content return {"pred_ls": [extract(ans) for ans in ans_ls]} ``` 该工具的功能是从模型输出字符串中提取 `\boxed{...}` 格式的最终答案文本, 输出结果会映射到变量 `pred_ls`,供下游评测或后处理模块使用。 ## 调用示例 定义好自定义工具后,只需在 Pipeline 中注册 custom 模块并调用对应的 Tool 即可: ```yaml examples/rag_full.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="8,20" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 在此示例中,custom.output\_extract\_from\_boxed 被用于从模型输出中提取标准化答案, 随后交由 evaluation.evaluate 进行评测。 # Evaluation Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/evaluation ## 作用 Evaluation Server 提供了一套完善的自动化评估工具, 用于对检索与生成任务的模型输出进行系统化、可复现的性能评测。 它支持多种主流指标,包括排序类、匹配类与摘要类评估,可直接嵌入 Pipeline 末尾,实现评估结果的自动计算与保存。 ### 检索 | 指标名 | 类型 | 说明 | | :---------- | :---- | :---------------------------------------------------------------- | | `MRR` | float | Mean Reciprocal Rank(平均倒数排名),衡量首个相关文档的平均排名位置。 | | `MAP` | float | Mean Average Precision(平均精确率),综合考虑检索的精确性与召回率。 | | `Recall` | float | 召回率,衡量检索系统能找回多少相关文档。 | | `Precision` | float | 精确率,衡量检索结果中有多少是相关文档。 | | `NDCG` | float | Normalized Discounted Cumulative Gain(标准化折损累计增益),评估检索结果与理想排序的一致性。 | ### 生成 | 指标名 | 类型 | 说明 | | :--------- | ----- | :-------------------------------------------- | | `EM` | float | Exact Match,预测与任一参考完全相同。 | | `Acc` | float | Answer 包含参考答案中的任一形式(宽松匹配)。 | | `StringEM` | float | 针对多组答案的软匹配比例(常用于多选/嵌套 QA)。 | | `CoverEM` | float | 参考答案是否完全被预测文本覆盖。 | | `F1` | float | Token 级别 F1 得分。 | | `Rouge_1` | float | 1-gram ROUGE-F1。 | | `Rouge_2` | float | 2-gram ROUGE-F1。 | | `Rouge_L` | float | Longest Common Subsequence (LCS) based ROUGE。 | ## 使用示例 ### 检索 #### Trec文件评估 在信息检索中,TREC 格式文件 是标准化的评测接口,用于衡量模型在排序、召回等方面的性能。 TREC 评估通常由两类文件组成:qrel(人工标注的真实相关性)与 run(系统检索输出结果)。 **一、qrel 文件(“ground truth”,人工标注的相关性)** qrel 文件用于存储“哪些文档与哪个查询是相关的”这类人工标注的真实相关性判断。\ 在评测时,系统输出的检索结果会与 qrel 文件进行对比,用来计算指标(如 MAP、NDCG、Recall、Precision 等)。 格式(4列,空格分隔): ``` ``` * `query_id`:查询编号 * `iter`:通常写 `0`(历史遗留字段,可忽略) * `doc_id`:文档编号 * `relevance`:相关性标注(通常 0 表示不相关,1 或更高表示相关) 示例: ``` 1 0 DOC123 1 1 0 DOC456 0 2 0 DOC321 1 2 0 DOC654 1 ``` **二、run 文件(系统输出的检索结果)** run 文件保存检索系统的输出结果,用于与 qrel 文件对比评估性能。\ 每行表示一个查询返回的文档及其得分信息。 格式(6列,空格分隔): ``` Q0 ``` * `query_id`:查询编号 * `Q0`:固定写 `Q0`(TREC 标准要求) * `doc_id`:文档编号 * `rank`:排序名次(1 表示最相关) * `score`:系统打分 * `run_name`:系统名称(例如 bm25、dense\_retriever) 示例: ``` 1 Q0 DOC123 1 12.34 bm25 1 Q0 DOC456 2 11.21 bm25 2 Q0 DOC654 1 13.89 bm25 2 Q0 DOC321 2 12.01 bm25 ``` 你可以点击以下链接下载示例文件:[qrels.test](https://github.com/usnistgov/trec_eval/blob/main/test/qrels.test) 和 [results.test](https://github.com/usnistgov/trec_eval/blob/main/test/results.test) ```yaml examples/eval_trec.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: evaluation: servers/evaluation # MCP Client Pipeline pipeline: - evaluation.evaluate_trec ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/eval_trec.yaml ``` ```yaml examples/parameters/eval_trec_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} evaluation: ir_metrics: - mrr - map - recall - ndcg - precision ks: - 1 - 5 - 10 - 20 - 50 - 100 qrels_path: data/qrels.txt # [!code --] run_path: data/run_a.txt # [!code --] qrels_path: data/qrels.test # [!code ++] run_path: data/results.test # [!code ++] save_path: output/evaluate_results.json ``` 运行以下命令执行该 Pipeline: ```shell theme={null} ultrarag run examples/eval_trec.yaml ``` #### 显著性分析 显著性分析(Significance Testing)用于判断两个检索系统之间的性能差异是否“真实存在”,而不是由随机波动造成。\ 它回答的核心问题是:系统 A 的提升是否具有统计学意义? 在检索任务中,系统的性能通常通过多个查询的平均指标(如 MAP、NDCG、Recall 等)衡量。\ 然而,平均值的提升并不一定可靠,因为不同查询间存在随机性。\ 显著性分析通过统计检验方法,评估系统改进是否稳定且可复现。 常见的显著性分析方法包括: * **置换检验(Permutation Test)**:通过随机交换系统 A 和系统 B 的查询结果多次(如 10000 次),构建差异的随机分布。若实际差异超过 95% 的随机情况(p \< 0.05),则认为提升显著。 * **t 检验(Paired t-test)**:假设两个系统的查询得分服从正态分布,计算两者均值差异的显著性。 UltraRAG 内置 双侧置换检验(Two-sided Permutation Test),在自动评估过程中输出以下关键统计信息: * **A\_mean / B\_mean** 表示新旧系统的平均指标; * **Diff(A-B)** 表示改进幅度; * **p\_value** 为显著性检验的概率; * **significant** 为显著性判断(p \< 0.05 时为 True)。 ```yaml examples/eval_trec_pvalue.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: evaluation: servers/evaluation # MCP Client Pipeline pipeline: - evaluation.evaluate_trec_pvalue ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/eval_trec_pvalue.yaml ``` ```yaml examples/parameters/eval_trec_pvalue_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} evaluation: ir_metrics: - mrr - map - recall - ndcg - precision ks: - 1 - 5 - 10 - 20 - 50 - 100 n_resamples: 10000 qrels_path: data/qrels.txt run_new_path: data/run_a.txt run_old_path: data/run_b.txt save_path: output/evaluate_results.json ``` 运行以下命令执行该 Pipeline: ```shell theme={null} ultrarag run examples/eval_trec_pvalue.yaml ``` ### 生成 #### 基本用法 ```yaml examples/rag_full.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="5,19" theme={null} servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 只需在 Pipeline 的末尾添加 evaluation.evaluate 工具,即可在任务执行完成后自动计算所有指定评测指标,并输出结果到配置文件中设定的路径。 #### 评估已有结果 如果你已经拥有模型生成的结果文件,并希望直接对其进行评估,可以将结果整理为标准化的 JSONL 格式。文件中应至少包含代表答案标签与生成结果的字段,例如: ```json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "question": "when was the last time anyone was on the moon", "golden_answers": ["14 December 1972 UTC", "December 1972"], "pred_answer": "December 14, 1973"} {"id": 1, "question": "who wrote he ain't heavy he's my brother lyrics", "golden_answers": ["Bobby Scott", "Bob Russell"], "pred_answer": "The documents do not provide information about the author of the lyrics to \"He Ain't Heavy, He's My Brother.\""} ``` ```yaml examples/evaluate_results.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark evaluation: servers/evaluation # MCP Client Pipeline pipeline: - benchmark.get_data - evaluation.evaluate ``` 为了让 Benchmark Server 读取生成结果,需要在 get\_data 函数中增加 `pred_ls` 字段: ```python servers/prompt/src/benchmark.py icon="python" theme={null} @app.tool(output="benchmark->q_ls,gt_ls") # [!code --] @app.tool(output="benchmark->q_ls,gt_ls,pred_ls") # [!code ++] def get_data( benchmark: Dict[str, Any], ) -> Dict[str, List[Any]]: ``` 然后,运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/evaluate_results.yaml ``` 在生成的参数文件中,新增字段 pred\_ls 并指定其在原始数据中的对应键名,同时修改数据路径和名称以指向新的评估文件: ```yaml examples/parameters/evaluate_results_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question pred_ls: pred_answer # [!code ++] limit: -1 name: nq # [!code --] path: data/sample_nq_10.jsonl # [!code --] name: evaluate # [!code ++] path: data/test_evaluate.jsonl # [!code ++] seed: 42 shuffle: false evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json ``` 运行以下命令执行该 Pipeline: ```shell theme={null} ultrarag run examples/evaluate_results.yaml ``` # Generation Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/generation ## 作用 Generation Server 是 UltraRAG 中负责 调用和部署大语言模型(LLM) 的核心模块。 它接收来自 Prompt Server 构建的输入提示(Prompt),并生成相应的输出结果。 该模块支持 文本生成 与 图像-文本多模态生成 两种模式,可灵活适配不同任务场景(如问答、推理、总结、视觉问答等)。 Generation Server 原生兼容以下主流后端:[vLLM](https://github.com/vllm-project/vllm)、[HuggingFace](https://github.com/huggingface/transformers) 以及 [OpenAI](https://platform.openai.com/docs/quickstart)。 ## 使用示例 ### 文本生成 以下示例展示了如何使用 Generation Server 执行一个基础的文本生成任务。该流程通过 Prompt Server 构建输入提示后,调用 LLM 生成回答,并最终完成结果提取与评估。 ```yaml examples/vanilla_llm.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="5,12,14" theme={null} # MCP Server servers: benchmark: servers/benchmark prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - generation.generation_init - prompt.qa_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/vanilla_llm.yaml ``` 修改参数: ```yaml examples/parameters/vanilla_llm_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false custom: {} evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json generation: backend: vllm backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 concurrency: 8 model_name: MiniCPM4-8B retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: template: prompt/qa_boxed.jinja ``` 运行 Pipeline: ```shell theme={null} ultrarag run examples/vanilla_llm.yaml ``` ### 多模态推理 在多模态场景下,Generation Server 不仅可以处理文本输入,还能结合图像等视觉信息完成更复杂的推理任务。下面通过一个示例展示如何实现。 我们先准备一个示例数据集(包含图像路径): ```json data/test.jsonl icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} {"id": 0, "question": "when was the last time anyone was on the moon", "golden_answers": ["14 December 1972 UTC", "December 1972"], "image":["image/page_0.jpg"],"meta_data": {}} ``` 在进行多模态生成前,需要在 Benchmark Server 的 `get_data` 函数中新增字段 `multimodal_path`, 用于指定图像输入路径。 如何新增字段请参考[新增加载数据集字段](/pages/cn/rag_servers/benchmark)。 ```yaml examples/vanilla_vlm.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="5,12,14" theme={null} # MCP Server servers: benchmark: servers/benchmark prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - generation.generation_init - prompt.qa_boxed - generation.multimodal_generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/vanilla_vlm.yaml ``` 修改参数: ```yaml examples/parameters/vanilla_vlm_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question multimodal_path: image # [!code ++] limit: -1 name: nq # [!code --] path: data/sample_nq_10.jsonl # [!code --] name: test # [!code ++] path: data/test.jsonl # [!code ++] seed: 42 shuffle: false custom: {} evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json generation: backend: vllm backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 concurrency: 8 model_name: MiniCPM4-8B retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B # [!code --] model_name_or_path: openbmb/MiniCPM-V-4 # [!code ++] trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false image_tag: null sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: template: prompt/qa_boxed.jinja ``` 运行: ```shell theme={null} ultrarag run examples/vanilla_vlm.yaml ``` 注意:你可以设置 `image_tag` 如 `` 来指定你希望图像输入的位置,为空默认为最左侧输入。 ### 部署模型 UltraRAG 完全兼容 OpenAI API 接口规范,因此任何符合该接口标准的模型都可以直接接入,无需额外适配或修改代码。 以下示例展示如何使用 [vLLM](https://docs.vllm.ai/en/latest/cli/serve.html#parallelconfig) 部署本地模型。 **step1: 后台部署模型** 以 Qwen3-32B 为例,建议使用多卡并行以保证推理速度。 **Screen (宿主机直接运行)** 1. 新建会话会话: ```shell theme={null} screen -S llm ``` 2. 启动命令: ```shell script/vllm_serve.sh theme={null} CUDA_VISIBLE_DEVICES=0,1 python -m vllm.entrypoints.openai.api_server \ --served-model-name qwen3-32b \ --model Qwen/Qwen3-32B \ --trust-remote-code \ --host 0.0.0.0 \ --port 65503 \ --max-model-len 32768 \ --gpu-memory-utilization 0.9 \ --tensor-parallel-size 2 \ --enforce-eager ``` 出现类似以下输出,表示模型服务启动成功: ``` (APIServer pid=2811812) INFO: Started server process [2811812] (APIServer pid=2811812) INFO: Waiting for application startup. (APIServer pid=2811812) INFO: Application startup complete. ``` 3. 退出会话:按下 `Ctrl + A + D` 可退出并保持服务在后台运行。 如需重新进入该会话,可执行: ```shell theme={null} screen -r llm ``` **Step 2:修改 Pipeline 参数** 修改参数: ```yaml examples/parameters/vanilla_llm_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false custom: {} evaluation: metrics: - acc - f1 - em - coverem - stringem - rouge-1 - rouge-2 - rouge-l save_path: output/evaluate_results.json generation: backend: vllm # [!code --] backend: openai # [!code ++] backend_configs: hf: batch_size: 8 gpu_ids: 2,3 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true openai: api_key: abc base_delay: 1.0 base_url: http://localhost:8000/v1 # [!code --] base_url: http://127.0.0.1:65501/v1 # [!code ++] concurrency: 8 model_name: MiniCPM4-8B # [!code --] model_name: qwen3-8b # [!code ++] retries: 3 vllm: dtype: auto gpu_ids: 2,3 gpu_memory_utilization: 0.9 model_name_or_path: openbmb/MiniCPM4-8B trust_remote_code: true extra_params: chat_template_kwargs: enable_thinking: false sampling_params: max_tokens: 2048 temperature: 0.7 top_p: 0.8 system_prompt: '' prompt: template: prompt/qa_boxed.jinja ``` 完成配置后,即可正常运行. # 模块概述 Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/overview ## Server 简介 在典型的 RAG 系统中,整体流程通常由多个功能模块组成,例如检索器(Retriever)、生成器(Generator)等。这些模块分别承担不同的任务,并通过流程编排协同工作,从而完成复杂的问答与推理过程。 在 UltraRAG 中,我们基于 MCP(Model Context Protocol) 架构,对这些功能模块进行了统一封装,提出了更加标准化的实现方式——Server。 Server 本质上就是一个具备独立功能的 RAG 模块组件。 每个 Server 封装一类核心任务逻辑(如检索、生成、评测等),并通过函数级别的 Tool 对外提供标准化接口。借助这一机制,Server 可以在完整的 Pipeline 中被灵活组合、调用与复用,从而实现模块化、可扩展的系统构建方式。 ## Server开发 为了帮助你更好地理解 Server 的使用方式,本节将通过一个简易示例,演示从零构建一个自定义 Server 的完整开发流程。 ### Step1:创建Server文件 首先,在`servers`文件夹下新建名为`sayhello`的文件夹,并在其中创建源码目录`sayhello/src`。然后,在 `src` 目录下新建文件 `sayhello.py`,作为 Server 的主程序入口。 在 UltraRAG 中,所有 Server 都通过基类 `UltraRAG_MCP_Server` 完成实例化。示例如下: ```python servers/sayhello/src/sayhello.py icon="python" theme={null} from ultrarag.server import UltraRAG_MCP_Server app = UltraRAG_MCP_Server("sayhello") if __name__ == "__main__": # Start the sayhello server using stdio transport app.run(transport="stdio") ``` ### Step2:实现工具函数(Tool) 使用 `@app.tool` 装饰器即可注册工具函数(Tool)。这些函数将在 Pipeline 执行过程中被调用,用于实现具体的功能逻辑。 例如,下面的示例定义了一个最简单的问候函数 `greet`,输入一个名字,返回相应的问候语: ```python servers/sayhello/src/sayhello.py icon="python" theme={null} from typing import Dict from ultrarag.server import UltraRAG_MCP_Server app = UltraRAG_MCP_Server("sayhello") @app.tool(output="name->msg") def greet(name: str) -> Dict[str, str]: ret = f"Hello, {name}!" app.logger.info(ret) return {"msg": ret} if __name__ == "__main__": # Start the sayhello server using stdio transport app.run(transport="stdio") ``` ### Step3:配置参数文件 接下来,在 `sayhello` 文件夹下创建参数配置文件 `parameter.yaml`。该文件用于声明工具(Tool)所需的输入参数及其默认值,方便在 Pipeline 运行时自动加载与传递。 示例如下: ```yaml servers/sayhello/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} name: UltraRAG v3 ``` 此处定义了参数 name,其默认值为 "UltraRAG v3"。 ### 参数注册机制 若不同 Prompt Tool 存在参数命名冲突,请参考 [Prompt Server](/pages/cn/rag_servers/prompt) 中的“多 Prompt Tool 调用场景”部分了解解决方案。 UltraRAG 在 build 阶段会自动读取每个 Server 目录下的 `parameter.yaml` 文件,并据此感知并注册工具函数所需的参数。在使用时需注意以下几点: * 参数共享机制:当多个 Tool 需要共用同一个参数(如 template、model\_name\_or\_path 等),可在 `parameter.yaml` 中仅声明一次并复用,无需重复定义。 * 字段覆盖风险:若多个 Tool 所需参数的名称相同但含义或默认值不同,应显式区分字段名,使用不同的名称,以避免在自动生成的配置文件中被覆盖。 * 上下文自动推断机制:若工具函数中的某些输入参数未出现在 ·parameter.yaml· 中,UltraRAG 会默认尝试从运行时上下文中推断(即从上游 Tool 的输出中获取)。因此,仅需在参数无法通过上下文自动传递时,才需要在 `parameter.yaml` 中显式定义。 ### 基于类封装共享变量 在某些场景下,我们可能希望在同一个 Server 内部维护共享状态或变量,例如模型实例、缓存对象、配置等。此时,可以将 Server 封装为一个类,并在类的初始化阶段完成共享变量的定义与 Tool 的注册。 以下示例展示了如何将 sayhello Server 封装为类,以实现内部变量共享: ```python servers/sayhello/src/sayhello.py icon="python" highlight="9" theme={null} from typing import Dict from ultrarag.server import UltraRAG_MCP_Server app = UltraRAG_MCP_Server("sayhello") class Sayhello: def __init__(self, mcp_inst: UltraRAG_MCP_Server): mcp_inst.tool(self.greet, output="name->msg") self.sen = "Nice to meet you" def greet(self, name: str) -> Dict[str, str]: ret = f"Hello, {name}! {self.sen}!" app.logger.info(ret) return {"msg": ret} if __name__ == "__main__": Sayhello(app) app.run(transport="stdio") ``` 在此示例中,`self.sen` 用于模拟需要在不同 `Tool` 之间共享的变量。这种方式特别适用于需要加载模型、重复配置参数的场景。 # Prompt Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/prompt ## 作用 Prompt Tool 是用于构建语言模型输入(Prompt)的核心组件。 每个 Prompt Tool 由 `@app.prompt` 装饰器定义,其主要职责是: 根据输入内容(如问题、检索到的段落等),加载对应的模板文件,并生成标准化的 PromptMessage, 以便直接传递给大语言模型(LLM)进行生成或推理。 ## 实现示例 ### Step 1:准备 Prompt 模板 请将你的 prompt 模板保存为 `.jinja` 结尾的文件,例如: ```jinja prompt/qa_rag_boxed.jinja icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/jinja.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=a15fd18398a4c6c7fac44f02ba3dbecc" theme={null} Please answer the following question based on the given documents. Think step by step. Provide your final answer in the format \boxed{YOUR_ANSWER}. Documents: {{documents}} Question: {{question}} ``` ### Step 2:在 Prompt Server 中实现 Tool 调用 `load_prompt_template` 方法加载模板,并在 Prompt Server 中实现一个工具函数用于组装 prompt: ```python servers/prompt/src/prompt.py icon="python" theme={null} @app.prompt(output="q_ls,ret_psg,template->prompt_ls") def qa_rag_boxed( q_ls: List[str], ret_psg: List[str | Any], template: str | Path ) -> list[PromptMessage]: template: Template = load_prompt_template(template) ret = [] for q, psg in zip(q_ls, ret_psg): passage_text = "\n".join(psg) p = template.render(question=q, documents=passage_text) ret.append(p) return ret ``` ## 调用示例 在调用模型生成工具前,需要先通过对应的 Prompt Tool 构建输入提示。 ```yaml examples/rag_full.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="3,16" theme={null} servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index - retriever.retriever_search - generation.generation_init - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` ## 多 Prompt Tool 调用场景 在一些复杂的 Pipeline 中,模型往往需要在不同阶段执行不同任务——例如,先生成子问题,再根据新的检索结果生成最终答案。 此时,就需要在同一 Pipeline 中配置多个 Prompt Tool,分别负责不同的提示构建逻辑。 ```yaml examples/rag_loop.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="19,29" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - retriever.retriever_search - loop: times: 3 steps: - prompt.gen_subq - generation.generate: output: ans_ls: subq_ls - retriever.retriever_search: input: query_list: subq_ls output: ret_psg: temp_psg - custom.merge_passages - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 若希望为不同任务加载不同模板,需在注册时为每个 Prompt Tool 指定独立的模板字段名: ```python servers/prompt/src/prompt.py icon="python" highlight="1,13" theme={null} @app.prompt(output="q_ls,ret_psg,template->prompt_ls") def qa_rag_boxed( q_ls: List[str], ret_psg: List[str | Any], template: str | Path ) -> list[PromptMessage]: template: Template = load_prompt_template(template) ret = [] for q, psg in zip(q_ls, ret_psg): passage_text = "\n".join(psg) p = template.render(question=q, documents=passage_text) ret.append(p) return ret @app.prompt(output="q_ls,ret_psg,gen_subq_template->prompt_ls") def gen_subq( q_ls: List[str], ret_psg: List[str | Any], template: str | Path, ) -> List[PromptMessage]: template: Template = load_prompt_template(template) all_prompts = [] for q, psg in zip(q_ls, ret_psg): passage_text = "\n".join(psg) p = template.render(question=q, documents=passage_text) all_prompts.append(p) return all_prompts ``` 随后,在 `servers/prompt/parameter.yaml` 中添加对应模板字段: 请确保在执行 build 命令前完成此修改。 ```yaml servers/prompt/parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # servers/prompt/parameter.yaml # QA template: prompt/qa_boxed.jinja # RankCoT kr_template: prompt/RankCoT_knowledge_refinement.jinja qa_template: prompt/RankCoT_question_answering.jinja # Search-R1 search_r1_gen_template: prompt/search_r1_append.jinja # R1-Searcher r1_searcher_gen_template: prompt/r1_searcher_append.jinja # For other prompts, please add parameters here as needed # Take webnote as an example: webnote_gen_plan_template: prompt/webnote_gen_plan.jinja webnote_init_page_template: prompt/webnote_init_page.jinja webnote_gen_subq_template: prompt/webnote_gen_subq.jinja webnote_fill_page_template: prompt/webnote_fill_page.jinja webnote_gen_answer_template: prompt/webnote_gen_answer.jinja gen_subq_template: prompt/gen_subq.jinja # [!code ++] ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build rag_loop.yaml ``` 系统会自动在生成的参数文件中注册新字段: ```yaml examples/rag_loop_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="3" theme={null} ... prompt: gen_subq_template: prompt/gen_subq.jinja template: prompt/qa_boxed.jinja retriever: backend: sentence_transformers ... ``` 随后即可正常执行该 Pipeline。 # Reranker Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/reranker ## 作用 Reranker Server 是 UltraRAG 中用于 对检索结果进行精排的模块。 它接收来自 Retriever Server 的初步检索结果,并基于语义相关性对候选文档进行重新排序, 从而提升检索阶段的精度与最终生成结果的质量。 该模块原生支持多种主流后端包括 [Sentence-Transformers](https://github.com/UKPLab/sentence-transformers)、 [Infinity](https://github.com/michaelfeil/infinity) 以及 [OpenAI](https://platform.openai.com/docs/guides/embeddings)。 ## 使用示例 ```yaml examples/corpus_rerank.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="5,14,15" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever reranker: servers/reranker # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index - retriever.retriever_search - reranker.reranker_init - reranker.reranker_rerank ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/corpus_rerank.yaml ``` 修改参数: ```yaml examples/parameters/corpus_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false reranker: backend: sentence_transformers backend_configs: infinity: bettertransformer: false device: cuda model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: device: cuda trust_remote_code: true batch_size: 16 gpu_ids: 0 model_name_or_path: openbmb/MiniCPM-Reranker-Light # [!code --] model_name_or_path: BAAI/bge-reranker-large # [!code ++] query_instruction: '' top_k: 5 retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: abc base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl embedding_path: embedding/embedding.npy gpu_ids: 0,1 # [!code --] gpu_ids: 1 # [!code ++] index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] overwrite: false query_instruction: '' top_k: 5 ``` 运行 Pipeline: ```shell theme={null} ultrarag run examples/corpus_rerank.yaml ``` # Retriever Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/retriever ## 作用 Retriever Server 是 UltraRAG 中的核心检索模块,集成了 模型加载、文本编码、索引构建与检索查询 等一体化功能。 它原生支持 [Sentence-Transformers](https://github.com/UKPLab/sentence-transformers)、[Infinity](https://github.com/michaelfeil/infinity) 以及 [OpenAI](https://platform.openai.com/docs/guides/embeddings) 等多种后端接口, 可灵活适配不同规模与类型的语料库,满足 大规模向量化 与 高效文档召回 的需求。 ## 使用示例 ### 语料库编码与索引 以下示例展示如何使用 Retriever Server 对语料库进行编码与索引构建。 ```yaml examples/corpus_index.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: retriever: servers/retriever # MCP Client Pipeline pipeline: - retriever.retriever_init - retriever.retriever_embed - retriever.retriever_index ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/corpus_index.yaml ``` 根据实际情况修改参数文件。下面分别展示两种典型场景:文本语料编码 与 图像语料编码。 1. 文本语料编码 示例:使用 `Qwen3-Embedding-0.6B` 对文本语料进行向量化。 ```yaml examples/parameters/corpus_index_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="2" theme={null} retriever: backend: sentence_transformers # 我们这里以st为例 backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl embedding_path: embedding/embedding.npy gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] overwrite: false ``` 2. 图像语料编码 示例:使用 `jinaai/jina-embeddings-v4` 对图像语料进行向量化。 ```yaml examples/parameters/corpus_index_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document # [!code --] psg_task: null # [!code --] q_prompt_name: query # [!code --] q_task: null # [!code --] psg_prompt_name: null # [!code ++] psg_task: retrieval # [!code ++] q_prompt_name: query # [!code ++] q_task: retrieval # [!code ++] trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl # [!code --] corpus_path: corpora/image.jsonl # [!code ++] embedding_path: embedding/embedding.npy gpu_ids: 0,1 # [!code --] gpu_ids: 1 # [!code ++] index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false # [!code --] is_multimodal: true # [!code ++] model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: jinaai/jina-embeddings-v4 # [!code ++] overwrite: false ``` 运行以下命令执行该 Pipeline: ```shell theme={null} ultrarag run examples/corpus_index.yaml ``` 编码与索引阶段通常涉及大规模语料处理,耗时较长。建议使用 `screen` 或 `nohup` 将任务挂载至后台运行,例如: ```shell theme={null} nohup ultrarag run examples/corpus_index.yaml > log.txt 2>&1 & ``` ### 向量检索 以下示例展示如何使用 Retriever Server 在已构建的索引上执行向量检索任务。 ```yaml examples/corpus_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.retriever_search ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/corpus_search.yaml ``` 修改参数: ```yaml examples/parameters/corpus_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false retriever: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] query_instruction: '' top_k: 5 ``` 运行 Pipeline: ```shell theme={null} ultrarag run examples/corpus_search.yaml ``` ### BM25检索 除了向量检索外,UltraRAG 还内置了经典的 BM25 文本检索算法。BM25 是一种基于 词频–逆文档频率(TF-IDF) 改进的 稀疏检索方法, 常用于快速、轻量的文本语义匹配任务。在实际应用中,BM25 可与向量检索(Dense Retrieval)互补,共同提升检索的覆盖率与召回多样性。 Step 1:构建 BM25 索引 使用 BM25 进行检索前,需要先对文档进行分词并构建稀疏索引。 ```yaml examples/bm25_index.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: retriever: servers/retriever # MCP Client Pipeline pipeline: - retriever.retriever_init - retriever.bm25_index ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/bm25_index.yaml ``` 修改参数: ```yaml examples/parameters/bm25_index_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} retriever: backend: sentence_transformers # [!code --] backend: bm25 # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light overwrite: false ``` 运行: ```shell theme={null} ultrarag run examples/bm25_index.yaml ``` Step 2:执行 BM25 检索 索引构建完成后,即可进行基于 BM25 的文档检索。 ```yaml examples/bm25_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - retriever.bm25_search ``` 编译 Pipeline: ```shell theme={null} ultrarag build examples/bm25_search.yaml ``` 修改参数: ```yaml examples/parameters/bm25_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false retriever: backend: sentence_transformers # [!code --] backend: bm25 # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light top_k: 5 ``` 运行检索流程: ```shell theme={null} ultrarag run examples/bm25_search.yaml ``` ### 混合检索 在实际应用中,单一的检索方式往往难以兼顾 召回率 与 精准度。 例如,BM25 在关键词匹配上表现出色,而向量检索则在语义理解上更具优势。 因此,UltraRAG 支持将稀疏检索(BM25)与稠密检索(Dense Retrieval)进行融合, 通过混合策略(Hybrid Retrieval)综合两者的优点,进一步提升检索的多样性与鲁棒性。 以下示例展示了如何在同一个 Pipeline 中同时运行 BM25 与向量检索,并通过自定义模块进行结果合并。 你可以参考本示例,将检索方式灵活扩展为任意组合,例如结合本地知识库与在线 Web 检索,或融合文本与图像等多模态检索结果,以构建更强大的混合检索 Pipeline。 ```yaml examples/hybrid_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark dense: servers/retriever bm25: servers/retriever custom: servers/custom # MCP Client Pipeline pipeline: - benchmark.get_data - dense.retriever_init - bm25.retriever_init - dense.retriever_search: output: ret_psg: dense_psg - bm25.bm25_search: output: ret_psg: sparse_psg - custom.merge_passages: input: ret_psg: dense_psg temp_psg: sparse_psg ``` 该 Pipeline 涉及 [参数重命名](/pages/cn/rag_client/data_and_params) 与 [模块复用](/pages/cn/rag_client/multi_agents) 机制,可点击链接查看详细说明。 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/hybrid_search.yaml ``` 修改参数: ```yaml examples/parameters/hybrid_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false bm25: backend: sentence_transformers # [!code --] backend: bm25 # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light top_k: 5 custom: {} dense: backend: sentence_transformers backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' base_url: https://api.openai.com/v1 model_name: text-embedding-3-small sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light # [!code --] model_name_or_path: Qwen/Qwen3-Embedding-0.6B # [!code ++] query_instruction: '' top_k: 5 ``` 运行混合检索 Pipeline: ```shell theme={null} ultrarag run examples/hybrid_search.yaml ``` ### 部署检索模型 UltraRAG 完全兼容 OpenAI API 接口规范,因此任何符合该接口标准的Embedding 模型都可以直接接入,无需额外适配或修改代码。 以下示例展示如何使用 [vLLM](https://docs.vllm.ai/en/latest/cli/serve.html#parallelconfig) 部署本地检索模型。 **step1: 后台部署模型** 推荐使用 Screen 方式后台运行,以便实时查看日志和状态。 进入一个新的 Screen 会话: ```shell theme={null} screen -S retriever ``` 执行以下命令部署模型(以 Qwen3-Embedding-0.6B 为例): ```shell script/vllm_serve_emb.sh theme={null} CUDA_VISIBLE_DEVICES=2 python -m vllm.entrypoints.openai.api_server \ --served-model-name qwen-embedding \ --model Qwen/Qwen3-Embedding-0.6B \ --trust-remote-code \ --host 0.0.0.0 \ --port 65504 \ --task embed \ --gpu-memory-utilization 0.2 ``` 出现类似以下输出,表示模型服务启动成功: ``` (APIServer pid=2270761) INFO: Started server process [2270761] (APIServer pid=2270761) INFO: Waiting for application startup. (APIServer pid=2270761) INFO: Application startup complete. ``` 按下 Ctrl + A + D 可退出并保持服务在后台运行。 如需重新进入该会话,可执行: ```shell theme={null} screen -r retriever ``` **Step 2:修改 Pipeline 参数** 以 corpus\_search Pipeline 为例,只需将检索后端切换为 openai, 并将 base\_url 指向本地 vLLM 服务即可: ```yaml examples/parameters/corpus_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false retriever: backend: sentence_transformers # [!code --] backend: openai # [!code ++] backend_configs: bm25: lang: en save_path: index/bm25 infinity: bettertransformer: false model_warmup: false pooling_method: auto trust_remote_code: true openai: api_key: '' # [!code --] api_key: 'abc' # [!code ++] base_url: https://api.openai.com/v1 # [!code --] base_url: http://127.0.0.1:65504/v1 # [!code ++] model_name: text-embedding-3-small # [!code --] model_name: qwen-embedding # [!code ++] sentence_transformers: sentence_transformers_encode: encode_chunk_size: 256 normalize_embeddings: false psg_prompt_name: document psg_task: null q_prompt_name: query q_task: null trust_remote_code: true batch_size: 16 collection_name: wiki corpus_path: data/corpus_example.jsonl gpu_ids: '1' index_backend: faiss index_backend_configs: faiss: index_chunk_size: 10000 index_path: index/index.index index_use_gpu: true milvus: id_field_name: id id_max_length: 64 index_chunk_size: 1000 index_params: index_type: AUTOINDEX metric_type: IP metric_type: IP search_params: metric_type: IP params: {} text_field_name: contents text_max_length: 60000 token: null uri: index/milvus_demo.db vector_field_name: vector is_demo: false is_multimodal: false model_name_or_path: openbmb/MiniCPM-Embedding-Light query_instruction: '' top_k: 5 ``` 完成配置后,即可像使用普通向量检索一样运行. ### Web Serach API UltraRAG 原生集成了三种主流 Web 检索 API:[Tavily](https://www.tavily.com/)、[Exa](https://exa.ai/) 以及 [GLM](https://docs.z.ai/guides/tools/web-search)。 这些 API 可直接作为 Retriever Server 的检索后端使用,实现在线信息检索与实时知识增强。 **Step 1:配置 API Key** 使用前需设置对应服务的 API Key。你可以在运行 Pipeline 前手动导出环境变量: ```shell theme={null} export TAVILY_API_KEY="your retriever key" ``` 更推荐使用 .env 配置文件 进行统一管理: 在 UltraRAG 根目录下,将模板文件 `.env.dev` 重命名为 `.env`, 并填写你的密钥信息,例如: ``` LLM_API_KEY= RETRIEVER_API_KEY= TAVILY_API_KEY=tvly-dev-yourapikeyhere EXA_API_KEY= ZHIPUAI_API_KEY= ``` UltraRAG 会在启动时自动读取该文件并加载相关配置。 **Step 2:Web Search** 以下示例演示如何使用 Tavily API 进行 Web 检索: ```yaml examples/web_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_tavily_search ``` 编译 Pipeline: ```shell theme={null} ultrarag build examples/web_search.yaml ``` 在自动生成的参数文件中,填写数据路径与检索参数: ```yaml examples/parameters/web_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false retriever: retrieve_thread_num: 1 top_k: 5 ``` 执行以下命令即可启动 Web 检索流程: ```shell theme={null} ultrarag run examples/web_search.yaml ``` 你可以将 retriever\_tavily\_search 替换为 retriever\_exa\_search 或 retriever\_zhipuai\_search 作为 Web 检索源。 ### 部署 Retriever Server 在同一语料库下测试多种 benchmark 或模型性能时,如果每次都重新初始化 retriever server,都会重复加载大型语料库和索引,耗时且低效。 为此,UltraRAG 提供了 常驻式 Retriever Server 部署脚本,可让 retriever 长时间运行在 CPU 或 GPU 上,避免重复加载,加速实验流程。 **step1: 参数设置** 与普通 retriever server 相同,需先准备配置文件: ```json script/deploy_retriever_config.json icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/json.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=81a8c440100333f3454ca984a5b0fe5a" theme={null} { "model_name_or_path": "openbmb/MiniCPM-Embedding-Light", "corpus_path": "data/corpus_example.jsonl", "collection_name": "ultrarag_embeddings", "backend": "sentence_transformers", "backend_configs": { "infinity": { "bettertransformer": false, "pooling_method": "auto", "model_warmup": false, "trust_remote_code": true }, "sentence_transformers": { "trust_remote_code": true, "sentence_transformers_encode": { "normalize_embeddings": false, "encode_chunk_size": 10000, "q_prompt_name": "query", "psg_prompt_name": "document", "psg_task": null, "q_task": null } }, "openai": { "model_name": "text-embedding-3-small", "base_url": "https://api.openai.com/v1", "api_key": "" }, "bm25": { "lang": "en", "save_path": "index/bm25" } }, "index_backend": "faiss", "index_backend_configs": { "faiss": { "index_use_gpu": true, "index_chunk_size": 50000, "index_path": "index/index.index" }, "milvus": { "uri": "index/milvus_demo.db", "token": null, "id_field_name": "id", "vector_field_name": "vector", "text_field_name": "contents", "id_max_length": 64, "text_max_length": 60000, "metric_type": "IP", "index_params": { "index_type": "AUTOINDEX", "metric_type": "IP" }, "search_params": { "metric_type": "IP", "params": {} }, "index_chunk_size": 50000 } }, "batch_size": 16, "gpu_ids": "0,1", "is_multimodal": false, "is_demo": false } ``` **step2: 后台部署** 推荐使用 Screen 以便让 retriever 后台长期运行、随时查看日志。 创建 Screen 会话: ```shell theme={null} screen -S retriever ``` 启动 retriever server: ```python script/deploy_retriever_server.py theme={null} python ./script/deploy_retriever_server.py \ --config_path script/deploy_retriever_config.json \ --host 0.0.0.0 \ --port 64501 ``` Server 启动后,将常驻内存,无需重复加载语料与索引。 **step3: 在线检索** 在线检索时,无需重新初始化 retriever,只需在 pipeline 中指定已部署的地址: ```yaml examples/deploy_corpus_search.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} # Deploy Corpus Search Demo # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_deploy_search ``` 运行以下命令编译 Pipeline: ```shell theme={null} ultrarag build examples/deploy_corpus_search.yaml ``` 修改参数: ```yaml examples/parameters/deploy_corpus_search_parameter.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" theme={null} benchmark: benchmark: key_map: gt_ls: golden_answers q_ls: question limit: -1 name: nq path: data/sample_nq_10.jsonl seed: 42 shuffle: false retriever: query_instruction: '' retriever_url: http://127.0.0.1:64501 top_k: 5 ``` 运行 Pipeline: ```shell theme={null} ultrarag run examples/deploy_corpus_search.yaml ``` # Router Source: https://ultrarag.openbmb.cn/pages/cn/rag_servers/router 本小节建议结合教程 [分支型结构](/pages/cn/rag_client/branch) 一起学习。 ## 作用 在复杂的 RAG 推理任务 中,常常需要根据中间结果(例如模型当前的生成内容或检索结果)动态决定后续执行路径。 Router Server 正是为此而设计的关键组件——它根据输入信息对当前状态进行判断,并返回一个自定义的分支标签(状态标识),用于驱动 Pipeline 中的分支跳转与动态控制。 ## 实现示例 下面通过一个简单示例,展示如何实现 Router Tool。 假设当前的 RAG 流程中,需要模型判断当前检索到的文档是否已包含足够信息回答问题:若信息充足则结束流程,否则继续执行检索。 可以这样实现一个 Router Tool: ```python servers/router/src/router.py icon="python" theme={null} @app.tool(output="ans_ls->ans_ls") def check_model_state(ans_ls: List[str]) -> Dict[str, List[Dict[str, str]]]: def check_state(text): if "" in text: return True else: return False ans_ls = [ { "data": answer, "state": "continue" if check_state(answer) else "stop", } for answer in ans_ls ] return {"ans_ls": ans_ls} ``` 该 Tool 会为每条回答打上状态标签,用于引导后续流程执行: * `continue`:信息不足,需继续检索; * `stop`:信息已足够,可终止流程。 ## 调用示例 定义好的 `Router Tool` 需要与分支结构 `branch:` 和 `router:` 搭配使用,共同实现基于状态标签的动态跳转。 ```yaml examples/rag_branch.yaml icon="https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3b" highlight="9,24,26,37" theme={null} # MCP Server servers: benchmark: servers/benchmark retriever: servers/retriever prompt: servers/prompt generation: servers/generation evaluation: servers/evaluation custom: servers/custom router: servers/router # MCP Client Pipeline pipeline: - benchmark.get_data - retriever.retriever_init - generation.generation_init - retriever.retriever_search - loop: times: 10 steps: - prompt.check_passages - generation.generate - branch: router: - router.check_model_state branches: continue: - prompt.gen_subq - generation.generate: output: ans_ls: subq_ls - retriever.retriever_search: input: query_list: subq_ls output: ret_psg: temp_psg - custom.merge_passages stop: [] - prompt.qa_rag_boxed - generation.generate - custom.output_extract_from_boxed - evaluation.evaluate ``` 该示例展示了一个典型的循环推理流程: 当 `router.check_model_state` 判断模型输出包含 `` 标识时,进入 `continue` 分支继续检索; 否则进入 `stop` 分支直接结束循环。 # 部署指南 Source: https://ultrarag.openbmb.cn/pages/cn/ui/prepare 本指南将指导您完成 UltraRAG UI 的全栈部署,包括生成模型(LLM)、检索模型(Embedding)以及 Milvus 向量数据库。 ## 模型推理服务部署 UltraRAG UI 统一采用 OpenAI API 协议进行调用。您可以选择直接在宿主机使用 `Screen` 运行,或使用 `Docker` 容器化部署。 ### 生成模型部署 以 Qwen3-32B 为例,建议使用多卡并行以保证推理速度。 **Screen (宿主机直接运行)** 1. 新建会话会话: ```shell theme={null} screen -S llm ``` 2. 启动命令: ```shell script/vllm_serve.sh theme={null} CUDA_VISIBLE_DEVICES=0,1 python -m vllm.entrypoints.openai.api_server \ --served-model-name qwen3-32b \ --model Qwen/Qwen3-32B \ --trust-remote-code \ --host 0.0.0.0 \ --port 65503 \ --max-model-len 32768 \ --gpu-memory-utilization 0.9 \ --tensor-parallel-size 2 \ --enforce-eager ``` 出现类似以下输出,表示模型服务启动成功: ``` (APIServer pid=2811812) INFO: Started server process [2811812] (APIServer pid=2811812) INFO: Waiting for application startup. (APIServer pid=2811812) INFO: Application startup complete. ``` 3. 退出会话:按下 `Ctrl + A + D` 可退出并保持服务在后台运行。 如需重新进入该会话,可执行: ```shell theme={null} screen -r llm ``` **Docker (容器化部署)** ```shell theme={null} docker run -d --gpus all \ -e CUDA_VISIBLE_DEVICES=0,1 \ -v /parent_dir_of_models:/workspace \ -p 29001:65503 \ --ipc=host \ --name vllm_qwen \ vllm/vllm-openai:latest \ --served-model-name qwen3-32b \ --model Qwen/Qwen3-32B \ --trust-remote-code \ --host 0.0.0.0 \ --port 65503 \ --max-model-len 32768 \ --gpu-memory-utilization 0.9 \ --tensor-parallel-size 2 \ --enforce-eager ``` ### 检索模型部署 以 Qwen3-Embedding-0.6B 为例,通常占用显存较小。 **Screen (宿主机直接运行)** 1. 新建会话: ```shell theme={null} screen -S retriever ``` 2. 启动命令: ```shell script/vllm_serve_emb.sh theme={null} CUDA_VISIBLE_DEVICES=2 python -m vllm.entrypoints.openai.api_server \ --served-model-name qwen-embedding \ --model Qwen/Qwen3-Embedding-0.6B \ --trust-remote-code \ --host 0.0.0.0 \ --port 65504 \ --task embed \ --gpu-memory-utilization 0.2 ``` **Docker (容器化部署)** ```shell theme={null} docker run -d --gpus all \ -e CUDA_VISIBLE_DEVICES=2 \ -v /parent_dir_of_models:/workspace \ -p 29002:65504 \ --ipc=host \ --name vllm_qwen_emb \ vllm/vllm-openai:latest \ --served-model-name qwen-embedding \ --model Qwen/Qwen3-Embedding-0.6B \ --trust-remote-code \ --host 0.0.0.0 \ --port 65504 \ --task embed \ --gpu-memory-utilization 0.2 ``` ## 向量数据库部署 (Milvus) Milvus 用于高效存储和检索向量数据。 **官方部署** ```shell theme={null} # milvus单机版(docker):https://milvus.io/docs/zh/install-overview.md#Milvus-Standalone curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.sh bash standalone_embed.sh start ``` **自定义部署** 若需自定义端口(如防止端口冲突)或数据路径,可使用以下脚本: ```shell start_milvus.sh highlight="7,8,10" theme={null} #!/usr/bin/env bash set -e CONTAINER_NAME=milvus-ultrarag MILVUS_IMAGE=milvusdb/milvus:latest GRPC_PORT=29901 HTTP_PORT=29902 DATA_DIR=/root/ultrarag-demo/milvus/ echo "==> Starting Milvus (standalone)" echo "==> gRPC: ${GRPC_PORT}, HTTP: ${HTTP_PORT}" echo "==> Data dir: ${DATA_DIR}" mkdir -p ${DATA_DIR} chown -R 1000:1000 ${DATA_DIR} 2>/dev/null || true docker run -d \ --name ${CONTAINER_NAME} \ --restart unless-stopped \ --security-opt seccomp:unconfined \ -e DEPLOY_MODE=STANDALONE \ -e ETCD_USE_EMBED=true \ -e COMMON_STORAGETYPE=local \ -v ${DATA_DIR}:/var/lib/milvus \ -p ${GRPC_PORT}:19530 \ -p ${HTTP_PORT}:9091 \ --health-cmd="curl -f http://localhost:9091/healthz" \ --health-interval=30s \ --health-start-period=60s \ --health-timeout=10s \ --health-retries=3 \ ${MILVUS_IMAGE} \ milvus run standalone echo "==> Waiting for Milvus to become healthy..." sleep 5 docker ps | grep ${CONTAINER_NAME} || true ``` 修改GRPC\_PORT、HTTP\_PORT以及DATA\_DIR,并运行以下命令进行部署: ```shell theme={null} bash start_milvus.sh ``` 部署成功后,您可以通过以下命令检查Milvus的状态: ```shell theme={null} docker ps | grep milvus-ultrarag ``` 如果一切正常,您应该能够看到Milvus容器正在运行。 UI 配置提示:启动成功后,在 UltraRAG UI 的 `Knowledge Base` -> `Configure DB` 中填写 `GRPC_PORT` 地址(如 `tcp://127.0.0.1:29901`)。点击 Connect 显示 Connected 即代表成功。 # 快速开始 Source: https://ultrarag.openbmb.cn/pages/cn/ui/start UltraRAG UI 不仅仅是一个聊天界面,它是一个完整的 RAG 开发与调试平台。 ## 启动命令 使用以下命令启动 UI 服务: ```bash theme={null} ultrarag show ui [OPTIONS] ``` ### 常用选项 * `--port `: 指定服务端口,默认为 `5050`。 * `--host `: 指定绑定地址,默认为 `127.0.0.1`。 * `--admin`: 启用管理员模式。默认情况下 UI 仅展示对话界面(Chat Only)。开启此选项后,将解锁 Pipeline Builder(可视化编排)、参数配置与在线 Prompt 编辑功能。此外,管理员界面内置了 AI 助手,可辅助您高效完成 Pipeline 的配置与调试。 ### 示例 **启动完整功能的 Admin 模式:** ```bash theme={null} ultrarag show ui --admin ``` **仅启动对话界面(适合最终用户):** ```bash theme={null} ultrarag show ui ``` 启动后,在浏览器访问 `http://127.0.0.1:5050` 即可进入系统。 ## 1. Chat(对话) 进入系统默认展示对话页面,您可以直接选择已编译的 Pipeline 开启对话。 我们在[典型场景](/pages/cn/demo/llm)中提供了多个开发好的 Pipeline 的部署教程,您也可以根据需求自定义 Pipeline。 ### Pipline 切换 通过左上角的下拉菜单,可以在已配置好参数的 Pipeline 之间快速切换。 ### 选择知识库 点击 Knowledge Base 图标,挂载已构建的知识库,即可进行基于文档的问答。 ### 后台运行 针对 Deep Research 等耗时较长的 Pipeline,支持后台运行模式。任务执行完成后,结果将自动加载至当前聊天窗口。 ## 2. Knowledge Base UltraRAG UI 提供了全流程的知识库管理功能,支持文件的上传、切片(Chunking)及向量化(Embedding)管理。 ### 连接向量库 不知道如何部署 Milvus 向量库? 请参考[部署指南](/pages/cn/ui/prepare)。 点击 Configure DB,与部署好的 Milvus 向量库建立连接,即可使用知识库功能。 ### 构建知识库 点击 New Collection,上传文档并创建专属知识库。 点击 Settings 按钮,可自定义切片策略(Chunk)和 Embedding 模型的相关参数。 首次使用通常需要配置参数。若希望实现免配置部署(用户无需手动设置),请预先修改`examples/parameter/corpus_chunk_parameter.yaml`与`examples/parameter/milvus_index_parameter.yaml`中的相关参数,即可跳过下方设置步骤。 ## 3. Pipeline Builder 若启动时指定了 `--admin` 参数,侧边栏将显示 Settings 入口,点击即可进入高级配置页面。 ### Pipeline 可视化搭建 支持左侧画布拖拽式编排与右侧代码编辑器的双向实时同步。您既可以像搭积木一样直观构建,也可以在代码编辑器中进行精细微调。 ### 配置参数 点击 Build 按钮解析 Pipeline 后,您可以在参数面板中查看并修改运行参数。 ### Prompt 管理 支持在线新建、编辑及删除 Prompt,并将其一键应用到 Pipeline 中。 ### Ai 助手 系统内置了 AI 助手,可辅助您搭建 Pipeline、调整参数及编写 Prompt。 首次使用该功能前,需先点击设置配置 API Key 及相关模型参数。 **使用示例:优化 Prompt** 假设您已有一个基础 Prompt,希望将其调整为适配法律领域的风格: 1. 打开 AI 助手,输入原始 Prompt 及修改需求。 2. 点击 Apply,AI 助手将自动生成优化后的内容并替换原有 Prompt。