Vai al contenuto principale
S

dsh-ragflow

staff-os/dsh-ragflow

RAGFlow knowledge-base retrieval plugin for the DeepSeek Harness.

Installazione

dsh plugin --profile web add github:staff-os/dsh-ragflow

README

dsh-ragflow

English | 中文

RAGFlow knowledge-base retrieval for the DeepSeek Harness. It gives the agent a ragflow_retrieve tool that queries your RAGFlow datasets and returns document chunks with similarity scores and source names.

Design

The package follows the Harness three-role capability pattern: one seam, one provider, one consumer — shipped as one package with four plugin entry points (the fourth is the configuration page over the same values), so a profile can override, replace, or drop any single role without touching the others.

RoleModulePlugin nameResponsibility
Service Definitionsrc/index.ts@deepseek-ai/dsh-ragflowOwns ctx.ragflow: provider registry, order-independent selection, maxChunks enforcement
Service Providersrc/http.ts@deepseek-ai/dsh-ragflow/httpCalls POST /api/v1/retrieval, resolves credentials, normalizes chunks
Consumersrc/tool.ts@deepseek-ai/dsh-ragflow/toolThe model-facing tool: schema, prompt guidance, chunk bound, presentation
Consumersrc/config.ts@deepseek-ai/dsh-ragflow/configThe person-facing configuration page over the same settings and credential seams

The provider and the consumer depend only on the Service Definition, never on each other. Replacing the backend means replacing one row:

- id: ragflow-http
  name: 'your-own-ragflow-provider'

Prerequisites

  1. A running RAGFlow instance — self-hosted or cloud. Defaults to http://localhost:9380.
  2. An API key — create one in RAGFlow.
  3. A dataset with parsed documents — RAGFlow rejects a retrieval that names no dataset and no document, so at least one dataset id must be configured.

Install

dsh plugin --profile web add "github:staff-os/dsh-ragflow#main"

dsh plugin add forwards the source to pnpm as-is, so any pnpm-recognized source works:

dsh plugin --profile web add link:/path/to/dsh-ragflow   # local development

lib/ is committed, so no build script runs at install time and pnpm needs no build allowance. Restart dsh web afterwards, then verify the four rows landed:

dsh --profile web --dump-config | grep ragflow

Configure

Three ways in, one set of values. The configuration page is the easy one; the environment and the YAML rows remain exactly what they were.

The configuration page

With dsh web running, open http://127.0.0.1:3080/ragflow (whatever port the web surface printed). It edits the endpoint, the datasets, the retrieval options, and the tool bound, and it stores the API key through the credential service — the key never reaches a settings file, and the field reports only whether one is configured.

Every field is leave empty to inherit: the box holds your own override, the placeholder names the value in effect without one. Clearing a box is how a field goes back to inheriting the composition row, the environment variable, or the schema default. Test retrieval runs one live retrieval so a saved endpoint can be confirmed rather than assumed.

The page is served on loopback only, whatever dsh web --host binds, because it reads deployment configuration and writes a credential. Move it with the row's path, or take it out entirely:

# ~/.dsh/profiles/web/cordis.patch.yml
- id: ragflow-config
  disabled: true

Saved values land in ~/.dsh/settings.yaml under the ragflow-http and tool-ragflow namespaces, which layer over the composition rows: schema defaults, then the cordis.patch.yml entry, then your saved section. They apply to the next retrieval without a restart — except timeoutMs, which the tool registry reads once when the tool registers.

Environment variables

Set the environment the plugin reads — no YAML and no page needed for the common case:

export RAGFLOW_API_KEY=ragflow-xxx
export RAGFLOW_BASE_URL=http://your-ragflow-host:9380     # optional, defaults to localhost:9380
export RAGFLOW_DATASET_IDS=dataset_id_1,dataset_id_2      # required unless set in YAML

The API key resolves through the DSH credentials service when one is mounted (~/.dsh/.credentials.yaml), and through the launch environment otherwise. Never inline a key in a config file.

The launch environment is a snapshot taken when the process starts, so editing a variable never reaches a running dsh — restart it from a shell that already carries the new value. On Windows that is easy to get wrong: editing System variables in the GUI only writes the registry, and every process already running keeps its old block — Explorer included, so anything started from the Start menu or a shortcut inherits Explorer's stale copy until you restart Explorer or sign out and back in. The page reports what the process actually sees, which makes it the quickest way to tell a stale environment from a wrong value.

To override a row, restate it in your profile's cordis.patch.yml — a patch replaces a row's whole config rather than merging into it, so state every key that row needs:

# ~/.dsh/profiles/web/cordis.patch.yml
- insert:
    - id: ragflow-http
      name: '@deepseek-ai/dsh-ragflow/http'
      config:
        baseURL: http://your-ragflow-host:9380
        datasetIds: ['dataset_id_1']
        similarityThreshold: 0.3
        vectorTopK: 1024

