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 three plugin entry points, so a profile can override, replace, or drop any single role without touching the others.
| Role | Module | Plugin name | Responsibility |
|---|---|---|---|
| Service Definition | src/index.ts | @deepseek-ai/dsh-ragflow |
Owns ctx.ragflow: provider registry, order-independent selection, maxChunks enforcement |
| Service Provider | src/http.ts | @deepseek-ai/dsh-ragflow/http |
Calls POST /api/v1/retrieval, resolves credentials, normalizes chunks |
| Consumer | src/tool.ts | @deepseek-ai/dsh-ragflow/tool |
The model-facing tool: schema, prompt guidance, chunk bound, presentation |
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
- A running RAGFlow instance — self-hosted or cloud. Defaults to
http://localhost:9380. - An API key — create one in RAGFlow.
- 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 three rows landed:
dsh --profile web --dump-config | grep ragflow
Configure
Set the environment the plugin reads — no YAML 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.
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)
| Config | Default | Description |
|---|---|---|
retrieveProvider |
auto | Provider id to pin. Unset auto-selects when exactly one is usable. Also $DSH_RAGFLOW_PROVIDER. |
@deepseek-ai/dsh-ragflow/http (provider)
| Config | Default | Description |
|---|---|---|
apiKey |
— | Literal key. Prefer apiKeyEnv. |
apiKeyEnv |
RAGFLOW_API_KEY |
Credential reference resolved per retrieval. |
baseURL |
$RAGFLOW_BASE_URL → http://localhost:9380 |
Endpoint base; /api/v1/retrieval is appended. |
datasetIds |
$RAGFLOW_DATASET_IDS |
Datasets searched by default. |
documentIds |
— | Narrows the search below dataset level. |
similarityThreshold |
0.2 |
Chunks below this combined similarity are dropped. |
vectorTopK |
RAGFlow's 1024 |
RAGFlow's top_k: the vector candidate pool, not the result count. |
vectorSimilarityWeight |
RAGFlow's 0.3 |
Vector weight in RAGFlow's hybrid score. |
keyword |
false |
Run RAGFlow's keyword pass alongside vector search. |
rerankId |
— | Rerank model applied to the candidate pool. |
@deepseek-ai/dsh-ragflow/tool (consumer)
| Config | Default | Description |
|---|---|---|
maxChunks |
8 |
Upper bound on chunks per call; sent as RAGFlow's page_size and enforced again by the seam. |
timeoutMs |
30000 |
Cooperative per-call timeout budget. |
Retrieval flow
- The model calls
ragflow_retrievewith aquestion. - The tool validates it and calls
ctx.ragflow.retrieve({ question, maxChunks }, signal). - The seam selects the usable provider and forwards the request.
- The provider posts to
/api/v1/retrievaland normalizesdata.chunks[]. - 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}.js
lib/ is committed; rebuild and commit it with any src/ change.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
RAGFLOW_SCOPE_MISSING |
No dataset or document in scope | Set datasetIds or $RAGFLOW_DATASET_IDS |
RAGFLOW_PROVIDER_CREDENTIAL_MISSING |
No key for the credential reference | Set $RAGFLOW_API_KEY, or match apiKeyEnv to your credentials key |
RAGFLOW_PROVIDER_UNAUTHORIZED |
RAGFlow rejected the key | Reissue the key in RAGFlow |
RAGFLOW_PROVIDER_UNAVAILABLE |
Provider row missing or its options invalid | Check --dump-config for the ragflow-http row |
RAGFLOW_PROVIDER_AMBIGUOUS |
Two usable providers registered | Pin one with the seam's retrieveProvider |
ragflow_retrieve absent from the tool list |
Bundle not loaded | dsh --dump-config | grep ragflow; restart dsh web |
| Fewer chunks than expected | vectorTopK is not the result count |
Raise maxChunks on the tool row |
Known limitations
- Retrieval only — no dataset or document management (create, upload, parse).
- 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, anduse_kgoptions are not surfaced yet.
No comments yet. Be the first to write one.