Skip to content

2026-06-17 v1.7.0 - Agent Knowledge DAG Answer Contract Plan

English Document

Objective

This note updates the 2026-06-10 Knowledge Workspace / DAG alignment with the user's clarified requirement: the graph structure is this project's existing DAG-shaped structured knowledge data, not a generic graph database product.

The goal is to define the correct implementation direction for agent knowledge answers:

  1. keep the public answer area focused on the user's question,
  2. keep supporting evidence, graph traces, and developer/debug material in secondary panes and exportable traces,
  3. make file hits reliably open the right-side focus pane with source markdown and matched-span highlighting,
  4. stop treating the DAG as a shallow relation bonus and start using it as an answer-planning substrate,
  5. preserve additive response compatibility and robustness while the architecture is tightened.

2026-06-20 Completion Audit

  • The implementation slices in this plan are complete: P0 through P5 now exist in the current codebase rather than remaining as design direction.
  • The completion boundary is the plan's numbered slices. The later Remaining gap, Tradeoffs, and Next robust direction sections describe future calibration or follow-on work, not unfinished blockers for this plan.
  • Fresh evidence captured on 2026-06-20:
  • npm test -- --runInBand: 112 suites passed, 893 tests passed, 26 skipped.
  • npm exec -- tsc --noEmit: passed.
  • npm run build:mini: passed.
  • node scripts/verify-knowledge-workspace-runtime.js --case waterglass_explicit_scope_compact_zh: passed.
  • The implemented acceptance surface now covers the user's explicit concerns:
  • public answer contraction instead of dumping evidence into the main answer area,
  • reliable right-pane source opening with matched-span highlighting,
  • click-hint copy plus fixed Learning Path / Related Focus actions on knowledge hits,
  • DAG-conditioned context assembly and graph-aware retrieval/ranking,
  • quality gates and replayable operator telemetry through knowledgeRunReports and graphFocusReports.
  • This plan is now marked completed. Further ranking calibration or richer provenance work should be tracked as new iterations rather than keeping this architecture plan open indefinitely.

First Principles

Term Definitions

  • DAG: a directed acyclic graph. In this project it is a directed knowledge structure where nodes are concepts, notes, atoms, or indexed units, and edges encode ordered relationships such as prerequisite, reference, next step, supersession, or temporal replacement. The "acyclic" part matters because topological order and prerequisite chains only stay meaningful when cycles are either absent or explicitly handled.
  • KnowledgeAtom: the learning-layer unit used by src/learning/KnowledgeLearningPlatform.ts and src/learning/types.ts. It is smaller and more queryable than a whole Markdown file.
  • RelationEdge: a directed semantic edge between atoms. It carries relation kind, confidence, provenance, and evidence linkage.
  • TemporalEdge: an edge describing validity over time, supersession, replacement, or expiry. It prevents the answer planner from treating stale knowledge as equally current.
  • EvidenceSpan: a source-grounded text span that connects an atom or answer claim back to markdown content.
  • Anchor: the primary atom or document selected as the center of the user's current question.
  • Support node: an atom that is not the anchor but is needed to explain, justify, contrast, sequence, or qualify the answer.
  • Path: an ordered sequence of atom IDs connected by directed edges. A path is not just "related content"; it is a claim about how concepts connect.
  • Predecessor: a transitive upstream dependency of an anchor.
  • Successor: a transitive downstream consequence or next-step node from an anchor.
  • Topological order: an order of DAG nodes where prerequisites appear before dependent nodes.
  • GraphContextPack: the bounded, deterministic graph-derived context passed to answer synthesis. It should contain anchor identity, selected support nodes, relation summaries, explicit paths, temporal warnings, and evidence spans. It must not be the whole graph.
  • Public answer: the concise user-facing response.
  • Evidence pane: the secondary UI surface where citations, graph context, durable artifacts, and developer-facing trace material can be inspected.
  • Developer trace: the structured runtime/export payload used by developers and operators. It should remain available without crowding the public answer.

Layered Architecture

The project already has multiple graph-bearing layers. The implementation must respect the different responsibilities instead of collapsing them into one "RAG" box.

  1. Markdown source layer
  2. Owner: Knowledge_Base, src/backend/FileLoader.ts, markdown reader/runtime.
  3. Responsibility: durable source text, frontmatter, links, headings, and evidence spans.
  4. Boundary: file paths and source content must be canonical enough for right-pane rendering and highlighting.

  5. Graph build layer

  6. Owner: src/backend/GraphBuilder.ts, src/core/Graph.ts, src/core/PathEngine.ts, path workers.
  7. Responsibility: build graph nodes/edges, dependency edges, inferred edges, layout ranks, predecessor/successor/path operations.
  8. Boundary: this layer gives the project its structural DAG. It is not the same thing as an LLM prompt.

  9. Learning atom/relation layer

  10. Owner: src/learning/KnowledgeLearningPlatform.ts, src/learning/types.ts, src/learning/store.ts.
  11. Responsibility: KnowledgeAtom, RelationEdge, TemporalEdge, EvidenceSpan, snapshots, graphdb/sqlite/file-backed ops, path queries through findPath.
  12. Boundary: this is the correct layer for answer-time graph context because it has atom IDs, relation metadata, temporal state, and source evidence.

  13. Retrieval layer

  14. Owner: src/learning/queryBackend.ts.
  15. Responsibility: produce candidate atoms using keyword/vector/hybrid scoring under scope constraints.
  16. Current reality: the DAG mostly enters as connection-degree bonus (0.08 in local hybrid, 0.06 in local vector) and relation-path hints after retrieval. That is useful, but it is not graph-native answer planning.

  17. Graph-conditioned context assembly layer

  18. Proposed owner: a new learning-domain owner, not server.ts and not the frontend.
  19. Responsibility: turn retrieved candidates into a bounded GraphContextPack by selecting anchor, expanding predecessor/successor/path windows, applying temporal validity, attaching evidence spans, and enforcing a token/size budget.
  20. Current 2026-06-17 slice: now advanced into a first-class owner by src/learning/graphContextAssembler.ts, which selects the anchor, reorders support nodes, carries explicit connectionPaths, adds bounded predecessor/successor windows, and records evidence refs plus graph diagnostics before answer synthesis.
  21. The same slice protects the current graph substrate during read-side auto-save by merging still-valid store-side relation/temporal edges into rebuilt snapshots before persisting.
  22. The same slice contracts the public answer / directAnswer string so it no longer embeds citation lists, connection paths, memory notices, or knowledge-run diagnostics.
  23. 2026-06-18 update: right-pane source-focus diagnostics now also cross the runtime boundary through session-state persistence and export-derived runtime.graphFocusReports; the remaining work is calibration, not missing plumbing.

  24. Answer synthesis layer

  25. Owner: src/learning/conversationComposer.ts plus future composer/assembler modules.
  26. Responsibility: produce a targeted answer using the graph-conditioned context while keeping the public answer concise.
  27. Boundary: answer synthesis may carry graph paths in typed structured sections and traces, but it must not dump evidence, relation summaries, and diagnostics into the public answer.

  28. UI and export layer

  29. Owner: src/frontend/agent_workspace.js, src/frontend/workspace_panes.js, src/export/WorkspaceExportBundle.ts.
  30. Responsibility: public answer rendering, right-pane focus, evidence pane, durable artifacts, workspace export.
  31. Boundary: the frontend should project structured payloads; it should not infer graph semantics from display strings.