@deepseek-ai/dsh-ragflow (seam)

ConfigDefaultDescription
retrieveProviderautoProvider id to pin. Unset auto-selects when exactly one is usable. Also $DSH_RAGFLOW_PROVIDER.

@deepseek-ai/dsh-ragflow/http (provider)

ConfigDefaultDescription
apiKeyLiteral key. Prefer apiKeyEnv.
apiKeyEnvRAGFLOW_API_KEYCredential reference resolved per retrieval.
baseURL$RAGFLOW_BASE_URLhttp://localhost:9380Endpoint base; /api/v1/retrieval is appended.
datasetIds$RAGFLOW_DATASET_IDSDatasets searched by default.
documentIdsNarrows the search below dataset level.
similarityThreshold0.2Chunks below this combined similarity are dropped.
vectorTopKRAGFlow's 1024RAGFlow's top_k: the vector candidate pool, not the result count.
vectorSimilarityWeightRAGFlow's 0.3Vector weight in RAGFlow's hybrid score.
keywordfalseRun RAGFlow's keyword pass alongside vector search.
rerankIdRerank model applied to the candidate pool.

@deepseek-ai/dsh-ragflow/tool (consumer)

ConfigDefaultDescription
maxChunks8Upper bound on chunks per call; sent as RAGFlow's page_size and enforced again by the seam.
timeoutMs30000Cooperative per-call timeout budget. Read at registration: a change applies at the next start.

@deepseek-ai/dsh-ragflow/config (configuration page)

ConfigDefaultDescription
path/ragflowPathname the page and its JSON endpoints (/state, /save, /probe) are served under.

Retrieval flow

  1. The model calls ragflow_retrieve with a question.
  2. The tool validates it and calls ctx.ragflow.retrieve({ question, maxChunks }, signal).
  3. The seam selects the usable provider and forwards the request.
  4. The provider posts to /api/v1/retrieval and normalizes data.chunks[].
  5. The seam caps the result to maxChunks; the tool renders it as cited text plus structured metadata that survives session replay.

An empty result is a result: the tool tells the model the knowledge base has nothing relevant and not to invent a citation.

Develop

pnpm install
pnpm test        # vitest
pnpm typecheck   # tsc --noEmit
pnpm build       # tsdown → lib/{index,http,tool,config}.js

lib/ is committed; rebuild and commit it with any src/ change.

Troubleshooting

SymptomCauseFix
RAGFLOW_SCOPE_MISSINGNo dataset or document in scopeSet datasetIds or $RAGFLOW_DATASET_IDS
RAGFLOW_PROVIDER_CREDENTIAL_MISSINGNo key for the credential referenceSet $RAGFLOW_API_KEY, or match apiKeyEnv to your credentials key
RAGFLOW_PROVIDER_UNAUTHORIZEDRAGFlow rejected the keyReissue the key in RAGFlow
RAGFLOW_PROVIDER_UNAVAILABLEProvider row missing or its options invalidCheck --dump-config for the ragflow-http row
RAGFLOW_PROVIDER_AMBIGUOUSTwo usable providers registeredPin one with the seam's retrieveProvider
ragflow_retrieve absent from the tool listBundle not loadeddsh --dump-config | grep ragflow; restart dsh web
Fewer chunks than expectedvectorTopK is not the result countRaise maxChunks on the tool row
The page answers NOT_LOOPBACKReached over a LAN addressOpen it from the host itself, or tunnel the port
The page answers SETTINGS_CONFLICTThe settings document moved since the page loadedReload the page and reapply
The API key field is read-onlyA launch-environment RAGFLOW_API_KEY shadows the storeChange the variable and restart dsh, or unset it to manage the key from the page
The page still shows an endpoint or dataset you already changedThe process inherited the environment block from before the changeRestart dsh from a shell opened afterwards; on Windows also restart Explorer or sign out and back in
No page at /ragflowSurface without a web server, or the row is disableddsh --dump-config | grep ragflow-config

Known limitations

  • Retrieval only — no dataset or document management (create, upload, parse).
  • The page is this plugin's own, not a card in DSH's Settings → Plugins tab: that tab renders only the settings namespaces the host api-proxy allowlists (WEB_SETTINGS_NAMESPACES), which a plugin distributed outside the harness repository cannot join without patching a released package. If that allowlist ever moves to settings.register(), these same namespaces become a card there with no change here.
  • No streaming; the full response is awaited.
  • The result renders as the generic search card, not a bespoke citation card.
  • RAGFlow's cross_languages, metadata_condition, highlight, and use_kg options are not surfaced yet.

Plugin correlati