Skip to content

Knowledge base guide ​

RuoYi AI knowledge bases manage documents, retrieve relevant content, and provide reference material for agents and workflows. Upload business documents, inspect parsed fragments, test retrieval, and then attach the knowledge base to an application.

Supported capabilities ​

CapabilityWhat it doesInstructions
Document management and parsingUpload, parse automatically or manually, inspect fragments, and reparse updated material.Upload and parse, Maintenance.
Retrieval testingInspect matching fragments, sources, and relevance scores; adjust threshold and result count.Retrieval test.
Retrieval tuningCombine semantic and keyword search, or rerank candidate fragments.Tune retrieval.
Knowledge-based answersAttach one or more knowledge bases to an agent so its chat model can use retrieved material.Attach an agent.
Workflow and API integrationUse a retrieval node or pass a knowledge-base ID from a custom chat frontend.Integration.

Uploads support text, Markdown, PDF, Word, Excel, CSV, JSON, and various source-code formats. The current user app accesses knowledge through agents; ordinary chat has no direct knowledge-base selector.

How knowledge participates in an answer ​

Knowledge-based chat uses RAG (Retrieval-Augmented Generation): retrieve relevant material first, then ask a chat model to compose the answer. Parsing, retrieval testing, and answer generation are separate stages.

ConceptMeaning
Knowledge base and fragmentsA knowledge base groups documents and retrieval settings. Parsing splits documents into smaller fragments used for retrieval.
Embedding model and vector storeThe model converts documents and questions into numerical representations; the store keeps those vectors for similarity search.
Retrieval and rerankingRetrieval finds candidates; an optional reranker scores and orders them again. Hybrid retrieval combines semantic similarity and keyword matching.
Chat modelReads the question and retrieved fragments to generate an answer. A retrieval test only checks fragments.

Documents must be parsed and embedded before retrieval. Confirm fragment content and retrieval first, then evaluate the model's answer.

Follow environment and models → create a knowledge base → upload and parse → test retrieval → ask through the user app. Sections 1–6 cover first use; tuning and maintenance follow. Code excerpts identify APIs and can be skipped when following the UI steps.

The current revision checked page entry points and source code. Successful parsing and retrieval screenshots are from an earlier run; end-to-end verification could not be repeated in the revision environment. See verification notes.

1. Open the admin console and prepare services ​

Follow Local installation, sign in to the admin console, and open Chat Management → Knowledge Management.

Use the following addresses, or the actual ports in your startup logs. 5173 is reserved for documentation.

ApplicationLocal addressRole
Admin consolelocalhost:5666Models, documents, retrieval tests, and agent associations.
User applocalhost:5180Select an agent from the market and ask questions.
Backendhttp://127.0.0.1:6039Upload, parsing, retrieval, and model calls.

If needed, start the frontends in separate terminals, replacing checkout paths:

powershell
# 管理端
cd D:\Project\github\ruoyi-admin
pnpm run dev:antd
powershell
# 用户端,避开文档站点的 5173 端口
cd D:\Project\github\ruoyi-web
pnpm run dev --port 5180

Before uploading, check:

DependencyRequirement
MySQLInitialization and applicable migrations from the installation guide, including knowledge_attach.file_hash and knowledge_fragment.fid.
Object storageA usable default under System Management → File Management → File Configuration; local examples use MinIO.
Vector storeLocal examples use Weaviate at backend-configured 127.0.0.1:28080.
Embedding modelAt least one model that actually produces vectors.

Object storage holds originals; the vector store holds retrieval vectors. Both must be available. A loaded admin page does not prove parsing dependencies are running.

2. Prepare embedding and chat models ​

The basic flow needs an embedding model and a chat model. Reranking can wait:

ModelPurposeSelection
Embedding (vector)Convert documents and questions into vectors.Knowledge base's Embedding model.
Chat (chat)Compose an answer from retrieved fragments.Agent's Bound model in section 6.
Rerank (rerank, optional)Reorder retrieved candidates.Enable after the basic flow works.

2.1 Configure models ​

Configure the service in Provider Management, then add or inspect its models in Model Management. See Model management for addresses and credentials. Categories come from chat_model_category; add missing values through the category dictionary. A chat model cannot serve as an embedding model simply by changing its category.