How the Layers Connect

The intended runtime flow should be:

  1. User question arrives at /api/knowledge/conversation.
  2. Scope is normalized once at the API/runtime edge.
  3. Retrieval returns a limited set of atom/document candidates.
  4. Graph-conditioned context assembly chooses the anchor and asks the learning graph for:
  5. direct relations among candidates,
  6. explicit paths between candidate atoms and anchor,
  7. prerequisite predecessors,
  8. successor/next-step nodes,
  9. temporal validity and supersession details,
  10. source evidence spans.
  11. The assembler budgets and ranks the graph context.
  12. The composer generates:
  13. a concise public answer,
  14. optional typed assistantBlocks,
  15. trace.graphContext,
  16. durable artifacts when needed.
  17. The UI renders the public answer first.
  18. File hits open the right pane with source markdown and matched highlights.
  19. Evidence/graph/debug material stays in the evidence pane and export bundle.

This order matters. If graph expansion happens before scope normalization, it can leak out of the user's intended corpus. If graph expansion happens only after answer synthesis, the LLM cannot use the DAG to plan the answer. If graph expansion is unbounded, prompt size and latency will grow faster than answer quality.

Current Code vs Requirements

Requirement Current code reality 2026-06-17 status Gap / risk
Public answer should answer the user's question, not list every internal artifact buildScopedConversationAnswer() now returns a single targeted answer string; citation lists, graph paths, memory notices, and knowledge-run diagnostics stay in typed blocks, traces, panes, or exports. Implemented current slice Keep future DAG context from re-inflating the answer area.
Hide developer-heavy evidence and purple-box-style support material for now Evidence pane and runtime/export traces carry supporting context. Direction is correct Any new graph details must default to secondary surfaces unless explicitly requested.
Clicking a file hit should open right-side content and highlight matched text workspace_panes.js routes file entries through graph focus, retries source reads across payload + matched-span candidate paths, renders through the shared markdown runtime, highlights matched spans, records requested/candidate/attempted/resolved-path diagnostics, emits interesting diagnostics through the agent-workspace runtime, and now reports inlineHighlightStrategy including source_offset_provenance. EvidenceSpan offsets flow through citations and matched spans so repeated identical fragments inside one authenticated block can be disambiguated when offsets exist. Implemented broadened P4 slice Remaining risk is old payloads without offsets or genuinely richer nested AST provenance needs, not missing pane opening or persistence plumbing.
Use this project's existing DAG, not a generic graph database abstraction KnowledgeAtom, RelationEdge, TemporalEdge, store ops, findPath, path/session logic, and Graph.ts DAG helpers already exist. Retrieval-side graph intent detection now also aligns with the rest of the stack by covering Chinese compare/how-to/explain markers. Confirmed The prior "graph database + prompt framework" framing was too generic.
Let LLM inspect high-quality graph structure 2026-06-17/18 code now uses graphContextAssembler.ts to choose the anchor, reorder support nodes, preserve explicit store path chains, add predecessor/successor windows, and expose graph diagnostics through trace/export/evidence pane. Durable knowledge_run artifacts now also retain graphContext, operator inspection/history/compare cards surface graph context plus graph diagnostics, WorkspaceExportBundle emits runtime.knowledgeRunReports, and graph-focus render diagnostics are exported as runtime.graphFocusReports. Implemented broader P1/P4/P5 foundation Remaining work is calibration breadth and owner reduction, not runtime-surface absence.
Compact mixed-language alias queries inside an explicit scope must still retrieve evidence 2026-06-18 fix: planner-derived title-like variants are now passed into retrieval as expanded queryTokens plus explicit queryVariants; queryBackend.ts consumes those variants for semantic tokens, anchor inference, and title matching; the runtime verifier now defaults to the 什么是waterglass? + 什么是water glass matrix. Implemented current slice Keep alias normalization centralized. Do not relax the evidence gate to hide normalization bugs.
Preserve compatibility assistantMessage remains valid; new graphContext.connectionPaths is optional and additive; snapshot merging keeps existing relation/temporal edges only when both endpoints remain active. Preserved Keep optional fields optional in all clients and exports. Add edge ownership metadata before treating missing persisted edges as intentional deletes.

Open-Source Library Review Result

The referenced repositories were cloned under ref/ and reviewed as design inputs:

Project Local ref Useful pattern What not to copy
DSPy ref/dspy 4987601 Typed signatures, evaluable programs, optimizer mindset. Useful for defining GraphContextPack -> Answer as a measurable program. Do not add a Python optimizer/runtime into the TypeScript/Tauri path just to rewrite prompts.
Guidance ref/guidance 21b1d90 Constrained generation and structured output discipline. Useful for strict JSON/section contracts. Do not make prompt templating the graph reasoning layer.
Semantic Kernel ref/semantic-kernel 13f812b Named prompt functions, execution settings, telemetry boundaries. Do not import a broad orchestration framework when local owners already exist.
LangChain Core ref/langchain 847312e Explicit runnable/pipeline composition and parser boundaries. Avoid framework-wide abstractions that duplicate the existing platform/lifecycle code.
LiteLLM ref/litellm cf2db41 Provider routing, fallback, and model-call boundary normalization. Do not let provider routing decide graph semantics.

