dshbase

插件目录 / Knowledge / dsh-ontology

dsh-ontology

已验证 · 实测可装 tancheng33

✓ 持续维护 基于 5 个官方 DSH 包 纯 TypeScript

查看 GitHub ↗ ← 返回插件目录

16Stars
4Forks
1未关闭 issue
TypeScript语言
2026-08-16最近推送
跨平台平台

功能简介

A typed, inference-capable ontology (TBox + ABox) plugin for DeepSeek Harness — durable domain knowledge the agent declares, asserts against, and queries under schema constraints.

✅
我们的评价
可用 — 实测通过,早期项目

A typed, inference-capable ontology (TBox + ABox) plugin for DeepSeek Harness — durable domain knowledge the agent declares, asserts against, and queries under schema constraints. 实测能干净安装、正常启动。早期项目,但功能可用。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

dsh-ontology

English | 中文

A typed, inference-capable ontology for DeepSeek Harness — durable domain knowledge the agent declares, asserts against, and queries under schema constraints.

Most agent memory is a bag of strings: the agent writes prose, later reads prose, and nothing ever tells it that what it just recorded contradicts what it recorded last week. This plugin gives the agent a vocabulary it must respect. You declare what kinds of things exist and how they may relate; every claim is then checked against that model before it is stored, and claims that follow from other claims are derived rather than repeated.

ontology_define   declare classes and typed relations   (the TBox)
ontology_assert   record entities and facts             (the ABox, validated)
ontology_query    look things up, traverse, infer
ontology_retract  remove, with dependency protection

Why a TBox, not a notes file

notes-style memory dsh-ontology
Structure free text classes, typed relations, entities, triples
Bad input silently stored rejected, naming the constraint it broke
Implied facts restated by hand, drift apart derived on read from transitive / symmetric / inverseOf
Retraction orphaned prose lingers facts cascade with their entity; derived facts vanish with their premise
Reading it back grep and hope query by class (subclass-aware), triple pattern, neighbourhood, or shortest path

The constraint is the point. When the agent asserts ada depends_on api and depends_on is declared Component -> Component, it gets back:

REJECTED ada depends_on api: ada is not in the domain of depends_on
  (requires one of: Component; has: Person)

That is a real signal — either the claim is wrong, or the model of the domain is incomplete. Free-text memory can produce neither.

Install

dsh plugin --profile <name> add dsh-ontology
dsh --profile <name>

Or from a checkout / git host:

dsh plugin --profile <name> add ./dsh-ontology
dsh plugin --profile <name> add github:tancheng33/dsh-ontology

A github: install builds from source, so pnpm ≥10 needs the build allowlisted. Add allowBuilds: { dsh-ontology: true } to the profile's pnpm-workspace.yaml and re-run, and pin a commit (#<sha>) so a later push cannot silently change what runs. Installing from npm needs no allowance.

The bundle brings its own storage stack (dsh-storage + dsh-storage-json + dsh-storage-domain) under the same row ids dsh-web-app uses, so it works in a bare profile and composes cleanly with one that already has storage. Data lands in $DSH_HOME/storages/<domain>.json.

Configuration

Override any of these in your profile's cordis.patch.yml:

Key Default Meaning
domain ontology Storage domain name; one name is one isolated graph. Must match /^[a-z][a-z0-9_]*$/.
strict true Reject facts that violate the vocabulary. false stores them with the violations recorded, for exploratory modelling.
inference true Allow queries to return entailed facts.
promptSection true Contribute the vocabulary summary to the system prompt.
promptMaxTerms 60 Upper bound on terms in that summary.
promptOrder 150 Where the section lands in the assembled prompt.
defaultLimit / maxLimit 50 / 500 Query result sizes.
maxEntities / maxFacts 20000 / 100000 Capacity guards; a write past the bound fails loudly.

Running two isolated graphs is just two rows:

- insert:
    - id: ontology-team
      name: dsh-ontology
      config: { domain: team_ontology, strict: true, inference: true, promptSection: true,
                promptMaxTerms: 60, promptOrder: 150, defaultLimit: 50, maxLimit: 500,
                maxEntities: 20000, maxFacts: 100000 }