The retained local retrieval screenshots use the following Ollama configuration. Its HTTP URL belongs to the earlier runtime; new records must also satisfy the current save rules below.

FieldExample
Providerollama
CategoryEmbedding (vector)
Model nameall-minilm:v2
DescriptionFor example, Ollama local embeddings.
Dimension384
API Hosthttp://127.0.0.1:11434, for a backend on the host machine.
KeyEmpty in the local Ollama example.

See the local embedding example for installation and model downloads. A containerized backend needs an address reachable from its container; 127.0.0.1 inside a container refers to itself.

New configurations must satisfy current save rules

Local Ollama can use an HTTP or HTTPS address reachable by the backend. Leave the Key empty for services without authentication. The Ollama embedding adapter does not read a Key; authenticated gateways still require adapter support. Enter the actual API Key for cloud embedding providers such as Qianwen directly in ruoyi-admin Model Management. See Model management.

A dropdown entry only confirms the record exists. Local services must be running with the model downloaded; cloud credentials must match the actual adapter.

2.2 Why only embedding models appear ​

The Add Knowledge Base form loads category vector, displays descriptions, and saves model names. See ruoyi-admin/apps/web-antd/src/views/knowledge/info/components/KnowledgeAddModal.vue:

ts
const response = await modelList({ category: 'vector', pageSize: 1000 });
const models = Array.isArray(response)
  ? response
  : (response.rows || response.records || []);
embeddingModelOptions.value = models.map((model: any) => ({
  label: model.modelDescribe || model.modelName,
  value: model.modelName,
}));

Parsing looks up that name. For example, OllamaEmbeddingProvider.embedAll() calls the configured URL and model:

java
EmbeddingModel model = OllamaEmbeddingModel.builder()
        .baseUrl(chatModelVo.getApiHost())
        .modelName(chatModelVo.getModelName())
        .build();

return model.embedAll(textSegments);

It does not call a chat model. Documents and queries in one knowledge base must use the same embedding model, even if another model has the same dimension. With Milvus, collection dimensions must also match actual output.

3. Create a knowledge base and configure splitting ​

Download the project-information sample for this walkthrough. It is intentionally retained in Chinese to match the recorded tests: the Beichen project (北辰项目) uses backend port 6039, and its release owner is Lin Xiaoman (林小满). Use this small file before importing business material.

3.1 Fill in the Add form ​

Open Chat Management → Knowledge Management → Add:

FieldExampleNotes
NameRAG document verificationSeparate it from production material; select the same name when attaching an agent.
PublicNoNot required for agent association.
Vector storeWeaviateMatch the deployed service.
Embedding modelThe verified model from section 2Check explicitly; the dropdown may default to its first option.
RerankingOffVerify basic retrieval first.
Hybrid searchOffStart with vector retrieval.
Result count5Starting value for this sample.
DescriptionVerify retrieval and answers for Beichen project materialIdentify the purpose.

Add Knowledge Base form showing store, model, and retrieval fields

This form was opened but not submitted in the revision environment, where embedding-3 was selected by default. Choose your verified model; an option's presence does not prove a working call.

Save, find the new row, and open Details. A document count of zero is expected initially.

3.2 Set splitting options in Knowledge Base Configuration ​

Details has File Management, Retrieval Test, and Knowledge Base Configuration tabs. Open configuration, set the following, and click Save update. Chunk size and overlap are not in the Add dialog.

FieldValuePurpose
Chunk size300Small searchable pieces for this short sample.
Overlap30Preserve context across fragment boundaries.
SeparatorKeep the existing newline configurationActual splitting also depends on file type and splitter.
Similarity threshold0Establish a result first, then raise based on quality.
Result count5Match the test settings.

Earlier Ollama knowledge-base configuration with splitting and retrieval options

DocumentSplitConfig validates that overlap is smaller than chunk size:

java
if (blockSize <= 0) {
    throw new ServiceException("文本块大小必须大于0");
}
if (overlap < 0 || overlap >= blockSize) {
    throw new ServiceException("重叠字符数必须大于等于0且小于文本块大小");
}

Custom frontends use POST /system/info to add and PUT /system/info to update. Updates also need the actual id:

json
{
  "name": "RAG 文档验证知识库",
  "share": 0,
  "vectorModel": "weaviate",
  "embeddingModel": "all-minilm:v2",
  "textBlockSize": 300,
  "overlapChar": 30,
  "retrieveLimit": 5,
  "similarityThreshold": 0,
  "enableHybrid": 0,
  "enableRerank": 0
}

Despite its name, vectorModel stores the vector-store type; embeddingModel stores the embedding model name. Creation currently returns an operation status; the admin refreshes the list to find the new row. Do not assume the response contains its ID.

4. Upload documents and inspect parsed fragments ​

4.1 Upload a file ​

In File Management:

  1. Click Upload document.
  2. Leave Automatic parsing enabled.
  3. Select rag-verification-sample.md.
  4. Check the pending file and click Confirm and save.

Earlier upload dialog with the sample selected and automatic parsing enabled

FileManagement.vue builds FormData per file, including the knowledge-base ID and parsing switch:

ts
const formData = new FormData();
const rawFile = file.originFileObj || file;
formData.append('file', rawFile);
formData.append('knowledgeId', String(props.knowledgeId));
formData.append('autoParse', String(autoParse.value));
await requestClient.post('/system/attach/upload', formData);

requestClient handles login authentication. A custom upload client also needs the current application's authentication headers; a model provider API key is not a RuoYi AI login token.

The backend hashes content with SHA-256 and deduplicates by knowledge-base ID plus digest. Renaming identical content does not make it a new file. Reparse with the row's Parse action instead of reuploading. Existing databases need the relevant columns and unique index from the installation guide.

4.2 Wait for parsing ​

The file appears after upload while parsing continues asynchronously. Click Refresh later:

StateMeaningAction
PendingSaved but not parsed.Click Parse if automatic parsing was disabled.
ParsingReading, splitting, embedding, and saving.Wait and refresh.
ParsedThis parse completed.Check chunk count and open Knowledge fragments.
FailedA parsing-stage error occurred.Hover the status for details and inspect backend logs.

Earlier successful parsing with a nonzero fragment count

Successful upload and completed parsing are different. KnowledgeAttachServiceImpl.upload() saves the attachment and starts parsing asynchronously through the Spring proxy:

java
baseMapper.insert(knowledgeAttach);

if (Boolean.TRUE.equals(bo.getAutoParse())) {
    SpringUtils.getBean(IKnowledgeAttachService.class)
        .parse(knowledgeAttach.getId());
}

parse() uses @Async("knowledgeParseExecutor"). It reads the original from object storage, selects a loader, splits with current settings, and writes vectors and fragments. This excerpt shows writes; see the full method for setup and failure cleanup:

java
vectorStoreService.removeByDocId(docId, String.valueOf(knowledgeId));
vectorStoreService.storeEmbeddings(storeEmbeddingBo);

// 向量写入成功后,替换该文件的片段记录。
knowledgeFragmentMapper.delete(Wrappers.<KnowledgeFragment>lambdaQuery()
    .eq(KnowledgeFragment::getDocId, docId));
knowledgeFragmentMapper.insertBatch(knowledgeFragmentList);
knowledgeRetrievalService.invalidateKnowledge(String.valueOf(knowledgeId));

attach.setStatus(KnowledgeAttachStatus.COMPLETED.getCode());
baseMapper.updateById(attach);

4.3 Inspect fragment content ​

Open Knowledge fragments on the sample row. Find the Beichen project fragment and check that it contains 6039 and 林小满. Open details if the preview is truncated.

Earlier fragments containing the sample's project facts

Before retrieval, require all three: Parsed status, more than zero fragments, and the original text present. Otherwise resolve parsing first.

Supported upload formats include text, Markdown, PDF, Word, Excel, CSV, JSON, and code. Start with the small Markdown sample. For scans or complex layouts, inspect extracted text. Folder and GitHub loaders exist in the backend, but the upload dialog has no corresponding import entry.

5. Test retrieval before generating answers ​

5.1 Ask a question with a known answer ​

In Retrieval Test, enter:

text
北辰项目的后端服务端口和发布负责人分别是什么?

This asks for the project's backend port and release owner. Set threshold 0, Top K 5, hybrid search off, and reranking off, then start the test.

Recheck test-page parameters

RetrievalTest.vue initially uses local defaults including threshold 0.5 and Top K 10; it does not load all saved knowledge-base retrieval settings automatically. Check them even if you saved settings earlier.