Best conclusion: use these projects as architectural references, not runtime dependencies. The implementation should stay native to this codebase: TypeScript types, local graph store operations, optional JSON/schema-constrained model calls, and existing export/diagnostic surfaces.

2026-06-18 Runtime Regression: Compact Alias Retrieval Contract Gap

A screenshot-backed runtime failure exposed a remaining cross-layer defect for the scoped waterglass corpus. The failing user prompt was the compact mixed-language form 什么是waterglass?, not the spaced control form 什么是water glass.

Observed runtime facts before the fix:

  • node scripts/verify-knowledge-workspace-runtime.js --full --target waterglass --query "什么是waterglass?" failed.
  • node scripts/verify-knowledge-workspace-runtime.js --full --target waterglass --query "什么是water glass" passed.
  • workspaceReadiness.status was still ready.
  • usedScope.workspaceId / corpusId were still waterglass.
  • the planner still found the right title-like document hit and matchedAtomCount stayed positive.
  • the final miss reason still collapsed to retrieval_candidates_below_threshold.

Root cause:

  • the planner already expanded compact/spaced/title aliases (waterglass, water glass, 水玻璃, 水杯),
  • but retrieval scoring still depended mainly on the raw query string and raw query tokens,
  • so the compact mixed-script form remained too opaque for keyword/vector scoring even after the planner hit the document.

Correction in the current slice:

  • KnowledgeLearningPlatform.buildQueryBackendContext() now expands retrieval queryTokens from the raw query plus planner-derived title-like variants and passes explicit queryVariants into the backend context.
  • queryBackend.ts now consumes queryVariants for semantic token construction, anchor inference, and title matching.
  • scripts/verify-knowledge-workspace-runtime.js now treats the compact/spaced waterglass pair as the default runtime acceptance matrix and fails if either query falls back to retrieval_candidates_below_threshold or returns zero citations.

Why this matters for the framework discussion:

  • This is not primarily a prompt-composition problem.
  • DSPy, Guidance, Semantic Kernel, LangChain Core, and LiteLLM can help with structured outputs, evaluation, or provider routing.
  • None of them fixes a broken lexical contract between planner normalization and retrieval scoring.
  • The right owner is the local learning-runtime retrieval boundary, not a new orchestration framework.

Concrete Implementation Plan

P0: Stabilize the current 2026-06-17 slice

Already advanced in the working tree:

  • AgentConversationGraphContext now accepts optional connectionPaths.
  • KnowledgeLearningPlatform can ask an ops-capable store for explicit paths between returned knowledge points and the anchor through findPath.
  • KnowledgeLearningPlatform now preserves still-valid store-side relation/temporal edges while auto-saving rebuilt snapshots, so path enrichment can use externally improved DAG structure instead of being starved by a read-side persist.
  • conversationComposer can mention explicit graph paths in structured answer sections while keeping the public directAnswer free of evidence/debug lists.
  • workspace_panes.js renders connection paths in the evidence pane.
  • WorkspaceExportBundle preserves connection paths in exported conversation graph context.
  • Regression tests cover composer output, KLP path enrichment, evidence-pane rendering, locale keys, and export serialization.

This is a compatibility-safe improvement because all new fields are optional and additive.

P1: Extract a graph-conditioned context assembler

Landed in the current working tree as src/learning/graphContextAssembler.ts.

Inputs:

  • normalized user question,
  • resolved scope,
  • retrieved AgentConversationKnowledgePoint[] or lower-level query candidates,
  • atom/relation/temporal stores,
  • budget options.

Outputs:

  • GraphContextPack / existing AgentConversationGraphContext extension,
  • selected anchor,
  • reordered support nodes,
  • explicit paths,
  • predecessor/successor windows,
  • temporal warnings,
  • source evidence span references,
  • diagnostics for missing graph data.

Implemented rules in the current slice:

  • path depth is capped by default (6),
  • support-node count is bounded by answer intent,
  • explicit edge direction is preserved in every rendered path,
  • graph ops failure falls open to retrieval-shaped graph context with diagnostics,
  • predecessor/successor windows are bounded and stay in secondary evidence surfaces.

P2: Make retrieval graph-aware without overfitting to degree

Implemented foundation in the current working tree. queryBackend.ts no longer leans on raw relation-degree bonus as the main graph signal. The active bounded feature set now includes:

  • candidate distance to title/document anchor,
  • prerequisite depth relative to anchor,
  • path existence and path confidence,
  • temporal validity score,
  • relation-kind intent match.

Current behavior:

  • local_hybrid and local_vector infer title/document anchors from the query,
  • planner-derived compact/spaced alias variants now also flow into retrieval semantic tokens and title/anchor scoring, so scoped prompts such as 什么是waterglass? no longer fail after the planner already found the document,
  • graph bonuses are only applied when an anchor can be inferred,
  • directed path confidence and prerequisite depth now reward structurally relevant support nodes,
  • temporal invalidity now acts as a penalty instead of a blind positive freshness reward,
  • unrelated high-degree hubs are no longer allowed to win just because they have many edges.
  • graph intent detection now covers Chinese compare/how-to/explain markers in addition to English forms,
  • direct compare branches (contrast / analogy) now receive an explicit structural promotion over reference-only notes, and this behavior is covered by regression tests.

Remaining gap: the feature mix now has graph-specific gates, but still needs calibration through more real-world ranking regressions and broader operator evidence.

P3: Keep answer-surface contraction strict

The public answer area should render:

  • direct answer,
  • minimal rationale if needed,
  • one or two graph-derived ordering/path statements only when they change the answer.