(A patch replaces a row's whole config, so restate every key.)

A worked example

Declare the vocabulary. Order does not matter — entries are resolved by repeated passes, so a subclass may precede its parent and a relation may precede its inverse.

// ontology_define
{
  "classes": [
    { "id": "Service", "subClassOf": ["Component"] },
    { "id": "Component", "comment": "A deployable unit of the system" },
    { "id": "Person" }
  ],
  "relations": [
    { "id": "depends_on", "domain": ["Component"], "range": ["Component"],
      "characteristics": ["transitive"] },
    { "id": "owns", "domain": ["Person"], "range": ["Component"], "inverseOf": "owned_by" },
    { "id": "owned_by", "domain": ["Component"], "range": ["Person"] },
    { "id": "version", "domain": ["Component"], "rangeKind": "literal" }
  ]
}

Assert instances. Entities are created before the facts of the same call, so one call introduces an individual and its relationships together.

// ontology_assert
{
  "entities": [
    { "id": "api", "classes": ["Service"] },
    { "id": "auth", "classes": ["Service"] },
    { "id": "pg", "classes": ["Component"] },
    { "id": "ada", "classes": ["Person"] }
  ],
  "facts": [
    { "subject": "api", "predicate": "depends_on", "object": "auth" },
    { "subject": "auth", "predicate": "depends_on", "object": "pg" },
    { "subject": "ada", "predicate": "owns", "object": "api", "source": "CODEOWNERS" },
    { "subject": "api", "predicate": "version", "object": "2.1.0" }
  ]
}

Query, including what was never asserted.

// ontology_query
{ "mode": "facts", "subject": "api", "predicate": "depends_on", "includeInferred": true }
api depends_on auth
api depends_on pg (inferred: transitive)
// ontology_query
{ "mode": "path", "from": "ada", "to": "pg", "depth": 4 }
connected in 3 step(s):
  ada owns api
  api depends_on auth
  auth depends_on pg

Query modes

Mode Answers
schema What vocabulary exists? (Start here.)
stats How big is the graph, and how much is inferable?
entities Which individuals are in class X (including its subclasses), or match text Y?
facts Which triples match this pattern? Each omitted position is a wildcard.
neighbors What surrounds this entity, out to depth N?
path How are these two entities connected?

The rules it enforces

Subsumption. subClassOf is transitive: an entity declared Service is also a Component, so it satisfies a Component domain and is returned by a Component query. Cycles are refused at definition time — a cycle would make "is an X" unfalsifiable for every class on it.

Domain and range. A relation's domain constrains subjects, its range constrains objects, both closed under subsumption. An empty list means unconstrained, which is the honest encoding of "not yet decided" rather than a silent allow-all.

Entity vs literal. rangeKind: "literal" makes a relation attribute-valued (a version string, a date). A literal-valued relation can be neither symmetric, transitive, nor inverted — the derived triple would have a literal in subject position — and that incoherence is refused at definition time rather than producing nonsense later.

Functional cardinality. A functional relation admits at most one object per subject. A second, different object is a functional-conflict, not a silent overwrite. Re-asserting the same object stays idempotent.

Entailment. transitive, symmetric, and inverseOf are applied to a fixpoint, so the rules compose (the inverse of a transitive relation is itself closed transitively). Entailed facts are derived on read and never stored — retract a premise and everything resting on it disappears, with no stale derivation left behind. Each carries via naming the rule that produced it.

Retraction safety. Retracting an entity cascades to every fact mentioning it. Retracting a term is refused while anything still depends on it — a class that still classifies an entity or appears in a relation signature, a relation still asserted — and the refusal names the dependent.

Code Mode

Every tool is reachable as a typed call, with the canonical JSON value (not the rendered prose) as the result:

const { facts } = await tools.ontology_query({
  mode: 'facts', predicate: 'depends_on', includeInferred: true,
})
const upstream = facts.filter(fact => fact.via === 'transitive').map(fact => fact.object)

Using the reasoning core on its own

The rule engine is pure — no IO, no storage, no Cordis — and ships as its own entry point, so it can be used outside a harness:

import { entail, findPath, validateFactInput } from 'dsh-ontology/ontology'

Development

pnpm install
pnpm test        # 47 unit tests: rules, tools, prompt section
pnpm typecheck
pnpm build

tests/memory-domain.ts is an in-memory stand-in for one open storage domain, so the store and the tools are tested end to end — real validation, real entailment, real tool results — without a backend.

Requirements

  • DeepSeek Harness >= 0.1.0-rc.6
  • Node ^22.19 || >=24

License

MIT

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-ontology」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:tancheng33/dsh-ontology

Headless(CLI)profile:

dsh plugin --profile headless add github:tancheng33/dsh-ontology

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Knowledge 里更多

浏览全部 7819 个插件 →