The test returns fragments, not a generated answer. Check:

  1. Content includes both correct facts.
  2. Source is rag-verification-sample.md.
  3. Relevant fragments rank near the top; open them for full content.

Earlier retrieval matching the sample, including 6039 and the release owner

The earlier test used all-minilm:v2, threshold 0, Top K 5, and scored about 48.7%. This is a retrieval relevance measure, not answer accuracy, and is not a universal threshold for other embedding models.

5.2 What the test sends ​

RetrievalTest.vue calls POST /system/fragment/retrieval:

ts
const res = await knowledgeRetrieval({
  knowledgeId: props.knowledgeId,
  query: query.value,
  topK: config.value.topK,
  threshold: config.value.similarityThreshold,
  enableRerank: config.value.enableRerank,
  rerankModel: config.value.rerankModelName,
  enableHybrid: config.value.enableHybridSearch,
  hybridAlpha: config.value.hybridAlpha,
});

KnowledgeFragmentServiceImpl.retrieval() loads the knowledge base and embedding configuration, then calls the shared retrieval service. Request parameters override saved settings; omitted values fall back:

java
queryVectorBo.setMaxResults(bo.getTopK() != null
    ? bo.getTopK() : knowledgeInfoVo.getRetrieveLimit());
queryVectorBo.setSimilarityThreshold(bo.getThreshold() != null
    ? bo.getThreshold() : knowledgeInfoVo.getSimilarityThreshold());

return knowledgeRetrievalService.retrieve(queryVectorBo);

5.3 Apply working parameters to the knowledge base ​

Click Apply to knowledge-base configuration, confirm, then inspect the saved configuration. Moving sliders and testing alone does not change settings used by subsequent chat.

The action reads the latest record, merges fields, and calls infoUpdate(). The merge in handleApplyConfig() is:

ts
const updatedData = {
  ...record,
  retrieveLimit: config.value.topK,
  similarityThreshold: config.value.similarityThreshold,
  enableHybrid: config.value.enableHybridSearch ? 1 : 0,
  hybridAlpha: config.value.hybridAlpha,
  enableRerank: config.value.enableRerank ? 1 : 0,
  rerankModel: config.value.rerankModelName,
};
await infoUpdate(updatedData);

For reranking, the test uses Top K and threshold for rerank count and filtering too, but Apply does not currently write separate rerankTopN or rerankScoreThreshold. Retest actual chat after tuning; the two paths are not necessarily identical.

6. Attach an agent and ask through the user app ​

6.1 Attach the knowledge base in the admin console ​

Ordinary ruoyi-web chat has no direct knowledge selector. Use an agent:

  1. Open Agent Management → Agent List and add a verification agent.
  2. Use a name such as Project material assistant and description Project material Q&A; the user card displays the description.
  3. Bind a verified chat model, not the all-minilm:v2 embedding model.
  4. Select the knowledge base under Associated knowledge bases. Multiple associations are retrieved separately and merged.
  5. Leave extra MCP tools and skills unselected for this check, choose normal/enabled status, enter a prompt, and save.

Start with this prompt, which instructs the assistant to use the supplied project material:

text
你是项目资料助手。根据当前问题附带的知识库资料回答,
保留端口号、人名和时间等事实。资料中没有答案时,明确说明未找到,
不要猜测,也不要为了补充答案调用无关工具。

See Agents for the full form. The selector is defined in ruoyi-admin/apps/web-antd/src/views/agent/agent/data.tsx:

ts
component: 'ApiSelect',
componentProps: {
  api: agentKnowledgeOptions,
  resultField: 'rows',
  labelField: 'name',
  valueField: 'id',
  mode: 'multiple',
  placeholder: '请选择关联的知识库',
},
fieldName: 'knowledgeIds',
label: '关联知识库',

Associations save an array of knowledge-base IDs, not names.

6.2 Verify the answer ​

  1. Sign in to the user app.
  2. Open Application Market, find your agent's description, and choose Start using.
  3. Confirm the agent is selected near the input, rather than an ordinary model.
  4. Send the same question from section 5.
  5. Check for 6039 and 林小满, without an invented project name or owner.