Current baseline: the public answer / directAnswer string is intentionally narrow. Evidence lists, graph connection paths, temporal details, memory notices, and knowledge_run diagnostics are retained in assistantBlocks, trace.graphContext, evidence panes, durable artifacts, and workspace export rather than being concatenated into the visible answer.

The evidence pane should render:

  • connection paths,
  • relation summaries,
  • temporal details,
  • citations,
  • workflow artifacts,
  • developer trace diagnostics.

This separation solves the user's first and third concerns better than trying to tune one monolithic answer template.

P4: Harden right-pane source focus

The current slice now broadens workspace_panes.js graph-focus render diagnostics beyond hidden controller state. The current controller records:

  • requested sourcePath,
  • markdown runtime availability,
  • storage-provider availability,
  • source read success,
  • markdown render success or fallback,
  • highlight-term count,
  • highlighted node count,
  • candidate source paths,
  • attempted source paths,
  • resolved source path,
  • whether a path fallback was used,
  • failure reason classification.

Expected failure classes remain:

  • Windows path separator or KB-root prefix mismatch,
  • sourcePath absent but citation/matchedSpan path present,
  • snippet text normalized differently from rendered markdown,
  • old runtime file path still used by a legacy entrypoint,
  • markdown rendering succeeds but highlight terms are too narrow.

The current code now uses those diagnostics across operator-facing paths without forking the rendering stack:

  • graph focus retries candidate paths collected from both payload and matched spans before falling back,
  • inline highlighting reports whether it used source_offset_provenance, source_fragment_provenance, text_search, or no inline match,
  • repeated identical fragments inside one authenticated rendered block use source offsets to select the correct occurrence when offsets are present,
  • the graph-focus pane renders diagnostics when fallback or path-fallback behavior occurs,
  • durable knowledge_run artifacts retain graphContext, and the knowledge-run inspection card shows graph context plus graph diagnostics for operator review.
  • knowledge-run history now shows compact graph telemetry per run, and run-to-run comparison cards expose path / temporal-warning / graph-fallback deltas for calibration review.
  • the agent workspace now persists interesting graph-focus diagnostics into session state and later conversation/study-session writes preserve that history instead of overwriting unrelated panelState domains,
  • WorkspaceExportBundle now emits durable runtime.knowledgeRunReports and runtime.graphFocusReports, so the same graph telemetry can be replayed and analyzed offline without reimplementing the frontend summary logic.

The best fix still remains typed payload/path/span provenance plus highlight diagnostics, not a second rendering stack. The current implementation is precise when offsets exist and backward-compatible when they do not. The remaining gap is calibration quality and offset coverage: decide whether richer AST provenance is justified only after current knowledgeRunReports + graphFocusReports prove offset-backed spans insufficient.

P5: Add graph answer quality gates

Implemented foundation in the current working tree through knowledgeRun.quality.gates. The active graph-specific gates now cover:

  • prerequisite questions include upstream path order,
  • comparison questions preserve branch differences and no longer treat reference-only support as sufficient branch evidence,
  • stale/superseded nodes trigger temporal warnings,
  • graph ops failure falls back cleanly,
  • oversized graphs are budgeted deterministically.

Remaining gap: add more regression coverage breadth and longer-run operator evidence before treating the quality model as fully calibrated.

Tradeoffs

  • Do not dump the DAG into prompts: full graph context increases latency, cost, and hallucination surface. A bounded context pack is more reliable.
  • Do not replace retrieval with graph traversal: lexical/semantic retrieval still finds the question target. DAG traversal should refine and explain, not blindly roam.
  • Do not depend on Python prompt frameworks in the app runtime: they are useful research references, but the deployment target is TypeScript/Node/Tauri/Godot.
  • Do not overtrust inferred edges: inferred links need provenance and confidence, especially when used to order learning explanations.
  • Do not hide graph context completely: users do not need developer traces in the answer, but developers need them in evidence/export surfaces to debug behavior.

Mental Model

Think of the answer pipeline as three separate decisions:

  1. Find the likely subject: retrieval and scope resolution identify candidate atoms/documents.
  2. Place the subject inside the DAG: graph context assembly decides what upstream, downstream, path, temporal, and evidence facts matter.
  3. Speak to the user: answer synthesis uses the selected context but only shows what the user's question requires.

The model is not "RAG plus graph decorations." It is "retrieval finds candidates; DAG determines structural relevance; composition decides visible communication."

Real Applications

  • A "what is X?" question should answer X directly, then optionally state its immediate prerequisite if that prerequisite changes understanding.
  • A "how do I learn X?" question should use topological order and prerequisites more heavily than citations.
  • A "compare X and Y" question should find the nearest common ancestors, divergent successors, and relation kinds between the branches.
  • A "is this still valid?" question should prioritize TemporalEdge and supersession over similarity score.
  • A file hit click should open the source markdown because the user's inspection task is document reading, not graph debugging.

Common Pitfalls

  • Treating "we have graphdb/sqlite" as equivalent to "the answer is graph-native." Storage is not reasoning.
  • Treating relation degree as knowledge quality. Degree is often a hub signal, not an answer signal.
  • Losing directionality when formatting paths. A -> prerequisite -> B and B -> prerequisite -> A are different claims.
  • Letting graph diagnostics leak into the public answer because the data is available.
  • Creating a new facade that only forwards calls from KnowledgeLearningPlatform without owning invariants.
  • Adding prompt frameworks before defining the local graph context contract.
  • Ignoring temporal edges, which can make the system confidently explain obsolete knowledge.

Five-Point Summary

  1. The project already has a real DAG substrate; the missing piece has moved from “extract the assembler” to “calibrate graph-aware ranking and quality gates.”
  2. The public answer must stay targeted; this slice keeps answer / directAnswer free of evidence/debug lists while preserving those details in evidence panes, traces, and exports.
  3. The graph-focus path is now durable end to end: pane diagnostics cross the runtime boundary, survive later session-state writes, export as runtime.graphFocusReports, and now include offset-backed inline highlight provenance for repeated-fragment disambiguation.
  4. The referenced open-source projects are best used as design patterns, not new runtime dependencies.
  5. The next robust direction is deeper calibration and carefully scoped owner reduction, not broader framework adoption.

中文文档

目标

本文档在 2026-06-10 知识工作区 / DAG 对齐基础上,按用户最新澄清更新方案:这里的图结构是本项目现有的 DAG 结构化知识数据,不是泛泛的图数据库产品。

本方案要解决的目标是:

  1. 前端公开回答区只针对用户问题给出回答;
  2. supporting evidence、graph trace、开发者/调试材料进入次级 pane 与可导出的 trace;
  3. 文件命中项单击后稳定打开右侧 focus pane,并显示原始 markdown 与命中高亮;
  4. 不再只把 DAG 当作浅层关系加分项,而是把它提升为 answer planning substrate;
  5. 在演进过程中保持向前兼容与鲁棒性。

2026-06-20 完成性审计

  • 这份计划中的实现切片已经完成,P0P5 都已经体现在当前代码里,而不再只是设计方向。
  • 完成边界以这份计划的编号切片为准。后文的“剩余缺口”“权衡”“下一步方向”描述的是后续校准或新一轮迭代,不再构成本计划的未完成 blocker。
  • 2026-06-20 当日重新采集的强证据:
  • npm test -- --runInBand:112 个 suite 通过,893 个测试通过,26 个 skipped。
  • npm exec -- tsc --noEmit:通过。
  • npm run build:mini:通过。
  • node scripts/verify-knowledge-workspace-runtime.js --case waterglass_explicit_scope_compact_zh:通过。
  • 当前实现已经覆盖用户最初提出的关键验收面:
  • 公开回答区收缩,不再把 evidence/debug 材料堆进主回答;
  • 右侧 pane 稳定打开原始来源并执行 matched-span 高亮;
  • 知识命中项的点击提示文案,以及固定的 Learning Path / Related Focus 动作;
  • DAG-conditioned context assembly 与 graph-aware retrieval/ranking;
  • 通过 knowledgeRunReportsgraphFocusReports 暴露可回放的图回答质量与运维 telemetry。
  • 因此本计划状态更新为 completed。后续若继续扩 ranking calibration 或更重的 provenance 能力,应作为新迭代跟踪,而不是无限期维持这份架构计划为 in_progress

第一性原理

术语定义

  • DAG:有向无环图。在本项目中,它是由概念、笔记、atom、indexed unit 组成的有向知识结构,边表达 prerequisite、reference、next step、supersession、temporal replacement 等关系。无环约束很重要,因为拓扑顺序与先修链只有在环不存在或被显式处理时才可靠。
  • KnowledgeAtomsrc/learning/KnowledgeLearningPlatform.tssrc/learning/types.ts 使用的学习层知识单元,比整篇 Markdown 更小、更适合查询。
  • RelationEdge:atom 之间的有向语义边,携带关系类型、置信度、provenance 与证据关联。
  • TemporalEdge:描述有效期、替换、过期、supersession 的边,防止回答层把旧知识当成当前有效事实。
  • EvidenceSpan:能把 atom 或回答 claim 连接回 markdown 原文的文本证据片段。
  • Anchor:当前用户问题的主要 atom 或文档中心。
  • Support node:不是 anchor,但用于解释、证明、对比、排序或限定回答的 atom。
  • Path:由有向边连接起来的一组有序 atom ID。path 不是普通“相关内容”,而是关于概念如何连接的结构性声明。
  • Predecessor:anchor 的传递上游依赖。
  • Successor:anchor 的传递下游结果或下一步节点。
  • Topological order:一种 DAG 节点顺序,保证先修节点出现在依赖它的节点之前。
  • GraphContextPack:传给 answer synthesis 的有界、确定性图上下文。它应包含 anchor 身份、support nodes、relation summaries、explicit paths、temporal warnings、evidence spans。它绝不应该是整张图。
  • Public answer:用户直接看到的简洁回答。
  • Evidence pane:次级 UI 表面,用于查看 citation、graph context、durable artifact 与开发者 trace。
  • Developer trace:给开发者和运维查看的结构化运行时/导出 payload。它应保留,但不应挤占公开回答区。

分层架构

当前项目已经有多层携带图信息的结构。实现方案必须尊重这些层的职责,而不是全部塞进一个“RAG”概念里。

  1. Markdown 源层
  2. Owner:Knowledge_Basesrc/backend/FileLoader.ts、markdown reader/runtime。
  3. 职责:保存源文本、frontmatter、links、headings、evidence spans。
  4. 边界:文件路径与源内容必须足够 canonical,右侧 pane 才能读取原文并高亮命中。

  5. 图构建层

  6. Owner:src/backend/GraphBuilder.tssrc/core/Graph.tssrc/core/PathEngine.ts、path workers。
  7. 职责:构建节点/边、dependency edge、inferred edge、layout rank、predecessor/successor/path 操作。
  8. 边界:这一层给项目提供结构化 DAG,但它本身不是 LLM prompt。

  9. 学习 atom / relation 层

  10. Owner:src/learning/KnowledgeLearningPlatform.tssrc/learning/types.tssrc/learning/store.ts
  11. 职责:维护 KnowledgeAtomRelationEdgeTemporalEdgeEvidenceSpan、snapshot、graphdb/sqlite/file-backed ops,以及 findPath 路径查询。
  12. 边界:这是回答阶段图上下文的正确来源,因为这里有 atom ID、关系元数据、时序状态和源证据。

  13. 检索层

  14. Owner:src/learning/queryBackend.ts
  15. 职责:在 scope 约束下,用 keyword/vector/hybrid scoring 产出候选 atom。
  16. 当前现实:DAG 主要以 connection-degree bonus 进入排序(local hybrid 为 0.08,local vector 为 0.06),并在检索后提供 relation-path hints。这有价值,但还不是 graph-native answer planning。

  17. Graph-conditioned context assembly 层

  18. 建议 owner:新的 learning domain owner,不应放在 server.ts 或前端里。
  19. 职责:把检索候选转成有界 GraphContextPack:选择 anchor,展开 predecessor/successor/path 窗口,应用 temporal validity,附加 evidence spans,并控制 token/size budget。
  20. 当前 2026-06-17 切片:已经通过 src/learning/graphContextAssembler.ts 进入一等 owner 阶段,会在回答合成前选择 anchor、重排 support node、挂接显式 connectionPaths、补有界 predecessor/successor window,并记录 evidence ref 与 graph diagnostics。
  21. 同一切片也保护了 read-side 自动保存路径:持久化重建 snapshot 前会合并仍然有效的 store 侧 relation/temporal edges,避免当前图底座被查询/对话读流程误删。
  22. 同一切片还收缩了公开 answer / directAnswer 字符串,不再把 citation list、connection path、memory notice 或 knowledge-run diagnostics 拼进用户回答。
  23. 剩余缺口:当前 retrieval ranking 仍过度依赖浅层信号,右侧 source focus 也还需要补路径 / 高亮诊断。

  24. 回答合成层

  25. Owner:src/learning/conversationComposer.ts 以及后续 composer/assembler 模块。
  26. 职责:用 graph-conditioned context 生成 targeted answer,同时保持公开回答简洁。
  27. 边界:回答可以在 typed structured section 与 trace 中携带图路径,但不能把 evidence、relation summary 和 diagnostics 倒进公开回答区。

  28. UI 与导出层

  29. Owner:src/frontend/agent_workspace.jssrc/frontend/workspace_panes.jssrc/export/WorkspaceExportBundle.ts
  30. 职责:公开回答渲染、右侧 focus、evidence pane、durable artifact、workspace export。
  31. 边界:前端应该投影结构化 payload,而不是从展示字符串里反推图语义。