Then ask something absent from the sample, such as the production database password. The answer should say the material does not provide it. Prompts express the requirement; actual behavior must still be checked.

If wrong, return to retrieval. Missing facts point to splitting, embeddings, or retrieval settings. Correct fragments with a wrong answer point to agent selection, associations, or the chat model's use of context.

6.3 How knowledge reaches chat ​

The user app sends the question and agentId; the backend retrieves material and augments model input. See ruoyi-web/src/pages/chat/layouts/chatWithId/index.vue:

ts
const payload: SendDTO = {
  model: modelStore.currentModelInfo.modelName ?? '',
  agentId: agentStore.currentAgentInfo?.id || undefined,
  content: lastUserMessage?.content ?? '',
  sessionId: route.params?.id !== 'not_login'
    ? String(route.params?.id)
    : undefined,
};

ChatServiceFacade loads the agent's model and knowledgeIds, then retrieves before Supervisor execution. The key part of augmentAgentInput() is:

java
RetrievalAugmentor augmentor = buildMultiKnowledgeAugmentor(knowledgeIds);
UserMessage userMessage = UserMessage.userMessage(content);
Metadata metadata = Metadata.from(
    userMessage, chatRequest.getSessionId(), new ArrayList<>());
AugmentationResult result = augmentor.augment(
    new AugmentationRequest(userMessage, metadata));
ChatMessage augmented = result.chatMessage();
return augmented instanceof UserMessage
    ? ((UserMessage) augmented).singleText() : content;

CustomVectorRetriever.retrieve() reads saved threshold, count, hybrid, and rerank settings and reuses KnowledgeRetrievalService. Apply test parameters to the knowledge-base configuration to affect this path.

An answer does not prove retrieval succeeded

If augmentation fails, the backend logs chat_rag operation=AUGMENT status=FALLBACK and uses the original question. Unavailable knowledge bases may also be skipped. Check retrieved content, backend logs, or RAG traces rather than only whether the model replied.

6.4 Integrate a custom chat frontend or workflow ​

For a custom frontend, ordinary model chat accepts knowledgeId in /chat/send; buildModelChatMessages() augments the current user message. Replace IDs and model names and retain the project's login and streaming handling:

json
{
  "model": "你的可用聊天模型名",
  "content": "北辰项目的后端服务端口和发布负责人分别是什么?",
  "knowledgeId": "你的知识库ID"
}

Agent-bound knowledgeIds take precedence; a request's single knowledgeId is only the fallback when there are no bindings. The standard user frontend does not currently send this field.

In a workflow, use Knowledge Retrieval, select a knowledge base, use the question as input, and pass fragments to a later model node. ruoyi-aiflow/.../node/knowledgeRetrieval/KnowledgeRetrievalNode.java uses the same shared retrieval service. See Workflows.

7. Tune retrieval after the basic flow works ​

Change one parameter group at a time and compare the same questions. Keep the working baseline from section 5.

7.1 Threshold and result count ​

A high threshold may exclude all fragments; a low one may admit irrelevant content. First retrieve the answer-bearing fragment, then raise the threshold gradually. More results add material and context length, so judge relevance as well as coverage.

7.2 Use hybrid retrieval for exact terms ​

Enable Hybrid search in the test and start at weight 0.5. The backend runs vector search and MySQL keyword search in parallel and merges ranks with RRF. KnowledgeRetrievalServiceImpl.calculateRRF() uses:

java
double finalScore = (1 - alpha) * vectorScores.getOrDefault(id, 0.0)
                  + alpha * keywordScores.getOrDefault(id, 0.0);
vo.setScore(finalScore * 60.0);

Higher alpha favors keywords; lower favors vectors. It weights ranks, so scores are not directly comparable to pure vector similarity. Semantic concepts and synonyms may benefit from vectors; model numbers, error codes, and exact field names may benefit from keywords.

7.3 Rerank candidates when ordering is poor ​

Configure a usable rerank model, enable reranking, and explicitly select it in the test.

The backend retrieves three times the requested count, reranks, and truncates. Failed reranking falls back to coarse results, which may still pass through the rerank threshold filter. If results disappear, check both model calls and thresholds.

Apply improvements and retest user-app chat. Query rewriting is currently displayed disabled and cannot be enabled here.

8. Keep knowledge current after document changes ​