各层如何连接

理想运行流程应是:

  1. 用户问题进入 /api/knowledge/conversation
  2. API/runtime 边界一次性归一化 scope。
  3. 检索返回有限 atom/document 候选。
  4. Graph-conditioned context assembly 选择 anchor,并向 learning graph 查询:
  5. 候选之间的直接关系;
  6. 候选 atom 与 anchor 之间的显式路径;
  7. prerequisite predecessors;
  8. successor / next-step nodes;
  9. temporal validity 与 supersession details;
  10. source evidence spans。
  11. assembler 对图上下文做预算控制与排序。
  12. composer 生成:
  13. 简洁 public answer;
  14. 可选 typed assistantBlocks
  15. trace.graphContext
  16. 必要时的 durable artifacts。
  17. UI 首先渲染 public answer。
  18. 文件命中项打开右侧 pane,展示原始 markdown 与命中高亮。
  19. evidence / graph / debug material 留在 evidence pane 与 export bundle。

这个顺序很关键。如果图扩展发生在 scope 归一化之前,就可能越过用户指定语料边界。如果图扩展只发生在回答合成之后,LLM 就无法用 DAG 规划回答。如果图扩展不设边界,prompt 体积与延迟会比答案质量涨得更快。

当前代码与要求对比

要求 当前代码现实 2026-06-17 状态 缺口 / 风险
公开回答区只回答用户问题,不罗列内部产物 buildScopedConversationAnswer() 现在只返回单一 targeted answer 字符串;citation list、graph path、memory notice 与 knowledge-run diagnostics 保留在 typed blocks、trace、pane 或 export 中。 当前切片已实现 后续 DAG context 不能把回答区重新撑大。
暂时隐藏开发者导向 evidence 与紫框类 support material evidence pane 与 runtime/export trace 已承接支持上下文。 方向正确 新增图细节默认应进次级 surface,除非用户显式要求。
文件命中单击后打开右侧内容并高亮命中 workspace_panes.js 已通过 graph focus 路由文件项,读取 markdown,经共享 markdown runtime 渲染,并用 matched spans 高亮;当前还会记录 inlineHighlightStrategy,并在 citation / matched span 带有 EvidenceSpan offset 时使用 source_offset_provenance 去区分同一认证块里的重复片段。 已实现扩展 P4 切片 剩余风险是旧 payload 没有 offset,或未来确实需要更丰富 nested AST provenance;不是 pane 打不开或诊断无法持久化。
使用项目现有 DAG,而不是泛图数据库抽象 KnowledgeAtomRelationEdgeTemporalEdge、store ops、findPath、path/session logic、Graph.ts DAG helper 都已存在。 已确认 先前“图数据库 + prompt framework”的表述过泛。
让 LLM 查阅高质量图结构 2026-06-17 代码现在通过 graphContextAssembler.ts 在回答合成前选择 anchor、重排 support node、保留显式 store path chain、补 predecessor/successor window,并通过 trace/export/evidence pane 暴露 graph diagnostics。 P1 基础已实现 graph-aware ranking 与图专项质量门禁现在都已存在,剩余工作转为校准广度与更广的运维诊断。
显式 scope 下的紧凑混合别名查询也必须召回证据 2026-06-18 修复:planner 推导出的 title-like variant 现在会以扩展 queryTokens 与显式 queryVariants 的形式进入 retrieval;queryBackend.ts 会在 semantic token、anchor inference 与 title matching 中消费这些 variant;runtime verifier 默认以 什么是waterglass? + 什么是water glass 作为验收矩阵。 当前切片已实现 必须把 alias normalization 维持为集中契约,不能靠放宽 evidence gate 掩盖归一化缺陷。
保持兼容 assistantMessage 仍有效;新增 graphContext.connectionPaths 是 optional additive field;snapshot merge 只在两端 atom 仍 active 时保留既有 relation/temporal edges。 已保持 所有客户端和导出路径都要继续把新增字段视为可选。后续需要 edge ownership metadata,才能区分“用户有意删除的边”和“外部增强但内存快照未携带的边”。

开源库研究结论

已将参考仓库 clone 到 ref/ 并作为设计输入分析:

项目 本地 ref 可借鉴模式 不应照搬的部分
DSPy ref/dspy 4987601 typed signature、可评测 program、optimizer 思维。适合把 GraphContextPack -> Answer 定义成可评测程序。 不应为了 prompt rewrite 把 Python optimizer/runtime 引入 TS/Tauri 主路径。
Guidance ref/guidance 21b1d90 constrained generation 与结构化输出纪律。适合严格 JSON/section contract。 prompt templating 不能替代图推理层。
Semantic Kernel ref/semantic-kernel 13f812b 命名 prompt function、execution settings、telemetry boundary。 本项目已有 local owner,不应引入宽框架编排。
LangChain Core ref/langchain 847312e 显式 runnable/pipeline composition 与 parser boundary。 避免引入会复制现有 platform/lifecycle 代码的框架级抽象。
LiteLLM ref/litellm cf2db41 provider routing、fallback、model-call boundary normalization。 provider routing 不应决定图语义。

最佳结论:把这些项目当架构参考,而不是运行时依赖。实现应保持本项目原生:TypeScript 类型、本地图 store ops、可选 JSON/schema-constrained 模型调用、现有 export/diagnostics surfaces。

2026-06-18 运行时回归:紧凑别名检索契约断裂

一条带截图的运行时失败暴露了 scoped waterglass 语料中的剩余跨层缺陷。失败的不是带空格控制组 什么是water glass,而是紧凑混合写法 什么是waterglass?

修复前的运行时事实:

  • node scripts/verify-knowledge-workspace-runtime.js --full --target waterglass --query "什么是waterglass?" 会失败。
  • node scripts/verify-knowledge-workspace-runtime.js --full --target waterglass --query "什么是water glass" 会通过。
  • workspaceReadiness.status 仍然是 ready
  • usedScope.workspaceId / corpusId 仍然是 waterglass
  • planner 仍然能找到正确的 title-like 文档命中,matchedAtomCount 也仍然大于 0。
  • 最终 miss reason 仍然落到 retrieval_candidates_below_threshold

根因:

  • planner 已经扩展出 compact/spaced/title alias(waterglasswater glass水玻璃水杯),
  • 但 retrieval scoring 仍然主要依赖原始 query 字符串与原始 query tokens,
  • 导致 compact mixed-script 写法即使在 planner 命中文档后,仍对 keyword/vector scoring 过于不透明。

本切片修正:

  • KnowledgeLearningPlatform.buildQueryBackendContext() 现在会基于原始 query 与 planner 推导出的 title-like variant 扩展 retrieval queryTokens,并向后端上下文显式传入 queryVariants
  • queryBackend.ts 现在会在 semantic token 构建、anchor 推断与 title matching 中消费这些 queryVariants
  • scripts/verify-knowledge-workspace-runtime.js 现在会把 waterglass 的 compact/spaced 双查询作为默认运行时验收矩阵;只要任何一个 query 再次落回 retrieval_candidates_below_threshold 或返回 0 citations,就会失败。

这对框架选择的含义:

  • 这不是 prompt composition 的主问题。
  • DSPy、Guidance、Semantic Kernel、LangChain Core 与 LiteLLM 可以帮助 structured output、evaluation 或 provider routing。
  • 但它们都无法修复 planner normalization 与 retrieval scoring 之间断裂的词法契约。
  • 正确 owner 是本地 learning-runtime 的 retrieval boundary,而不是再引入一层 orchestration framework。

具体实施计划

P0:稳定当前 2026-06-17 切片

当前工作区已推进:

  • AgentConversationGraphContext 现在支持可选 connectionPaths
  • KnowledgeLearningPlatform 可以通过 ops-capable store 的 findPath 查询返回 knowledge points 与 anchor 之间的显式路径。
  • KnowledgeLearningPlatform 在自动保存重建 snapshot 时保留仍然有效的 store 侧 relation/temporal edges,让 path enrichment 能使用外部增强后的 DAG 结构,而不是被读路径持久化饿死。
  • conversationComposer 可以在结构化回答 section 中引用 explicit graph path,同时保持公开 directAnswer 不包含 evidence/debug 列表。
  • workspace_panes.js 会在 evidence pane 中渲染 connection paths。
  • WorkspaceExportBundle 会在导出的 conversation graph context 中保留 connection paths。
  • 回归测试覆盖 composer output、KLP path enrichment、evidence-pane rendering、locale keys 与 export serialization。

这是兼容安全的改进,因为所有新增字段都是 optional/additive。

P1:抽出 graph-conditioned context assembler

当前工作区已落地为 src/learning/graphContextAssembler.ts

输入:

  • 归一化后的用户问题;
  • resolved scope;
  • retrieved AgentConversationKnowledgePoint[] 或更底层 query candidates;
  • atom/relation/temporal store;
  • budget options。

输出:

  • GraphContextPack / 现有 AgentConversationGraphContext 的扩展;
  • selected anchor;
  • 重排后的 support nodes;
  • explicit paths;
  • predecessor/successor windows;
  • temporal warnings;
  • source evidence span references;
  • graph data 缺失诊断。

当前切片已实现的规则:

  • 默认限制 path depth(当前为 6);
  • 按 answer intent 限制 support nodes;
  • 每条渲染路径保留边方向;
  • graph ops 不可用时 fail open 回到 retrieval-shaped graph context,并附带 diagnostics;
  • predecessor/successor window 有界,并默认停留在次级 evidence surface。

P2:让 retrieval 真正 graph-aware,但不要过拟合 degree

当前工作区已经落下 P2 基础实现。queryBackend.ts 不再把原始 relation-degree bonus 当作主要图信号,而是改为有界图特征组合:

  • candidate 到 title/document anchor 的距离;
  • 相对 anchor 的 prerequisite depth;
  • path existence 与 path confidence;
  • temporal validity score;
  • relation-kind intent match。

当前行为:

  • local_hybridlocal_vector 会先从 query 中推断 title/document anchor;
  • planner 推导出的 compact/spaced alias variant 现在也会进入 retrieval semantic token 与 title/anchor scoring,因此 什么是waterglass? 这类 scoped prompt 不会再出现“planner 已命中文档但 retrieval 仍空转”的断裂;
  • 只有当 anchor 可推断时,图加分才会介入;
  • directed path confidence 与 prerequisite depth 会提升结构上真正相关的 support node;
  • temporal invalidity 现在是惩罚项,而不是盲目的“新鲜度正奖励”;
  • 与 anchor 无关的高出入度 hub 不会再仅靠边多而取胜。