ChangeAction
Threshold, result count, or hybrid settingsSave/apply and retest; no reupload needed.
Chunk size, overlap, or separatorSave, then File Management → Reparse all; wait before testing.
One failed fileFix storage, model, or file issues, reparse that row, and refresh.
Original content changedTest the new version in a verification base, then remove the old attachment and upload/parse the replacement to avoid mixed versions.
Embedding model or vector store changedPrefer a new knowledge base, fully import and verify, then switch agent associations. Do not mix old document vectors and new query vectors.

Reparse all calls POST /system/attach/reparse/knowledge/{knowledgeId}, returning submitted, skipped, and total counts. Files already parsing are skipped. A response confirms submission, not completion; refresh the file list.

Reparsing deletes old file vectors before writing new ones, so it is not seamless. Schedule updates appropriately for active knowledge bases.

Deleting an attachment cleans up its fragments, vectors, and original file. Deleting a knowledge base clears its data; check agent/workflow associations first. Do not update knowledge by directly editing fragment text in the database: the fragment-update API does not regenerate vectors. Reparse the source document instead.

9. Code entry points for further development ​

Excerpts reflect the current workspace. Admin paths start at ruoyi-admin/apps/web-antd/src; backend paths mainly start at ruoyi-ai/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi.

OperationAPIImplementation
Add/configure knowledge basePOST /system/info, PUT /system/infoKnowledgeAddModal.vue, KnowledgeConfig.vue, KnowledgeInfoServiceImpl.
UploadPOST /system/attach/uploadFileManagement.vue, KnowledgeAttachServiceImpl.upload().
Parse/reparsePOST /system/attach/parse/{id}, POST /system/attach/reparse/knowledge/{knowledgeId}parse(), reparseKnowledge().
FragmentsGET /system/fragment/listKnowledgeFragmentServiceImpl, filtered by docId.
Retrieval testPOST /system/fragment/retrievalKnowledgeFragmentServiceImpl.retrieval() → KnowledgeRetrievalServiceImpl.
EmbeddingsDuring parsing and queryingEmbeddingModelFactory → service/embed/impl.
Vector writes/queriesDuring parsing and queryingVectorStoreService, service/vector/impl.
Answer augmentationPOST /chat/sendChatServiceFacade → CustomVectorRetriever.

For formats, inspect ResourceLoaderFactory and service/knowledge/impl; for splitting, inspect service/knowledge/impl/split. A new embedding provider needs provider/model configuration and factory routing, not just a dropdown option.

10. Troubleshooting ​

SymptomCheck
Missing menu or actionAccount permissions: system:info:*, system:attach:*; retrieval needs system:fragment:list.
Embedding model missingCategory vector and account visibility.
Model listed but parsing call failsProvider state, address, credentials, and actual service readiness.
Duplicate uploadSame content digest in the same base; use Parse or follow section 8 for content updates.
Upload hangs/failsDefault OSS, connectivity, and response; do not leave external example storage selected.
Missing file_hash / fidApply the relevant RAG migration.
File remains pendingAutomatic parsing setting; trigger Parse and refresh.
Parse fails or fragments are emptyOriginal file accessibility, loader, splitter, embeddings, and vector store, in that order.
No retrieval resultsTemporarily use threshold 0, disable hybrid/rerank, and check base, model, and fragments.
Test works but answer is wrongApplied settings, correct agent and associations, RAG logs, and actual context.
No knowledge selector in ordinary chatAttach an agent or pass knowledgeId in your own frontend.
Agent absent in marketSaved record, normal status, user identity, and list response.
Old material still retrievedOld attachments and reparse completion; configuration changes do not rebuild documents automatically.
Screenshot and verification notes

The Add dialog was captured from the actual revision environment without submitting it. Five other configuration, upload, fragment, and retrieval screenshots come from an earlier local run with all-minilm:v2 and Weaviate. Successful results were not fabricated from simulated responses.

The 2026-09-08 revision rechecked admin entry points, the Add dialog, model selection, and current frontend/backend code. Docker Desktop failed during startup with a dockerInference listener error, preventing restoration of vector-store dependencies. Parsing, retrieval, and knowledge-based chat were therefore not reverified end to end. Section 6 describes supported steps and acceptance checks, not a successful chat recorded during that revision.