剩余缺口:这套特征已经有图专项质量门禁,但还需要通过更多真实 ranking regression 与运维证据继续校准。

P3:严格保持回答主表面收缩

公开回答区应渲染:

  • direct answer;
  • 必要时的最小 rationale;
  • 只有当图路径会改变答案时,才显示一两句 graph-derived ordering/path statement。

当前基线:公开 answer / directAnswer 字符串刻意保持窄口径。evidence list、graph connection path、temporal detail、memory notice 与 knowledge_run diagnostics 会保留在 assistantBlockstrace.graphContext、evidence pane、durable artifact 与 workspace export 中,而不是拼接进用户可见回答。

Evidence pane 应渲染:

  • connection paths;
  • relation summaries;
  • temporal details;
  • citations;
  • workflow artifacts;
  • developer trace diagnostics。

这种分离比继续调一个超大回答模板更能解决用户提出的第 1 点和第 3 点。

P4:加固右侧 source focus

第一层诊断已经落到 workspace_panes.js 的 graph-focus 渲染链路。当前 controller 会记录:

  • requested sourcePath
  • markdown runtime availability;
  • storage-provider availability;
  • source read success;
  • markdown render success / fallback;
  • highlight-term count;
  • highlighted node count;
  • inlineHighlightStrategy;
  • candidate source paths;
  • attempted source paths;
  • resolved source path;
  • path fallback usage;
  • failure reason classification。

预期失败类型:

  • Windows 路径分隔符或 KB-root 前缀不一致;
  • sourcePath 缺失但 citation/matchedSpan path 存在;
  • snippet 文本归一化方式与渲染后的 markdown 不一致;
  • legacy entrypoint 仍在使用旧 runtime 文件;
  • markdown 渲染成功,但 highlight terms 太窄;
  • 旧 payload 没有 startOffset / endOffset,只能回退到 source fragment 或 text search。

最佳修复仍然是 typed payload/path/span provenance + highlight diagnostics,而不是再造一套渲染栈。当前 offset 存在时可以精确命中重复片段,offset 缺失时保持向前兼容的保守回退。2026-06-18 之后,这些诊断已不再只停留在 graph-focus pane/controller 层,而是通过 session state 与 runtime.graphFocusReports 进入更广的运维检查面;剩余缺口转为“offset 覆盖与运维汇总是否足够”的校准问题。

P5:增加图回答质量门禁

当前工作区已经通过 knowledgeRun.quality.gates 落下第一版图回答质量门禁,覆盖:

  • prerequisite 问题应包含上游路径顺序;
  • comparison 问题应保留分支差异;
  • stale/superseded 节点应触发 temporal warnings;
  • graph ops 失败时应保持 clean fallback;
  • oversized graph 经过确定性预算裁剪。

剩余缺口:继续补回归覆盖广度和运维侧证据,再决定是否把这套质量模型视为完全校准。

权衡

  • 不要把整张 DAG 塞进 prompt:全量图上下文会增加延迟、成本和幻觉面。有界 context pack 更可靠。
  • 不要用图遍历替代检索:lexical/semantic retrieval 仍负责找到问题目标。DAG traversal 应用于 refinement 和 explanation,而不是盲游图谱。
  • 不要把 Python prompt framework 引入 app runtime:它们适合作为研究参考,但部署目标是 TypeScript/Node/Tauri/Godot。
  • 不要过度信任 inferred edges:推断边必须带 provenance 与 confidence,尤其当它们用于排序学习解释时。
  • 不要完全隐藏 graph context:用户不需要在回答区看开发者 trace,但开发者需要在 evidence/export surface 中调试行为。

思维模型

把回答流水线拆成三个决策:

  1. 找到可能的主体:retrieval 与 scope resolution 识别 candidate atoms/documents。
  2. 把主体放回 DAG:graph context assembly 决定哪些 upstream、downstream、path、temporal、evidence facts 与当前问题有关。
  3. 对用户表达:answer synthesis 使用已选上下文,但只展示用户问题需要的内容。

这不是“RAG 加图装饰”。更准确地说,是“检索找候选;DAG 决定结构相关性;合成层决定可见表达”。

真实应用

  • “what is X?” 应直接回答 X,只有当前置概念会改变理解时才补充一个直接 prerequisite。
  • “how do I learn X?” 应更重地使用拓扑顺序与 prerequisites,而不是只堆 citation。
  • “compare X and Y” 应找 nearest common ancestors、分叉 successors 和分支之间的 relation kinds。
  • “is this still valid?” 应优先使用 TemporalEdge 与 supersession,而不是相似度分数。
  • 文件命中项点击后应打开源 markdown,因为用户此时要做的是文档阅读,不是图调试。

常见误区

  • 把“已经有 graphdb/sqlite”误认为“回答已经 graph-native”。存储不是推理。
  • 把 relation degree 当成知识质量。degree 经常只是 hub 信号,不是答案信号。
  • 格式化路径时丢掉方向。A -> prerequisite -> BB -> prerequisite -> A 是不同声明。
  • 因为图诊断数据已经存在,就把它泄漏到公开回答区。
  • 新增只转发 KnowledgeLearningPlatform 调用、但不拥有不变量的 facade。
  • 在定义本地图上下文契约前就引入 prompt framework。
  • 忽略 temporal edges,导致系统自信解释过期知识。

五点总结

  1. 项目已经有真实 DAG 底座;当前缺口已经从“抽出 assembler”转成“校准 graph-aware ranking 与质量门禁”。
  2. 公开回答必须保持 targeted;本切片让 answer / directAnswer 不再携带 evidence/debug 列表,同时把这些细节保留在 evidence pane、trace 与 export。
  3. graph-focus 路径现在已经形成端到端的 durable 链路:pane 诊断会跨过运行时边界,保留到后续 session-state 写入中,导出为 runtime.graphFocusReports,并且已经包含 offset-backed inline highlight provenance 来处理重复片段去歧义。
  4. 参考开源库更适合作为设计模式,不适合作为新的运行时依赖。
  5. 下一步应把重心转到更深的校准与克制的 owner reduction,而不是继续扩大框架面。