DX · DamnatioX Agent
终端优先的 Python Agent:RAG、Tools、Coding Harness、Skills、上下文压缩与回答校验。
它是一个非常暴躁的 agent · 测试版本,Agent 链路和边界判断仍在完善
⚡ Quick Start | 🧠 Architecture | 🛠 Tools | 🧩 Skills | 📦 Release
整体架构
当前实现以 AgentChain 为单轮编排入口,以 prompt-toolkit 全屏布局和 Rich
命令渲染组成 DamnatioX Agent 终端前端。会话历史、当前轮执行状态、工具
结果和事实证据分别存储,历史工具结果不会直接成为下一轮事实依据。
安装与首次启动
DamnatioX 以 damnatiox-agent 作为 Python 分发名,以 damnatiox 作为终端
命令。当前代码使用 Python 3.14 语法:
pipx install damnatiox-agent
damnatiox
需要显式指定解释器时:
pipx install --python C:\Python314\python.exe damnatiox-agent
从源码开发或验证:
py -3.14 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\damnatiox.exe
PyPI 安装包与知识库样例
结论:通过 PyPI 或 pipx 安装时,data/ 中的知识库样例会随 wheel 一起下载。
已核验 PyPI 0.1.0,安装包包含以下只读资源:
| 内容 | Wheel 内位置 | 是否随安装下载 |
|---|---|---|
| 知识库样例 | damnatiox_agent/resources/data/*.md |
是 |
| 默认分块 | damnatiox_agent/resources/vector_store/chunks.json |
是 |
| 默认向量 | damnatiox_agent/resources/vector_store/embeddings.npy |
是 |
| 用户 API Key | ~/.damnatiox/config.json |
否,本机首次启动时创建 |
| 会话和模型偏好 | 工作区 .damnatiox/ |
否,本机运行时创建 |
| 独立计算器样例脚本 | calculator.py |
0.1.1 起移除 |
运行时优先使用当前工作区已有的 vector_store/;工作区没有索引时读取 wheel
内置的样例索引。PyPI 安装方式见上方 Quick Start。
首次启动凭据链路如下。DeepSeek 地址固定为 https://api.deepseek.com,界面只
收集 API Key:
flowchart TD
A["执行 damnatiox"] --> B{"DEEPSEEK_API_KEY 是否存在"}
B -->|"是"| F["创建 DeepSeek Client"]
B -->|"否"| C["读取 ~/.damnatiox/config.json"]
C --> D{"api_key 是否存在"}
D -->|"是"| F
D -->|"否"| E["在 TUI 密码输入框中填写并原子保存"]
E --> F
F --> G["加载 AgentChain 并启动全屏 TUI"]
DEEPSEEK_API_KEY 适合临时运行和自动化,不写入配置文件;交互输入保存到用户
目录的 ~/.damnatiox/config.json。项目的 .gitignore 排除了该目录、旧版
config.py 和 .env*,API Key 也不会写入日志或构建产物。
完整运行链路
flowchart TD
UI["DamnatioX TUI:输入、状态、工具卡片、回答"] --> A["用户输入"]
A --> B["创建 TurnState"]
S["SessionState:摘要、最近对话、未完成任务、用户约束"] --> C
SK["SkillManager:元数据目录、显式选择、按需正文"] --> C
B --> C["Input Context Builder"]
C --> D["Router:chat / rag / tools / research"]
D -->|"chat"| X["Answer Context Builder"]
D -->|"rag / tools"| E{"是否复杂任务"}
D -->|"research"| F["Planner"]
E -->|"否"| G["Tool Selector:选择一个或多个工具"]
E -->|"是"| F
F --> H["生成 PlanStep 和完成条件"]
G --> H
H --> I{"Loop Guard:模型轮次、重试和重规划预算"}
I -->|"允许执行"| JB["Tool Batch Scheduler:校验、指纹、缓存和能力策略"]
I -->|"达到预算"| X
JB --> JC{"是否包含写入或独占屏障"}
JC -->|"否"| JD["独立批次:parallel_safe 并发,否则顺序执行"]
JC -->|"是"| JE["连续独立段内并发,写入和命令逐项执行"]
JD --> K["RAG / Search / DB / File / Browser / Coding / PowerShell"]
JE --> K
K --> L["按原 tool_call 顺序提交 ToolResult 到 TurnState"]
L --> M["Tool Failure Policy"]
M -->|"success / partial"| N["Current-turn Evidence Registry"]
M -->|"retryable error"| I
M -->|"empty / fatal / repeated"| O{"是否选择其他工具"}
O -->|"是"| F
O -->|"否"| X
N --> P["证据去重、过滤、重排和预算裁剪"]
P --> X
X --> Q["构建回答上下文"]
Q --> R["生成 Draft"]
R --> T["格式与确定性校验"]
T -->|"格式问题"| R
T -->|"通过"| U["事实与引用校验"]
U -->|"需要补充证据"| V{"仍有重规划预算"}
V -->|"是"| F
V -->|"否"| W["基于现有证据收敛回答"]
U -->|"仅回答内容问题"| R
U -->|"通过"| Y["最终回答"]
W --> Y
Y --> Z["Session Memory Writer"]
Z --> AA["生成精简 TurnRecord"]
AA --> AB["更新 SessionState"]
AB --> AC{"上下文是否超过预算"}
AC -->|"是"| AD["更新 SessionSummary 并裁剪旧 TurnRecord"]
AC -->|"否"| AE["等待下一次用户输入"]
AD --> AE
链路分段说明
-
启动阶段
- 从环境变量或
~/.damnatiox/config.json解析 API Key;首次使用时直接在 prompt-toolkit 密码输入框完成配置。 - 使用固定 DeepSeek API 地址创建兼容 Client,然后绘制 DamnatioX 首帧。
- 加载
vector_store/;索引缺失时从data/构建。 - 扫描项目和用户 Skill 目录,只登记通过校验的
SKILL.md。 - 创建进程级
SessionContext、SkillManager、ToolExecutor和AgentChain。
- 从环境变量或
-
Input Context 与 Router
- 每次输入创建独立
TurnState和TurnRagContext。 - Input Context Builder 只加入结构化摘要、最近对话和当前输入。
/skills选中的 Skill 只在当前请求上下文中披露完整正文;未选 Skill 只保留名称和说明,不进入模型 Prompt。- Router 使用严格 JSON 返回
chat / rag / tools / research、复杂度、置信度、 原因和建议工具;连续解析失败时使用确定性规则回退。 rag只代表“应该尝试知识库”。随后真实执行一次轻量检索,由 RAG Coverage Gate 根据空结果、错误和最低相关分判断知识库是否收录。
- 每次输入创建独立
-
计划和执行阶段
chat直接进入回答上下文;简单rag/tools使用单步计划。research和复杂任务调用严格结构化 Planner,生成有序PlanStep描述、 完成条件和工具白名单;当前执行器合并所有步骤的工具名作为本轮全局 allowlist,尚未维护逐步推进的 step cursor。该 allowlist 既过滤传给模型的 Tool Schema,也在 ToolExecutor 执行前再次强制检查。- 回答模型可在一次响应中给出多个互不依赖的读取调用;Scheduler 把混合调用
切成连续独立段和写入/命令屏障。段内只有全部工具声明
parallel_safe时才 使用最多 4 个 worker;RAG 等只读但未声明线程安全的工具顺序执行,同时仍 保留同批其他独立查询的结果。 - Loop Guard 默认以模型轮次、可重试错误和重新规划次数收敛链路,不再用固定 20 秒 API 超时中断已经成功的工具任务。
- Search、SQLite、File、Browser 和 Python Code 已与 RAG、Calculator 一起 注册到现有 ToolExecutor。
- Coding 请求继续复用同一个执行入口,可组合 Glob、Grep、Read、Write、 Edit、受约束 Command、结构化只读 PowerShell 和 Python Interpreter; MCP 继续保留为后续扩展槽位。
-
Tool Executor 和 Failure Policy
- 所有工具先在主线程完成注册检查、JSON 参数校验、规范化参数指纹、单轮缓存
和同批 single-flight 去重;worker 只运行工具函数,不修改
TurnState。 - 纯计算、Search、静态 Browser、SQLite、File/Glob/Grep 和结构化只读 PowerShell 可受控并发;RAG、写入、编辑、Command 和未知工具默认独占。
- 批次完成后严格按模型原始
tool_call顺序登记 Evidence 和 ToolResult, 因此并发完成顺序不会改变E1/E2、消息顺序或 workspace revision;写入 屏障成功后才准备后续读取,从而避免旧 revision 的 cache/single-flight 污染。 - 进程工具随后进入
tool/sandbox.py的命令白名单、工作区路径、精简环境、 非交互 stdin、超时和输出预算检查。 - 所有执行结果统一转换为
ToolResult,状态为success、partial、empty、retryable_error、fatal_error或repeated。 - 独立段中的失败彼此隔离:成功的兄弟调用继续保留;全独立批次只有全部失败
时才聚合失败上下文。若后面还有写入或命令屏障,任一前置读取失败都会先把
控制权交还模型,避免在不完整输入上执行副作用。屏障自身失败也会停止后续
副作用,但仍为每个原始
tool_call_id生成TOOL_CALL_SKIPPED结果。 - single-flight/cache 副本复用首个相同指纹的失败决策,一次物理失败只消耗 一次重试预算;单个模型响应最多执行 16 个工具调用,超出的调用同样生成 可观测的 skipped 结果。
- 成功、部分成功和空的可缓存只读结果可在同轮复用;瞬时失败释放相同参数 指纹供受预算控制的重试。RAG 继续复用原有查询缓存和最多 3 次实际检索限制。
execution_ms、物理batch_wall_ms/batch_size/parallel_width、模型响应级logical_batch_wall_ms/logical_batch_size、cache_hit和single_flight_hit写入结果元数据,便于后续基准测试。
- 所有工具先在主线程完成注册检查、JSON 参数校验、规范化参数指纹、单轮缓存
和同批 single-flight 去重;worker 只运行工具函数,不修改
-
Evidence 和回答阶段
- 任何携带非空 Evidence 的工具结果都写入仅属于当前
turn_id的 Registry; 失败状态也可因此保留可观测的进程信息。 - Evidence Registry 分配
E1等引用编号,完成去重、分数过滤、排序和字符 预算裁剪,并为最近的编辑与验证结果分别预留项目数和字符份额。 - Answer Context Builder 使用会话摘要和最近对话理解意图,但只把当前轮 Evidence 作为工具及知识库事实依据。
- 工具循环中的即时结果通过
role=tool结构化 JSON 直接交给下一次模型调用; 消息保留data和紧凑 Evidence 引用,Evidence 正文只在当前轮 Registry 保存,避免同一大段工具输出在一条消息内出现两次。 - Coding 路线还会动态注入当前工作目录、Git 分支、最近提交和工作区变更
概览;相同
workspace_revision的回答修复循环复用一次快照,工作区变化后 才重新读取 Git 状态。
- 任何携带非空 Evidence 的工具结果都写入仅属于当前
-
校验和会话写回
- 候选回答依次经过精确输出、JSON、空内容和长度等确定性检查。
- 所有用户输入(包括完整问候语)至少经过 LLM Router 和回答模型,不再按问候 文本设置本地特例。
- 简单
chat在确定性格式检查通过后直接收敛;复杂chat、RAG、工具和 Research 继续进入通用质量 Validator,避免对短问题固定增加评价器循环。 - 通用质量 Validator 使用隔离后的当前轮证据上下文。
- Grounding Validator 逐项检查事实断言和
[E1]引用;缺少证据时可在预算 内补充检索,否则生成明确说明证据不足的收敛回答。 - 最终回答通过后才生成精简
TurnRecord;上下文估算达到 700,000 tokens 时调用 LLM 更新结构化SessionSummary,并尽量压缩到 500,000 tokens。
当前已知状态与问题
下表记录第二至第四阶段完成后的实际状态。
| 环节 | 状态 | 当前表现与后续处理方向 |
|---|---|---|
| 四分类 Router | 已实现 | 严格解析 JSON,返回置信度、复杂度、原因和建议工具,并具有确定性回退。 |
| 知识库覆盖判断 | 已实现基础版 | rag 路线执行真实检索后,按错误、空结果和默认 0.5 分数阈值判断覆盖;阈值仍需用正式评估集校准。 |
| 统一工具结果 | 已实现 | RAG 和普通工具都返回 ToolResult,失败、空结果和重复调用具有明确状态。 |
| 当前轮 Evidence 隔离 | 已实现 | Validator 只接收当前 turn_id 的 Evidence;历史对话只用于理解意图。 |
| 引用和事实校验 | 已实现基础版 | 本地检查引用编号,LLM 逐项输出 claim 支撑关系;仍需扩大事实校验回归集。 |
| Planner | 已实现基础版 | 复杂任务可生成最多 6 个有序步骤描述;当前使用全步骤工具并集作为 allowlist,逐步推进、PlanStep DAG 和多 Agent Researcher 仍在后续阶段。 |
| Tool Batch Scheduler | 已实现受控并发版 | 连续独立段有界并发、非线程安全读取顺序执行、写入与未知工具作为失败屏障、结果顺序提交、single-flight、同轮缓存和批次级单次重规划。 |
| Coding Agent | 已实现增强版 | 已具备并行只读定位、Glob、Grep、按行读取、原子写入、唯一文本编辑、受约束 argv 命令、项目脚本验证和结构化只读 PowerShell。 |
| Skills | 已实现显式选择版 | 支持多目录发现、安全 YAML 校验、最多 5 个启用项、渐进正文披露、工具名交集和 /skills 选择。 |
| DamnatioX TUI | 已实现全屏版 | 固定输入栏、完整持久化会话历史、稳定滚轮浏览、模型/effort 选择浮层、显式思考显示开关、工具活动、时间统计和真实流式回答。 |
| 工具覆盖范围 | 已实现首版 | 已注册 RAG、网页搜索、SQLite、文件与 Coding、静态网页读取、Python 执行、计算器和文本长度工具;Browser 暂不执行 JavaScript。 |
本轮链路评估与优化依据
本轮没有把整条链路替换成另一套框架,而是针对实际热路径做局部优化:
| 观察点 | 修改前 | 当前处理 | 仍保留的边界 |
|---|---|---|---|
| 同一模型响应中的多个工具 | 逐个串行 | 按 capability 切成独立段与副作用屏障,段内有界并发 | 只并发明确声明安全的连续独立调用 |
| 工具线程与共享状态 | 执行和提交耦合 | prepare → run → ordered commit 两阶段 |
AgentChain 本身仍是单会话单轮执行器 |
| 同参数重复读取 | 直接返回 repeated |
成功/空只读结果同轮缓存,批内 single-flight | 写入、命令和未知工具保留重复保护 |
| 批次失败 | 每个失败都可能重新规划 | 相同物理失败只计一次预算;保留成功兄弟结果;前置读取或屏障失败时跳过后续副作用 | Planner 尚未形成带依赖边的 DAG |
| 回答上下文工作区状态 | 每次修复读取三次 Git | 按 workspace_revision 复用快照 |
外部进程绕过工具改文件时需下一轮刷新 |
| 即时 Tool Message | data 和 Evidence 正文重复 |
data + Evidence ID/URI 紧凑索引 |
Validator 仍从 Registry 读取完整正文 |
| 普通短请求 | 固定 Prompt 偏长且总进入评价器 | System Prompt 本地估算约 247 tokens;简单 chat 只保留 Router、回答模型和确定性检查 | 复杂任务与带证据任务仍保留独立质量/事实校验 |
简单与复杂任务现在采用同一个 LLM Router,不使用文本关键词为问候建立旁路。
Router 返回 complex_task=false 的 chat 时,主链路执行一次回答生成和确定性
格式门后结束;complex_task=true、research、RAG 和工具路线继续使用 Planner、
工具反馈、质量评价和证据校验。该分层遵循“先用最简单可行流程,只有在任务确实
需要时再增加 Agent 循环”的原则,同时保留复杂编码与多来源研究的规划入口。
实现策略与以下公开实现相符:
- AI Agent Book Coding Agent 给出 Code Interpreter、Shell、Read、Write、Edit、Glob、Grep 的极简工具集, 并强调用测试、类型系统和版本控制形成 Harness 反馈。
- Codex API 的类型化请求接口
在 Responses 请求中保留
parallel_tool_calls,并把工具、推理和流事件放入 统一协议层。 - Claude 并行 Tool Use 采用同一 assistant 消息发出多个调用、随后返回对应结果的批次结构。
- Hermes Agent Loop
对多工具使用
ThreadPoolExecutor,交互型工具保持串行,并按原调用顺序 重新插入结果。
因此当前并发单元是“同一次模型响应中的独立工具调用”,不是多轮 Prompt、
PlanStep 或多个会话同时写入一个 TurnState。这种边界先解决可测量的工具等待
时间,同时保持 Evidence ID、工具消息和 Coding 工作区写入顺序稳定。
本轮冗余检查
本轮移除了几条已经退出主链路的旧路径:
- 删除旧三分类
router_classify(),统一使用四分类route_request()。 - 删除
systemprompt.py中旧 Router 模板和旧 RAG 字符串拼接模板。 - 删除模块级
_vectorstore、set_vectorstore()和旧字符串版search_knowledge_base();RAG 继续由 ToolExecutor 专用适配器执行。 rag/__init__.py改用延迟导出,保留原公开导入方式,同时让普通链路测试 跳过提前加载 SentenceTransformer。- 清理 RAG Pipeline、Embedding 和 API 冒烟脚本中的未使用 import。
- 精简通用 Validator 的消息快照,只处理当前隔离上下文实际传入的字典消息。
Router、Planner、ToolExecutor、Evidence、三层答案校验和会话写回顺序保持原样。
集中式提示词
所有静态模型提示词和动态消息模板现在集中在 systemprompt.py。Router、Planner、
回答上下文、摘要器、质量 Validator、Grounding Validator 和回答修复模块只导入
各自需要的常量,业务模块不再维护独立提示词副本。systemprompt 小写名称继续
作为 SYSTEM_PROMPT 的兼容别名。
主回答提示包含 DamnatioX 的暴躁、嘴臭但心软角色口吻;Router、Planner、摘要和 Validator 使用各自的纯结构化提示,避免人格文字污染 JSON。主提示仍要求 JSON、 精确文本和用户指定语气优先,当前基础 System Prompt 本地估算约 247 tokens。
DamnatioX Agent TUI
首次创建源码开发环境:
py -3.14 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
pyproject.toml 声明运行依赖、damnatiox console script 和 dev 依赖组,
因此新环境安装后即可走格式化、静态检查、测试和构建入口。
运行入口:
.\.venv\Scripts\damnatiox.exe
TUI 是 AgentChain 的独立前端层。它负责全屏终端展示、底部 Composer、
输入队列和本地 Slash Commands;Router、Planner、工具执行、Evidence 和
Validator 仍由原链路负责。前端与链路之间只增加单向 StreamEvent,没有改变
现有工具、RAG 和校验顺序:
prompt-toolkit full-screen TUI
├─ 初始化:自适应立体 DAMNATIOX AGENT、工具、Skill 和会话信息
├─ 介绍滚出视口后:固定单宽 DX 立体标识、性格标签、模型与工作区
├─ 上部:会话、思考过程、工具活动、流式回答
├─ 底部:多行 Composer、命令补全和运行状态
└─ AgentChain.run_with_stream
├─ Router / Planner / Validator:同步 JSON
├─ ToolExecutor:结构化 ToolResult
└─ 回答模型:reasoning_content / content 流式增量
| 命令 | 功能 |
|---|---|
/help |
显示命令帮助 |
/status |
显示模型、工作区、Git 和会话状态 |
/tools |
显示全部已注册工具 |
/skills |
显示带编号的 Skill 列表和当前启用状态 |
/skills <编号或名称> |
启用或停用一个 Skill |
/skills off <名称> |
停用指定 Skill;另支持 clear 和 reload |
/diff |
查看当前 Git 工作区差异 |
/context |
查看当前上下文估算、各层占用和自动压缩阈值 |
/compact |
立即调用 LLM 生成结构化摘要并压缩当前会话 |
/sessions |
列出当前项目保存的会话 |
/resume [session-id] |
恢复指定会话;省略 ID 时恢复最近的其他会话 |
| `/model [v4pro | v4flash]` |
| `/effort [low | high |
/thinking on、/thinking off |
明确打开或关闭 TUI 思考流展示;模型 Thinking Mode 保持启用 |
/verbose |
切换完整链路事件显示 |
/clear |
清空终端显示并保留当前会话 |
/new |
保存当前会话并创建新会话 |
/quit、/exit |
结束程序 |
交互按键:
| 按键 | 功能 |
|---|---|
Enter |
发送输入 |
Alt+Enter |
在 Composer 内换行 |
PageUp、PageDown、鼠标滚轮 |
浏览当前 Session 的全部已保存和本次运行历史 |
Ctrl+Home、Ctrl+End |
跳到历史开头或回到最新输出 |
Ctrl+L |
清空当前终端对话显示,保留 Session |
Ctrl+C |
保存当前已完成轮次并立即结束程序 |
Ctrl+D |
输入栏为空且 Agent 空闲时结束程序 |
Agent 工作期间仍可继续输入,后续内容进入当前进程的输入队列。底部状态栏持续
显示当前阶段、已运行时间、排队数量、思考开关和流式状态。手动滚动到历史区域
后,流式刷新会保留阅读位置并显示 history paused;回到底部后继续自动追踪
最新增量。启动或 /resume 时,归档轮次与最近轮次都会恢复到 transcript;滚轮
每个事件直接移动 3 行可见起点,同时用 transcript 光标锁定阅读位置。
因此第一个滚轮事件就会改变视口,刷新也会保留当前历史位置。完成后的 Markdown、
用户输入和思考文本会按终端宽度转成可滚动行。
从 PowerShell 直接续聊:
# 恢复当前项目最近保存的会话
.\.venv\Scripts\python.exe .\main.py --continue
# 恢复指定 session ID
.\.venv\Scripts\python.exe .\main.py --resume session-xxxxxxxxxxxx
会话保存在项目的 .damnatiox/sessions/,模型偏好保存在
.damnatiox/settings.json,该目录已经加入 .gitignore。
持久化内容包括结构化摘要、最近轮次、归档轮次、上下文预算配置和最近一轮
API usage;载入会话时 System Prompt 始终使用当前代码版本。
当前上下文预算适用于 deepseek-v4-pro 和 deepseek-v4-flash:
| 预算 | 数值 | 用途 |
|---|---|---|
| 模型上下文窗口 | 1,000,000 tokens | DeepSeek V4 Pro/Flash 官方范围 |
| 官方最大输出 | 384,000 tokens | 输入与输出共同占用 1,000,000 token 上下文 |
| Prompt ceiling 目标 | 840,000 tokens | 为输出、工具结果和本轮动态内容预留空间;当前用于预算观测,并非请求发送前的硬截断器 |
| 自动压缩触发点 | 700,000 tokens | 达到后自动摘要旧轮次 |
| 自动压缩目标 | 500,000 tokens | 一次压缩尽量回落到该值 |
| 最近轮次安全上限 | 200 | 极短对话场景的额外轮数保护 |
| 结构化摘要字符上限 | 32,000 | 控制摘要自身大小 |
/context 和自动压缩共用 context/context_budget.py。本地估算采用无需加载
Tokenizer 的混合近似:ASCII 约按 4 字符/token,中文等非 ASCII 字符约按
1 字符/token,再加入每条消息的轻量开销。它用于压缩阈值,不再把 UTF-8
字节数直接当作 token。
context/token_usage.py 统一包装 OpenAI 兼容客户端,并读取服务端响应的
usage。/context 会把两个概念分开显示:
- Base context estimate:下一轮会重复发送的 System Prompt、结构化摘要和 最近会话记录的本地近似占用。
- Last turn exact usage:上一轮 Router、Planner、生成、Validator、压缩器等 全部模型请求的服务端精确累计值。
- Last request exact usage:上一轮最后一次模型请求自身的精确 prompt、 completion 和 total tokens。
- Prompt cache:服务端返回 cache hit/miss 时单独显示;没有该字段时不猜测。
此前仅输入“你好”时,System 792 来自 776 个 ASCII 字符加旧消息开销被按
逐字节计数,并不代表服务端 tokenizer 的真实结果。现在同一 System Prompt 的
本地估算约为 247 tokens;问候语与其他输入一样经过 LLM Router 和回答模型,
但简单 chat 不再额外调用质量评价器。/context 继续显示服务端精确 usage,
用于区分“当前上下文占用”和“一轮中多次模型调用的累计消耗”。
TUI 保持前后端分离:
- prompt-toolkit 使用 alternate screen、固定底部 Composer、滚动对话区、命令 补全、历史建议、鼠标滚动和差分重绘。
- 初始界面用
█与▓生成右下阴影的立体DAMNATIOX AGENT,并列出 模型、effort、工作区、工具、当前 Skill 和 Session。终端变窄时标题会拆分, 较窄时收敛为立体DX与普通品牌名。 - 当启动介绍被后续对话完全推出视口后,顶部自动切换为三行固定栏。
固定栏使用无阴影的加粗
DX,保持原有位置与高度,并在现有三行内显示 “它是一个非常暴躁的agent”与“测试版本,agent链路和边界判断并未完善”。 - Composer 初始高度为一行,显式换行或内容按终端宽度折行时自动增长,最高六行。
- Rich 负责
/context、/status、/diff等命令和最终 Markdown 的终端宽度 感知渲染;系统消息渲染会先为◆前缀预留宽度。终端列数变化时,before_render会重建 transcript;/help、/status、/tools、/skills、/diff、/context和/sessions会以新列宽重新生成 Rich 表格,而不是把旧边框 强制截断或二次换行。最终 Markdown 表格同样按新列宽重排。 reasoning_content和content分别产生thinking_delta与answer_delta; 工具调用分片在chain/streaming.py中重建后继续进入原 ToolExecutor。- 思考标题使用紫色粗体,思考正文使用紫灰色斜体和左侧竖线;最终回答使用终端
高对比浅色前景。链路完成后,最终
TurnOutcome.answer会替换临时思考区, 并以单宽└ Worked for显示总时间和实际输出流时间,避免 emoji 字形回退导致的字符重叠。 /thinking off只过滤 TUI 的thinking_*事件;流重建仍保存reasoning_content,工具调用后的下一次请求可按 DeepSeek 协议完整回传。 Router、Planner、Validator 等结构化调用始终保持非流式。/model可切换deepseek-v4-pro与deepseek-v4-flash;/effort支持官方low/high/max。当前官方映射中 Pro 的low实际采用high,/status和选择表会同时显示 requested/effective 值。/effort作用于启用 Thinking 的回答、工具循环收敛和回答修复请求;Router、 Planner、结构化质量判断、Grounding Validator 与上下文压缩保持 Thinking disabled, 以减少结构化控制阶段的延迟和输出波动。- 详细 Router/Validator 事件继续由
/verbose控制。 main.py只负责启动,依赖初始化位于tui/bootstrap.py。- OpenAI 兼容客户端不设置固定请求时限,SDK 对瞬时连接、限流和服务端状态错误 最多自动重试 3 次;Agent 链路由模型步骤、工具错误、重规划和修复轮次收敛。
- 启动阶段只读取 RAG 索引;SentenceTransformer 和 BGE 模型推迟到第一次 知识库检索时导入和加载,已缓存模型优先使用本地文件。
- 非 TTY、管道和重定向输入继续使用原有线性 Rich 界面。
设计参考:
- AI Agent Book:Coding Agent 与代码生成
- Anthropic:Building effective agents
- DeepSeek Chat Completion usage
- DeepSeek Models & Pricing
- DeepSeek Thinking Mode 与流式 reasoning_content
- DeepSeek 请求等待和 keep-alive
- Claude Code CLI reference
- Codex CLI slash commands
- Codex Skills
- Agent Skills specification
- Claude Code Skills
- Claude Code sandboxing
- Hermes Agent TUI
- prompt-toolkit full-screen applications
- OpenClaw TUI
- OpenClaw session compaction
- OpenClaw context breakdown
- DeepSeek V4 models and context length
RAG 执行链路
rag/rag_execution.py 负责一条独立的 RAG 子链路:
- 校验并规范化查询。
- 使用
规范化 query + top_k生成缓存键。 - 查询当前用户轮次的缓存。
- 缓存未命中时调用
VectorStore.query()。 - 将结果整理成统一结构。
- 将异常转换成结构化错误结果。
ToolExecutor 通过适配器调用该子链路,再把结果转换成统一 ToolResult 和
当前轮 Evidence。底层向量检索实现保持独立。
单轮缓存生命周期
- 每次读取一个新的用户 prompt 后创建一个
TurnRagContext。 rag路线的覆盖检索和本轮后续所有 RAG 工具调用共享该对象。- 同一轮内,相同的规范化 query 和
top_k直接复用缓存。 - 用户输入下一个 prompt 时创建新对象,上一轮缓存随之失效。
- 每轮最多执行 3 次实际向量检索;缓存命中不占用新的检索次数。
RAG 返回结构
成功示例:
{
"ok": true,
"query": "示例查询",
"cached": false,
"hits": [
{
"evidence_id": "example.md:12",
"source": "example.md",
"chunk_id": 12,
"score": 0.836,
"content": "检索到的文本"
}
],
"meta": {
"top_k": 3,
"duration_ms": 28
}
}
失败示例:
{
"ok": false,
"query": "示例查询",
"cached": false,
"hits": [],
"error": {
"code": "RAG_QUERY_FAILED",
"message": "错误信息"
},
"meta": {
"top_k": 3,
"duration_ms": 1
}
}
底层 evidence_id 用于描述原始片段;进入 Evidence Registry 后会重新分配
当前轮引用编号 E1、E2。引用编号只在当前 turn_id 内有效。
工具调用
| 工具名 | 功能 |
|---|---|
calculator |
计算受限的基础算术表达式 |
get_text_length |
计算字符串长度 |
search_knowledge_base |
检索本地知识库 |
search_web |
通过 DuckDuckGo HTML 搜索网页,返回去重后的标题、摘要和 URL |
query_sqlite |
通过只读连接查询项目目录内的 SQLite 数据库 |
read_file |
按行读取项目目录内的 UTF-8 文本文件 |
browse_web_page |
读取 http/https 静态页面的标题和可见正文 |
execute_python |
在临时目录中执行经过 AST 校验、仅暴露安全 builtins 与 math 的确定性 Python 代码 |
glob_files |
按 Glob 模式浏览项目文件结构 |
grep_files |
在项目文本文件中搜索字符串或正则表达式并返回行号 |
write_file |
原子创建文件;覆盖已有文件时要求显式 overwrite=true |
replace_in_file |
使用唯一 old_text 锚点执行确定性局部编辑 |
run_command |
按 coding policy 白名单运行测试、编译、Ruff、只读 Git 或项目 Python 脚本 |
run_powershell |
执行固定查询 cmdlet 和参数组成的结构化只读 PowerShell pipeline |
工具参数先经过 validation/tool_validation.py:
- 解析 JSON。
- 拒绝重复字段和非标准数值。
- 校验必填字段、额外字段、类型、枚举和长度等约束。
- 参数错误以对应工具结果返回给模型。
每个模型产生的 function tool_call 都对应一条 role: "tool" 消息。消息内容
统一包含工具名、状态、数据、Evidence、错误和元数据。
calculator 使用 Python AST 解析表达式,只执行声明支持的基础算术运算,
并限制表达式长度、节点数量、指数和结果范围。
新工具保持同一条执行路径:
一个 assistant 消息中的 function calls
→ AgentChain 按 capability 切分连续独立段与副作用屏障
→ ToolExecutor:Schema 校验 / 参数指纹 / cache / single-flight
→ 独立段全部 parallel_safe:最多 4 个 worker 并发运行
RAG 等独立但非线程安全的段:完整顺序运行并聚合失败
Write / Edit / Command / unknown:逐项执行,失败后停止后续副作用
→ 主线程:按原 tool_call 顺序提交 ToolResult
→ Current-turn Evidence Registry
ToolFunctionResult 只负责让普通工具声明结构化数据、来源和引用要求;
Evidence ID 仍由 ToolExecutor 按当前 turn_id 分配。
并发策略定义在 tool/tool_capabilities.py。调度维度与失败维度彼此分离:
parallel_safe 决定线程池,failure_barrier 决定失败后是否阻断后续副作用,
observes_workspace 决定指纹是否包含当前 revision。未知工具默认
effect="exclusive"、parallel_safe=False、cacheable=False;新增工具只有在
实现本身不写共享状态、参数相互独立且结果可重复读取时,才显式开启并发。当前
execute_python 运行于独立受限进程,因此按纯计算工具处理;run_command 即使
执行只读子命令也保持独占,因为同一入口还承载测试、格式化和项目脚本,同时它
会观察 workspace revision,以便编辑后用相同命令重新测试。
首版工具边界:
- Search、Database、File、Browser 和 Coding 工具实现使用 Python 标准库; TUI 将 prompt-toolkit 和 Rich 作为显式运行依赖。
- Search 使用 DuckDuckGo HTML,无额外 Python 依赖;网络错误进入现有工具失败策略。
- SQLite 使用标准库
sqlite3和只读 URI,最多返回 200 行。 - File 只读取项目目录内文件,单次最多 500 行、2,000,000 字节。
- Browser 读取静态 HTML、JSON 或纯文本,过滤脚本和样式,正文最多 20,000 字符。
- Code 使用
sys.executable -I -c在临时目录执行,超时最多 10 秒, stdout 与 stderr 分别执行首尾保留的长度裁剪。 - Glob 和 Grep 默认跳过
.git、.venv、缓存、node_modules和向量索引目录。 - Write 采用同目录临时文件加
os.replace原子落盘;Python、JSON、TOML 写入后 立即返回语法检查结果。 - Edit 要求
old_text在目标文件中恰好出现一次,并返回统一 Diff 与新旧哈希。 - Command 使用参数数组和
shell=False,工作目录限制在项目内,超时最多 60 秒; 只开放 Pythonunittest/pytest/ruff/compileall、项目内.py脚本、直接ruff/pytest和只读 Git 子命令。 - PowerShell 只接受
pipeline=[{"cmdlet": ..., "parameters": ...}],开放Get-Location、Get-ChildItem、Get-Content、Select-String、Select-Object、Sort-Object、Measure-Object、Test-Path、Resolve-Path、Get-FileHash和ConvertTo-Json。路径参数统一解析到 项目目录,文本参数始终作为单引号 literal。 - 当前轮工作区维护轻量
workspace_revision;文件写入或编辑成功后,允许 Read、 Glob、Grep、Command 和 PowerShell 使用相同参数复查新状态。可能写入工作区的 测试、格式化、编译和项目脚本即使非零退出或超时也会推进 revision,因为失败 前可能已经产生局部变更。 execute_python拒绝 import、文件入口、私有/栈帧反射和危险 builtins,只暴露 受限内建函数及math,并限制静态序列重复、range数量和 256 MiB 进程内存; 它与项目脚本使用不同执行策略。
Coding 进程策略边界
tool/sandbox.py 是应用层 policy sandbox:
- 拒绝
cmd、PowerShell、Bash、WSL 等通用 shell host 进入run_command。 - 拒绝 Python
-c、任意模块、Git 写操作、Git-C、外部路径和未知程序。 - 裸 Python 固定到当前解释器,Ruff/Pytest 固定到项目
.venv,Git 与 PowerShell 拒绝解析到工作区内的同名程序;短选项附加路径也逐项校验。 - 只使用校验后的 argv,固定
shell=False和stdin=DEVNULL。 - File/Edit/PowerShell 路径会保护
.git、.venv、.damnatiox、config.py、.env*和常见私钥/证书文件;Glob/Grep 同样跳过这些内容。 - 子进程只继承 PATH、系统目录、临时目录、语言和编码等必要环境;API Key、 代理和用户级 Python 包配置不进入子进程。
- Windows 子进程先挂入带
KILL_ON_JOB_CLOSE的 Job Object 再恢复运行; stdout/stderr 由独立线程持续排空,仅在内存中保留有界首尾内容,超时或父进程 退出都会清理后台后代。POSIX 使用独立进程组执行同类清理。 - 超时映射为
retryable_error,程序缺失映射为fatal_error,非零退出保留为 带COMMAND_NONZERO_EXIT原因的partial,继续进入现有 Failure Policy。 - Ruff 在用户参数前固定注入
--isolated --no-cache;只读check另加--no-fix。Pytest 同样在用户参数前注入空配置与no:cacheprovider,并关闭 外部插件自动加载,避免项目配置隐式改变执行行为。 - Ruff/Pytest 拒绝
--选项终止符;路径检查同时覆盖 Windows 盘符相对路径、 当前盘根路径、UNC、用户目录和父目录穿越,固定强化参数不会退化成位置参数。
该层用于缩小模型可表达的命令面,并不等同于 Windows AppContainer、受限 Token
或虚拟机。白名单内的项目测试和项目脚本仍是项目代码;若后续需要硬隔离,再把
同一 ToolExecutor 入口连接到独立容器或 Windows 受限进程服务,Router 和主链路
保持不变。
Coding Agent 最小循环
flowchart LR
A["理解编码任务"] --> B["同批 Glob / Grep / Read 并行定位"]
B --> C["补读存在依赖的上下文"]
C --> PS["可选:结构化 PowerShell 只读查询"]
PS --> D["Write 或唯一文本 Edit"]
D --> E["即时 Syntax Feedback"]
E -->|"通过"| F["受约束 Command 运行 Ruff / Compile / Tests"]
E -->|"有问题"| C
F -->|"失败"| B
F -->|"通过"| G["基于 ToolResult 收敛回答"]
该循环没有引入新的编排器,而是复用当前 Planner → Tool Batch Scheduler → ToolExecutor → ToolResult → Evidence → Validator 路径。简单任务由模型按需裁剪步骤,复杂任务仍受原有
步数、重试和重新规划预算约束;写入、编辑和验证命令仍按依赖顺序执行。
Skills
Skills 是对现有链路的工作流说明层,不是另一套 Agent Loop。SkillManager
扫描以下位置,后面的项目级定义覆盖同名用户级定义:
~/.codex/skills/<name>/SKILL.md
~/.agents/skills/<name>/SKILL.md
<project>/.claude/skills/<name>/SKILL.md
<project>/.agents/skills/<name>/SKILL.md
SKILL.md 使用 YAML frontmatter:
---
name: debug
description: 系统化复现、定位并修复代码缺陷。
allowed-tools: glob_files, grep_files, read_file, run_command
user-invocable: true
disable-model-invocation: false
---
# Debug workflow
1. 先复现。
2. 再定位和最小修改。
3. 最后执行针对性验证。
加载规则:
- 只扫描每个搜索根目录的直接子目录,要求
name与目录名一致。 - 使用
yaml.safe_load,限制文件、frontmatter、正文、名称、说明和工具数量。 - 无效 Skill 单独记录为 load issue,不影响其他有效项。
/skills只展示元数据;启用后才把正文放进当前轮 system context。Router 接收精简元数据,复杂任务 Planner 接收已选工作流正文;Router 服务异常时,allowed-tools也会作为确定性 fallback 的工具提示。- 最多同时启用 5 个 Skill;
allowed-tools只保留 ToolExecutor 已注册名称, 它作为工作流提示,不绕过 Router、Planner、Schema 校验或进程 policy。 - Skill 中出现的命令在加载阶段只是文本;真实操作仍要经过 function call 和 统一 ToolExecutor。
当前随项目提供 debug、code-review 和 python-quality 三个示例。选中状态
在当前 TUI 进程中持续生效,直到再次切换、执行 /skills clear 或结束进程;
Skill 正文不写入 TurnRecord 和会话摘要。
最终回答校验
最终回答进入会话历史前依次执行:
validation/validation_pipeline.py检查空内容、长度、精确输出和 JSON 格式。- 简单
chat在第 1 层通过后收敛;复杂chat、RAG、工具与 Research 进入validation/response_validation.py的通用质量检查。 - 带当前轮 Evidence 的路线由 Grounding Validator 严格返回 claim、支撑状态
和
evidence_ids;无 Evidence 的普通 chat 使用本地引用检查。 - 引用编号在本地检查,未知引用和需要引用却缺失引用都会触发修复。
- 缺少证据时,在重新规划预算内补充 RAG;预算结束后只输出现有证据可支持 的内容并明确说明证据缺口。
所有校验和修复请求均关闭工具调用。
冗余检查后继续保留三层职责:
- 确定性校验处理精确文本、枚举和 JSON。
- 通用质量 Validator 处理要求覆盖和内部一致性。
- Grounding Validator 处理当前轮事实、来源和引用。
三层职责仍然保留,但按任务复杂度启用。精确输出(例如只返回 1、2 或 3)
始终由确定性层检查并在不符合时重新生成;评价器循环只用于有明确质量收益的复杂
回答,事实与引用评价只消费当前轮 Evidence。
编码工具已经成功创建或编辑文件,而独立回答 Validator 恰好用完本轮预算时,
链路会依据真实 write_file / replace_in_file 结果生成确定性完成说明:
- 只采用状态为
success/partial且语法检查未失败的写入结果。 - 完成说明只包含真实路径、创建/更新/编辑状态和语法检查结果。
- 通过
quality_validator/local_fallback事件保留 Validator 结束原因。 - 文件操作成功状态与最终说明校验状态分别处理,避免把已完成写入展示成链路失败。
文件结构
main.py # 源码运行兼容入口
systemprompt.py # 全部静态模型提示词和动态消息模板
pyproject.toml # 包元数据、依赖、damnatiox 入口和 Ruff 配置
requirements.txt # 当前 Python 3.14 开发环境兼容锁
.github/workflows/ # Push/PR CI 与 GitHub Release → PyPI
.agents/skills/ # 项目级 SKILL.md 工作流定义
damnatiox_agent/
├─ cli.py # 安装后的 console script 入口
├─ paths.py # 工作区、用户状态和包内资源路径
└─ resources/ # Wheel 随附的默认 RAG 文档与向量索引
chain/
├─ agent_chain.py # 完整单轮链路编排
├─ chain_models.py # TurnState、ToolResult、PlanStep 等共享模型
├─ model_profile.py # DeepSeek 模型目录、selector 和 effort 映射
├─ streaming.py # reasoning、回答增量和工具调用流重建
├─ router.py # 四分类 Router 和 RAG Coverage Gate
├─ planner.py # 结构化复杂任务 Planner
├─ execution_policy.py # Loop Guard 和 Tool Failure Policy
└─ evidence_registry.py # 当前轮 Evidence 登记、去重、排序和裁剪
context/
├─ app_config.py # ~/.damnatiox/config.json 凭据读写
├─ context_state.py # SessionContext、SessionSummary、TurnRecord
├─ context_budget.py # 模型窗口预算估算和 /context 快照
├─ token_usage.py # API usage 精确采集和单轮聚合
├─ context_builder.py # 输入上下文、Router 上下文和消息转换
├─ context_compression.py # LLM 结构化会话摘要压缩
├─ runtime_settings.py # 独立于会话的模型偏好原子持久化
├─ session_store.py # 项目本地会话保存、列表和恢复
├─ environment_context.py # 动态目录、Git 分支、提交与变更状态
└─ answer_context.py # 回答上下文、工作区状态与隔离校验上下文
rag/
├─ document_loader.py # 文档加载
├─ chunk.py # 文本分块
├─ embedding.py # 向量化
├─ retrieve.py # 相似度检索
├─ vector_store.py # VectorStore
├─ rag_pipeline.py # 索引构建与查询入口
└─ rag_execution.py # 单轮 RAG 缓存、执行和结构化结果
skill/
├─ models.py # Skill 定义、来源、加载问题和异常
└─ manager.py # 多目录发现、选择、重载和渐进上下文披露
tool/
├─ tools.py # 全部工具 JSON Schema
├─ tools_function.py # 普通工具函数映射
├─ tool_output.py # 普通工具的结构化数据和来源协议
├─ local_tools.py # File、SQLite 和 Python Code
├─ coding_tools.py # Glob、Grep、Write、Edit 和 Command
├─ sandbox.py # Coding command 白名单、环境和工作区策略
├─ powershell_tools.py # 结构化只读 PowerShell pipeline
├─ process_runner.py # 有界输出、超时和子进程树清理
├─ python_sandbox.py # execute_python 的 AST 与 builtins 策略
├─ web_tools.py # Search 和静态 Browser
├─ tool_capabilities.py # 并发、缓存和工作区副作用的保守策略
└─ tool_executor.py # 批量调度、统一执行、顺序提交和结果适配
tui/
├─ app.py # DamnatioX 交互循环和 Slash Commands
├─ bootstrap.py # API、RAG、Session、ToolExecutor 初始化
├─ credential_setup.py # 首次启动 TUI 密码输入和 API Key 解析
├─ fullscreen.py # 全屏 Transcript、Composer、状态栏和流式事件
├─ welcome.py # 自适应 DAMNATIOX AGENT 启动画面
├─ markdown_rendering.py # 终端宽度感知 Markdown 和表格布局
└─ rendering.py # Banner、状态、工具卡片、回答与 Diff 渲染
validation/
├─ tool_validation.py # 工具参数解析和校验
├─ tool_completion.py # 编码工具成功后的本地完成说明回退
├─ response_validation.py # 通用回答质量校验与有限修复
└─ validation_pipeline.py # 确定性格式、事实和引用校验
data/ # 知识库源文件
vector_store/ # 持久化向量索引
.damnatiox/sessions/ # 本地会话 JSON(Git 忽略)
.damnatiox/settings.json # 模型与 effort 偏好(Git 忽略)
~/.damnatiox/config.json # 用户级 DeepSeek API Key(仓库外)
主要配置
| 参数 | 默认值 | 说明 |
|---|---|---|
ChainConfig.model |
deepseek-v4-pro |
/model 可切换为 deepseek-v4-flash |
ChainConfig.reasoning_effort |
high |
/effort 可选 low/high/max |
ChainConfig.max_model_steps |
30 | 单轮回答/工具循环的模型步骤上限 |
ChainConfig.total_timeout_seconds |
None |
默认关闭整轮 wall-clock 时限 |
ChainConfig.api_timeout_seconds |
None |
默认关闭单次模型 API 固定时限 |
ChainConfig.compression_timeout_seconds |
None |
默认关闭摘要 API 固定时限 |
ChainConfig.max_retryable_errors |
3 | 可重试工具错误预算 |
ChainConfig.max_replans |
5 | 重新规划和补充证据预算 |
ChainConfig.max_answer_repairs |
3 | 格式与事实回答修复预算 |
ChainConfig.max_tool_calls_per_batch |
16 | 单个模型响应实际执行的工具调用上限;其余调用生成 skipped 结果 |
ChainConfig.min_rag_score |
0.5 | RAG 覆盖和 Evidence 过滤阈值 |
DEFAULT_TOP_K |
3 | 每次 RAG 返回片段数 |
MAX_RAG_RETRIEVALS_PER_TURN |
3 | 单轮实际 RAG 检索上限 |
ToolExecutor.max_parallel_tools |
4 | 单个 parallel_safe 独立段的最大 worker 数 |
模型请求和整轮链路改为“轮次优先”,对应 Coding Agent 中常见的全局最大迭代、 每类错误独立计数和失败后继续收敛。Python 子进程、项目命令、静态网页读取等 本地工具仍保留各自的资源时限,防止卡住的外部进程占用执行器。
当前自动化验证
.\.venv\Scripts\python.exe -m unittest discover -s tests -v
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m ruff format --check .
.\.venv\Scripts\python.exe -m ruff check .
.\.venv\Scripts\python.exe -m build
.\.venv\Scripts\python.exe -m twine check .\dist\*
打包、GitHub Actions 与 PyPI 发布
.github/workflows/ci.yml 在 main push 和 Pull Request 时执行 Ruff、编译、
全量测试、wheel/sdist 构建与 Twine 元数据检查。.github/workflows/publish.yml
只在 GitHub Release 发布时运行,先构建并传递唯一的 distribution artifact,
再使用 OIDC 和 PyPI Trusted Publishing 上传,不读取 PyPI API Token。
PyPI 账号中需要一次性创建 pending Trusted Publisher:
| 字段 | 值 |
|---|---|
| PyPI project name | damnatiox-agent |
| GitHub owner | jame100101 |
| Repository | agent_learning |
| Workflow | publish.yml |
| Environment | pypi |
同时在 GitHub 仓库创建名为 pypi 的 Environment,建议为该 Environment 配置
发布审批。之后每次版本更新沿用固定流程:
- 修改
damnatiox_agent/__init__.py中的__version__。 - 执行 Ruff、全量测试、
python -m build和python -m twine check dist/*。 - 提交并推送
main,等待CIworkflow 全部完成。 - 创建与版本一致的 Git tag 和 GitHub Release,例如
v0.1.0。 Publish to PyPIworkflow 经pypiEnvironment 后构建并发布。- 用
pipx upgrade damnatiox-agent验证已发布版本和damnatiox --version。
流程依据 PyPA 的 GitHub Actions + Trusted Publishing 指南。
当前回归集包含 234 个测试,另含 75 组参数化子测试,覆盖:
- chat、rag、tools 三条完整模拟链路;
- 高相关和低置信度 RAG Coverage Gate;
- Router、Planner、Loop Guard 和失败预算;
- 普通工具、RAG、参数错误、重复保护、同轮 cache、批内 single-flight 和统一 ToolResult;
- Search/Browser 解析、SQLite 只读查询、文件范围和 Python 执行;
- Glob/Grep 定位、原子写入、唯一文本编辑、语法反馈、命令 policy、结构化 PowerShell、执行期计划白名单、可信可执行入口、Python AST/内存边界、失败映射、 工作区 revision、有界输出、进程超时和后台子进程清理;
- Skill 安全解析、目录优先级、选择预算、渐进披露、工具交集、TUI 选择、 重载后补全刷新和当前轮上下文注入;
- DamnatioX 本地命令、上下文查看、会话保存/恢复和无副作用入口导入;
- 用户级 API Key 缺省、环境变量优先级、首次 TUI 输入、原子持久化、损坏配置 恢复、凭据脱敏,以及 wheel 资源和 console script 启动;
/model、/effort直接切换、全屏选择浮层、requested/effective 映射和.damnatiox/settings.json原子持久化;- 当前轮 Evidence 去重、过滤、预算裁剪、最终编辑/验证保留和历史隔离;
- 精确输出、枚举、JSON、引用编号和逐 claim 支撑校验;
- SessionContext 和结构化摘要压缩的成功及失败事务。
- 中英文 token 本地估算、服务端精确 usage 聚合、问候语 LLM 路由、简单 chat 自适应收敛和无 wall-clock 默认预算。
- 提示词集中存放、动态模板边界、角色标记和基础 prompt token 预算。
- reasoning/content 增量、流式工具调用重建、流式 usage、全屏布局、思考开关、 完整 Session 历史恢复、全范围滚轮、Ctrl+C 退出、自适应 Composer 和 Markdown 表格重排、窗口缩放后的 Rich 重渲染、直接视口滚动、自适应启动页和 无阴影 DX 固定顶栏与测试版本提示。
- 独立只读工具真实并发、最大 worker 数、反序完成后的顺序提交、RAG 串行失败 隔离、副作用失败屏障、批次调用上限、single-flight 失败预算去重、写后 cache 失效、改后同命令复测、Evidence ID 稳定和 workspace snapshot revision 缓存。
RAG 测试与验收标准
RAG 目前没有统一的全球认证标准或固定及格分数。项目采用“固定测试集、分层 指标、人工抽检、版本回归和线上监控”的工程评估方法。RAGAS、LangSmith、 TruLens、DeepEval 和 ARES 属于常用评估框架或方法;TREC RAG Track 提供研究 级数据集与评测流程,但不作为本项目的强制产品认证标准。
评估时必须分别测量 Router、Retriever、回答生成、工具调用、Validator 和系统 性能,不能只用一个总分代表完整链路。
1. 测试集结构
每条测试数据建议包含以下字段:
{
"id": "rag_001",
"messages": [
{
"role": "user",
"content": "根据知识库解释 Git"
}
],
"expected_route": "rag",
"expected_tools": [
"search_knowledge_base"
],
"expected_sources": [
"git.md"
],
"required_facts": [
"Git 是分布式版本控制系统"
],
"forbidden_claims": [],
"reference_answer": "Git 是一种分布式版本控制系统。",
"should_answer": true
}
测试集由以下三种数据组成:
- 人工编写并核对的高质量样例。
- 脱敏后的真实用户问题和失败案例。
- 从知识库生成并经人工抽检的合成样例。
每次发现新的线上问题,都应将其整理为固定回归样例。测试数据、知识库版本、
模型版本、Embedding 版本、Prompt 版本、分块参数和 top_k 必须一起记录,
保证不同实验结果可复现、可比较。
第一版建议至少准备 100 条用例:
| 类型 | 建议数量 |
|---|---|
| 普通常识,应直接回答 | 15 |
| 明确要求读取知识库 | 20 |
| 知识库中不存在答案 | 10 |
| 包含相似但错误的干扰片段 | 10 |
| 多轮追问 | 10 |
| 跨轮证据隔离 | 10 |
| 普通工具调用 | 10 |
| RAG 与其他工具组合 | 10 |
| 全库统计问题 | 5 |
2. Router 评估
Router 测试集必须覆盖四分类、复杂度、建议工具和结构化解析失败回退:
什么是 Git? → chat
根据知识库解释 Git → rag
计算 2 + 3 → tools
比较多个来源并形成研究报告 → research
Git 在知识库里吗? → rag,再由 Coverage Gate 判断 covered
Router 记录以下指标:
| 指标 | 含义 |
|---|---|
| Accuracy | 全部路由结果的正确比例 |
| Precision | 被判为某类的问题中实际属于该类的比例 |
| Recall | 实际属于某类的问题中被正确识别的比例 |
| Macro-F1 | 对每个类别分别计算 F1 后取平均,避免大类别掩盖小类别 |
| Confusion Matrix | 观察 chat、rag、tools 和 research 的具体混淆方向 |
| Coverage Accuracy | rag 路线中 covered、empty、low_confidence 和 error 的判断准确率 |
rag Recall 和 Coverage Accuracy 是关键指标。前者判断是否应该尝试知识库,
后者判断真实检索结果是否足以支撑回答,两者应分别评估。
3. Retriever 评估
Retriever 只评估“正确文档或片段是否被检索出来”,不评价最终回答措辞。
| 指标 | 定义 |
|---|---|
| Hit@K | 前 K 个结果中是否至少出现一个正确片段 |
| Recall@K | 前 K 个结果召回的相关片段数除以全部相关片段数 |
| Precision@K | 前 K 个结果中的相关片段数除以 K |
| MRR | 第一个正确结果排名倒数的平均值 |
| nDCG@K | 同时考虑结果相关等级和排序位置 |
Retriever 测试必须保存预期的 source 或 evidence_id,不能仅凭最终回答是否
看起来正确来推断检索质量。测试时至少覆盖:
- 同义改写、缩写、大小写和中英文混合。
- 拼写错误和额外空白。
- 相似主题文档造成的干扰。
- 一个答案分布在多个片段中的多跳问题。
- 空知识库、空结果和低相关度结果。
- 不同 chunk 大小、overlap、Embedding、检索算法和
top_k的对照实验。
4. 回答生成评估
生成层至少分成四个维度:
| 指标 | 比较对象 | 检查内容 |
|---|---|---|
| Answer Correctness | 回答与参考答案 | 关键事实是否正确 |
| Answer Relevance | 回答与用户问题 | 是否直接回应问题 |
| Faithfulness / Groundedness | 回答与本轮证据 | 回答中的事实是否有证据支持 |
| Completeness | 回答与必需事实集合 | 是否覆盖所有关键要求 |
如果回答支持来源引用,还应增加:
| 指标 | 含义 |
|---|---|
| Citation Precision | 已给出的引用中真正支持对应结论的比例 |
| Citation Recall | 应当引用的关键结论中实际附带有效引用的比例 |
| Citation Validity | 回答中引用的 evidence_id 是否真实存在于本轮 Registry |
生成质量可以使用人工评分、确定性规则和 LLM Judge 组合测量。LLM Judge 的模型、 Prompt 和输出 Schema 必须固定,并使用人工标注样本定期校准。不能把 Judge 的 一次输出直接当作绝对真值。
5. 工具与 Agent 评估
搜索、数据库、文件、浏览器、代码执行和 RAG 工具统一记录:
| 指标 | 含义 |
|---|---|
| Tool Selection Accuracy | 是否选择了正确工具 |
| Argument Validation Pass Rate | 工具参数是否符合 Schema |
| Tool Call Precision | 实际工具调用中必要调用的比例 |
| Tool Call Recall | 所有必要工具调用中实际执行的比例 |
| Tool Result Utilization | 最终回答是否正确使用工具结果 |
| Redundant Call Rate | 相同参数和结果的非必要重复调用比例 |
| Agent Goal Success Rate | 整体任务是否完成 |
工具测试还必须包含参数缺失、额外字段、错误类型、超长输入、工具异常、超时、 空结果、重复调用和多个工具组合调用。
6. Validator 评估
Validator 本身作为独立模型组件进行评估。测试集中应同时包含:
- 完全正确的回答。
- 明显错误的回答。
- 部分正确但遗漏关键事实的回答。
- 事实正确但缺少本轮证据支持的回答。
- 格式错误但语义正确的回答。
- 已经正确、不应继续改写的回答。
记录以下指标:
| 指标 | 含义 |
|---|---|
| False Rejection Rate | 正确回答被判为失败的比例 |
| False Acceptance Rate | 错误回答被放行的比例 |
| Repair Success Rate | 修复后真正通过人工标准的比例 |
| Over-repair Rate | 原回答正确但被修坏的比例 |
| Average Repair Count | 每个回答平均重新生成次数 |
每次校验都应记录 valid、错误代码、错误原因、retry_instruction、修复前后
回答和修复次数,以区分真实修复和 Validator 波动。跨轮对话中,Validator 只能
把本轮 RAG 与工具结果当作当前事实证据;历史回答和历史工具结果只能作为会话
背景,不能作为本轮证据。
7. 确定性格式校验
枚举、固定字符串、JSON、字段类型、长度、数值范围等要求优先使用确定性代码, 语义一致性再交给 LLM Validator。
例如 Router 只接受:
candidate.strip() in {"1", "2", "3"}
推荐校验顺序:
确定性格式检查
↓
证据与事实校验
↓
失败后有限修复
↓
再次执行确定性格式检查
↓
最终输出
8. 系统性能与稳定性
每次评估同时记录:
- p50、p95 和最大响应延迟。
- 每轮输入、输出和总 Token 数量。
- 单次请求及完整任务成本。
- RAG 与其他工具的调用次数。
- 缓存命中率和重复调用率。
- API、解析、工具执行和 Validator 错误率。
- 超时、最大步数终止和修复次数分布。
质量指标提高但延迟、成本或错误率显著恶化时,不能直接认定新版本整体优于 基线版本。
9. 项目初始验收门槛
以下数值是本项目的第一版工程门槛,不属于统一行业标准。积累真实问题和人工 标注后,应根据业务风险调整:
| 指标 | 初始门槛 |
|---|---|
| Router Macro-F1 | >= 0.90 |
rag Recall |
>= 0.95 |
| RAG Coverage Accuracy | >= 0.90 |
| Retrieval Hit@3 | >= 0.90 |
| Retrieval Recall@5 | >= 0.90 |
| Faithfulness | >= 0.95 |
| Answer Correctness | >= 0.90 |
| 工具参数 Schema 通过率 | = 1.00 |
| 预期工具调用成功率 | >= 0.95 |
| 跨轮证据污染失败数 | = 0 |
| Validator False Acceptance Rate | <= 0.02 |
| Validator False Rejection Rate | <= 0.05 |
除绝对门槛外,每次改动还必须与上一稳定版本对比。核心指标下降、已有固定用例 失败或跨轮证据污染测试失败时,本次改动不进入稳定版本。
10. 当前项目固定回归样例
至少保留以下用例:
什么是 Markdown? → chat
什么是 Git? → chat
根据知识库解释 Git → rag、covered,并命中 Git 来源
Git 不是在知识库里吗? → rag,并执行本轮覆盖检索
计算 2 + 3 → tools,并调用 calculator
比较多个来源并形成报告 → research,并生成 PlanStep
知识库一共有多少字? → 全库统计工具,不使用 Top-K 推断
先询问 Markdown,再询问 Git → Markdown 证据不污染 Git 回答
检索 example2.md 后询问 Git → 重新检索 Git,不复用历史证据
只返回数字 1、2、3 中的一个 → 确定性枚举校验通过
RAG 检索为空 → 明确报告证据为空,不编造来源
工具参数错误 → 返回结构化参数错误并保持消息协议完整
11. 标准评估流程
冻结测试集、知识库和模型配置
↓
运行 Router 单项评估
↓
运行 Retriever 单项评估
↓
运行生成、引用和 Validator 评估
↓
运行工具及多轮端到端评估
↓
与上一稳定版本比较
↓
人工抽检失败样例
↓
输出指标、失败分类和实验配置
调优时一次只改变一个主要变量,例如 chunk 大小、Embedding、top_k、Router
Prompt 或生成模型。多个变量同时改变会增加归因难度。
12. 参考评估体系
- RAGAS Metrics
- RAGAS Testset Generation
- LangSmith RAG Evaluation
- ARES: An Automated Evaluation Framework for RAG Systems
- TREC RAG Track
后续任务
第二至第四阶段已经完成以下基础能力:
TurnState、统一ToolResult、当前轮EvidenceRegistry;- 四分类 Router、RAG Coverage Gate、Planner、Loop Guard;
- 工具失败、空结果、重复调用、重试和重新规划预算;
- Answer Context、确定性格式、事实与引用校验;
- 短期上下文、会话
TurnRecord和 LLM 结构化摘要。 - Search、SQLite、File、静态 Browser 和 Python Code 首版工具。
- Glob、Grep、Write、Edit、受约束 Command 和结构化 PowerShell 组成的 Coding Agent 工具箱。
- 项目/用户 Skills 发现、安全解析、显式选择和按需上下文披露。
- DamnatioX Agent 全屏 TUI、真实流式回答、可选思考展示、到底自动跟随、 模型/effort 选择和动态工作区状态。
- 同响应独立只读工具的受控并发、顺序提交、缓存、single-flight 和批次级 失败聚合。
已接入工具与下一步扩展
以下工具已进入统一执行入口:
| 工具 | 当前返回内容 |
|---|---|
| Search | 标题、摘要、URL、排序和 Evidence |
| SQLite | 字段、数据行、截断状态、查询耗时和 Evidence |
| File | 规范化项目路径、文本、行号和 Evidence |
| Browser | 静态页面正文、内容类型、URL 和 Evidence |
| Code | 退出码、stdout、stderr、耗时和 Evidence |
| Glob / Grep | 项目相对路径、真实行号、匹配数量、截断状态和 Evidence |
| Write / Edit | 原子写入结果、Diff、SHA-256 和即时语法反馈 |
| Command | policy 校验后的 argv、cwd、退出码、stdout/stderr、耗时、影响类型和截断状态 |
| PowerShell | 只读 pipeline、规范化参数、退出码、stdout/stderr、耗时和 Evidence |
MCP、JavaScript 浏览器交互、数据库连接池和持久终端进程留在后续阶段。
继续添加普通工具时,只注册 Schema 和执行函数,再由 ToolExecutor 统一生成
结果状态和 Evidence,不向 main.py 增加专用分支。
仍需继续加强
- 使用正式标注集校准 Router 和
min_rag_score,而不是长期依赖默认0.5。 - 为复杂任务增加真正的并行 PlanStep 调度和依赖关系。
- 为 retryable error 增加按工具配置的退避策略。
- 给 Validator 增加完整持久化日志和离线错误分析。
- 将内部
[E1]映射渲染为标题、文件位置或 URL 形式的来源列表。 - 长期语义记忆仍留在后续阶段;当前已持久化会话摘要、最近轮次和归档轮次, 支持按 session ID 续聊。
- Browser 后续再增加 JavaScript、点击、表单、截图和页面状态。
- Database 后续按实际业务决定 PostgreSQL/MySQL 连接配置和权限模型。
- Coding Agent 后续增加 LSP 符号搜索、Windows 受限 Token/容器执行后端和 按项目配置的自动验收命令。
- Skills 后续增加输入框
$skill-name补全和可选的浮层选择器。 - TUI 后续增加流式 Markdown 增量解析、运行中止和会话选择浮层。
Ruff 格式
项目格式配置位于 pyproject.toml,目标 Python 版本为 3.14,行宽为 88。
.\.venv\Scripts\ruff.exe format .
.\.venv\Scripts\ruff.exe format --check .
开源 RAG、Agent 与记忆项目研究
本节记录对以下项目主分支和官方文档的链路研究,并据此整理本项目后续的 目标架构:
这些项目并不属于同一种系统,主要分为四类:
| 类别 | 项目 | 核心目标 |
|---|---|---|
| 深度研究与报告生成 | Open Deep Research、STORM | 主动规划、反复搜索、生成长报告 |
| RAG 与 Agent 应用 | Khoj、Onyx、AnythingLLM、RAGFlow | 文档检索、工具调用、对话和引用 |
| 独立记忆层 | Mem0 | 从对话提取长期事实,并在后续检索 |
| 有状态 Agent 运行时 | Letta | 管理上下文窗口、记忆、工具和持久状态 |
统一观察模型
为了比较这些系统,将完整链路统一拆成以下阶段:
flowchart LR
A["用户输入"] --> B["会话状态与 Router"]
B --> C["任务规划与问题拆分"]
C --> D["RAG 检索与工具调用"]
D --> E["Evidence 统一登记"]
E --> F["去重、重排与压缩"]
F --> G["LLM 生成草稿"]
G --> H["格式、引用与事实校验"]
H -->|失败| C
H -->|通过| I["最终回答"]
I --> J["会话与长期记忆写回"]
各项目覆盖的重点不同:
| 项目 | 主要覆盖阶段 |
|---|---|
| Open Deep Research | 任务规划、并行研究、工具循环、研究压缩、报告生成 |
| STORM | 多视角提问、资料收集、大纲、分章节生成和引用 |
| Khoj | Router、本地与在线检索、工具循环、研究模式和记忆 |
| Onyx | 数据连接、权限索引、混合检索、工具循环和引用映射 |
| AnythingLLM | 工作区索引、普通 RAG、Agent Skills、Flows 和本地部署 |
| RAGFlow | 文档理解、模板切块、混合检索、重排、引用和 Agent Workflow |
| Mem0 | 长期记忆提取、去重、检索与更新 |
| Letta | Agent 状态、上下文窗口、Memory Blocks、文件和归档记忆 |
Open Deep Research 链路
用户输入
→ 判断是否需要澄清
→ 生成 research brief
→ Supervisor 制订研究计划
→ 并行启动多个 Researcher
→ Researcher 循环调用 Search、MCP 和 Think 工具
→ 网页去重和网页摘要
→ 压缩每个 Researcher 的研究结果
→ Supervisor 判断是否需要继续研究
→ 汇总全部 notes
→ Final Report 模型生成报告
主要实现:
可借鉴的设计:
- 普通输入先整理为独立的
research_brief。 - Supervisor 负责任务拆分,Researcher 负责执行。
- 多个互相独立的研究单元并行运行。
- 每个 Researcher 通过
LLM → Tool → Result → LLM循环继续研究。 - 原始网页先摘要,研究结果再压缩,降低最终模型的上下文压力。
- 复杂任务使用专门 Planner,普通问题继续走短链路。
需要补充的部分:
- 当前核心更接近在线深度研究,而不是本地知识库 RAG。
- 多次摘要和压缩后,需要额外保留原始 Evidence 映射。
- Structured Output 主要约束控制结果,不等同于逐断言事实校验。
STORM 链路
研究主题
→ 生成多个角色和视角
→ 每个角色与 Topic Expert 多轮对话
→ 每轮问题转换为多个搜索查询
→ 搜索并生成带引用的回答
→ 合并全部角色的访谈记录
→ 生成初始大纲
→ 使用访谈资料优化大纲
→ 按章节检索相关资料
→ 并行生成章节
→ 合并、去重和润色文章
主要实现:
可借鉴的设计:
- 多视角问题生成,提高复杂主题的检索覆盖率。
- 先构建资料表,再生成大纲和文章。
- 先确定文章结构,再为每个章节挑选证据。
- 章节独立生成,最终统一去重和润色。
- 保留搜索结果、访谈、大纲、草稿和引用映射等中间产物。
STORM 更适合作为独立的 report 工作流,不作为所有用户问题的默认链路。
Khoj 链路
用户输入
→ 加载 Agent 配置和对话历史
→ 检索相关长期记忆
→ Router 选择一个或多个数据源与工具
→ 普通问答或 Deep Research
→ 调用本地文档、网络、网页、代码、浏览器或 MCP
→ 合并和压缩工具结果
→ 生成回答
→ 从新对话中提取并写入长期记忆
主要实现:
Router 可选择的能力包括 Notes、General、Online、Webpage、Code、Research、 Operator 和 MCP。结构化结果返回后还会继续检查工具是否存在、当前 Agent 是否允许使用以及参数是否合法。
Deep Research 的主要循环为:
LLM 选择下一批工具
→ 校验工具及参数
→ 浏览器类工具顺序执行
→ 其他互不依赖的工具并行执行
→ 分类保存 document、web、code、browser 和 MCP 结果
→ 检查相同工具与参数是否重复调用
→ LLM 继续规划或生成最终总结
本项目重点参考:
- 结构化 Router;
- 工具白名单;
tool_name + normalized_arguments重复调用检测;- 普通问答与 Deep Research 分级;
- 当前轮工具结果分类保存;
- 用户中断和补充信息的处理方式。
Onyx 链路
离线索引:
Connector 拉取数据
→ 写入文档元数据和权限
→ 文档解析与切块
→ 可选上下文化摘要和文档摘要
→ 生成 embedding
→ 写入全文、向量、元数据和 ACL
→ 保存同步状态
在线检索:
用户查询
→ 构建用户权限和文档过滤条件
→ 生成查询 embedding
→ 关键词与向量混合检索
→ 并行查询内部索引和外部连接器
→ Chunk 去重
→ 分数融合与可选重排
→ 合并邻接 Chunk
→ 转换为统一搜索文档
→ 返回 LLM 工具循环
主要实现:
Onyx 会为搜索结果分配数字型 document ID。LLM 只使用这个 ID 引用,
真实标题、URL、权限和 UI 映射由系统保存。这种设计适合演化为本项目的
Evidence Registry。
本项目重点参考:
Evidence ID → 原始来源注册表;- 检索权限和过滤条件在工具执行前完成;
- Tool Result、LLM Context 和 UI 展示结果分离;
- 当前轮引用映射;
- 长工具结果压缩和上下文裁剪;
- 工具循环的显式状态管理。
AnythingLLM 链路
文档摄取:
文件、链接或文本
→ Collector 判断文件类型
→ 对应转换器解析
→ 输出标准化 Document
→ 根据 Workspace 切块
→ 生成 embedding
→ 写入 Workspace 对应的向量数据库 namespace
普通聊天与 RAG:
用户输入
→ 命令检测
→ Agent 模式检测
→ 模型路由
→ 加载聊天历史
→ 加载 pinned documents
→ 加载当前线程 parsed files
→ Workspace 向量相似度搜索
→ 可选 rerank
→ 历史来源回填上下文
→ 压缩和组装 messages
→ 调用 LLM
→ 返回 sources 并保存聊天记录
主要实现:
AnythingLLM 区分:
chat:没有检索结果时仍可使用模型通用知识;query:没有知识库命中时结束本轮知识回答;automatic:模型支持原生工具时转入 Agent 工具链。
它会把历史来源回填到上下文,但展示的 sources 主要保留本轮检索来源。
这种设计有助于连续对话,却不满足本项目计划中的严格当前轮证据隔离。
本项目主要参考工作区、Query 模式、全文与向量 RAG 混合方式,以及本地化 产品体验。
RAGFlow 链路
文档摄取:
上传或同步文档
→ 对象存储
→ 根据 parser_id 选择解析器
→ DeepDoc/Parser 解析版面、表格、图片和文本
→ 根据模板、分隔符和重叠率切块
→ 提取标题、问题、关键词、摘要和文档结构
→ 批量生成 embedding
→ 写入全文字段、向量和元数据
→ Elasticsearch/Infinity 建立索引
在线检索:
问题
→ KB、文档和元数据过滤
→ 构建全文 Query
→ 生成查询 embedding
→ 全文召回与 Dense 向量召回
→ 分数融合
→ 外部 reranker 或本地关键词/向量重排
→ PageRank、标签等额外排名特征
→ similarity threshold
→ 稳定排序和分页
→ 返回 Chunks 与文档聚合
主要实现:
可选能力还包括 GraphRAG、RAPTOR、PageIndex、元数据自动过滤、MCP、 Web Search、代码执行、Browser、Memory 和多 Agent Workflow。
本项目重点参考:
- Parser、Chunker、Embedder 和 VectorStore 分层;
- 标准化 Chunk 元数据;
- 关键词和向量多路召回;
- reranker 作为可插拔阶段;
- Retrieval 本身注册为普通工具;
- 检索权重、阈值和过滤条件显式化。
Mem0 链路
Mem0 是独立记忆层,不负责完整的 RAG 回答和通用工具 Agent。
记忆写入:
对话消息
→ 校验 user_id、agent_id 或 run_id
→ 加载最近消息
→ 检索已有相关记忆
→ 使用 LLM 提取新增事实
→ 批量生成 embedding
→ Hash 去重
→ 写入向量库
→ 提取并关联实体
→ 记录记忆历史
记忆检索:
查询
→ 校验 Scope 和 Filter
→ 查询词形归一
→ 提取查询实体
→ Dense 语义检索
→ Keyword/BM25 检索
→ Entity Boost
→ 分数融合和阈值过滤
→ 可选 reranker
→ 返回 MemoryItem
主要实现:
本项目主要参考:
- 按用户、Agent 和运行实例隔离记忆;
- 写入前检索已有记忆;
- 记忆去重、过期和更新策略;
- 语义、关键词和实体多信号检索;
- 记忆提取模型与正常回答模型分离。
记忆内容属于从对话提炼的状态,不与知识库的权威 Evidence 混为一类。
Letta 链路
用户输入
→ 加载 Agent 状态
→ 加载当前 Conversation 消息
→ 注入常驻 Memory Blocks
→ 注入已打开文件片段
→ 按需搜索 Archival Memory
→ 构建上下文窗口
→ LLM 推理
→ 调用记忆、文件、归档、MCP 或自定义工具
→ 工具结果写回上下文
→ LLM 继续推理或回答
→ 持久化消息、工具调用和 Agent 状态
→ 上下文过长时压缩历史
Letta 的上下文层级:
| 层级 | 是否常驻上下文 | 访问方式 | 适合内容 |
|---|---|---|---|
| Memory Blocks | 是 | 直接读取、记忆工具修改 | 用户信息、Persona、工作状态 |
| Conversation Messages | 部分 | 当前上下文、自动压缩 | 最近对话 |
| Files | 部分 | open、close、grep、semantic search | 较大的只读资料 |
| Archival Memory | 否 | 语义检索工具 | 长期但不必常驻的信息 |
| External RAG | 否 | MCP 或自定义工具 | 大规模外部知识库 |
官方文档:
本项目主要参考:
- 短期上下文、会话消息、常驻记忆和外部知识库分层;
- Memory Block 作为始终在上下文中的状态;
- 文件和长期记忆按需检索;
- 对话历史压缩和滑动窗口;
- Agent 状态与工具调用一起持久化。
项目能力横向对比
| 项目 | Router/规划 | 知识库检索 | Web 研究 | 通用工具 | 引用 | 长期记忆 | 主要适用场景 |
|---|---|---|---|---|---|---|---|
| Open Deep Research | Supervisor、多研究单元 | 较弱 | 很强 | Search、MCP | 报告引用 | 基本没有 | 深度调研 |
| STORM | Persona、Outline | 可接 VectorRM | 很强 | 较少 | 较强 | 没有 | 百科、综述和报告 |
| Khoj | 结构化多工具 Router | 强 | 强 | Code、Browser、MCP | 中等偏强 | 强 | 个人知识 Agent |
| Onyx | Agentic Loop | 很强 | 强 | Search、Web、Code | 很强 | 中等 | 企业知识助手 |
| AnythingLLM | chat、query、automatic | 中等 | 中等 | Skills、Flows、MCP | 中等 | Workspace、Global | 本地一体化助手 |
| RAGFlow | Workflow、Agent | 很强 | 强 | MCP、Code、Browser | 很强 | 正在完善 | 复杂文档 RAG |
| Mem0 | 无通用 Router | 只检索记忆 | 无 | 无 | 非核心能力 | 很强 | 独立长期记忆层 |
| Letta | 有状态 Agent Loop | Files、Archive、External RAG | 取决于工具 | 很强 | 非核心能力 | 很强 | 长期运行 Agent |
校验能力对比
需要区分三种校验:
Router 与输出结构校验
- Open Deep Research 使用 Structured Output 控制研究任务和终止状态。
- Khoj 使用 Pydantic、工具白名单和非法选择回退。
- Onyx 使用原生 Tool Calling,并为部分模型提供文本解析回退。
- RAGFlow 使用 Workflow 参数和结构化输出。
- Mem0 对 Scope、Filter 和输入类型进行校验。
- Letta 使用 Tool Rules 和工具参数模型限制执行路径。
工具调用与结果校验
- Khoj 检测重复的
tool_name + arguments。 - Onyx 把 Tool Result 和循环状态持久化,并限制循环次数。
- AnythingLLM 在 Query 模式下对空检索结果执行明确分支。
- RAGFlow 使用阈值、重排、过滤和任务日志控制检索结果。
- Open Deep Research 将工具错误作为 Tool Message 返回研究循环。
最终答案事实校验
上述项目的核心链路大多解决结构、工具、来源和引用编号问题,仍缺少统一的:
拆分最终答案中的事实断言
→ 为每条断言找到当前轮 Evidence
→ 判断 Evidence 是否支持断言
→ 不支持时删除、修改或继续检索
→ 重新生成
→ 再次校验
因此,本项目继续保留并增强独立 Validator。确定性格式要求优先使用代码 检查,事实与证据一致性再交给 Validator LLM。
研究后确定的目标链路
第二至第四阶段以以下链路为目标。Search、SQLite、File、静态 Browser 和 Python Code 已进入统一执行路径,MCP 继续作为后续扩展:
flowchart TD
A["用户输入"] --> B["创建 TurnState"]
S["SessionState:摘要、最近对话、未完成任务、用户约束"] --> C
B --> C["Input Context Builder"]
C --> D["Router:chat / rag / tools / research"]
D -->|"chat"| X["Answer Context Builder"]
D -->|"rag / tools"| E{"是否复杂任务"}
D -->|"research"| F["Planner"]
E -->|"否"| G["Tool Selector:选择一个或多个工具"]
E -->|"是"| F
F --> H["生成 PlanStep 和完成条件"]
G --> H
H --> I{"Loop Guard:步数、时间、重试和重规划预算"}
I -->|"允许执行"| JB["Tool Batch Scheduler"]
I -->|"达到预算"| X
JB --> JC{"是否包含写入或独占屏障"}
JC -->|"否"| JD["独立调用:线程安全段并发,否则顺序执行"]
JC -->|"是"| JE["连续独立段并发,写入与命令逐项执行"]
JD --> K["RAG / Search / DB / File / Browser / Code / PowerShell"]
JE --> K
K --> L["按 tool_call 原顺序写入 TurnState"]
L --> M["Tool Failure Policy"]
M -->|"success / partial"| N["Current-turn Evidence Registry"]
M -->|"retryable error"| I
M -->|"empty / fatal / repeated"| O{"是否选择其他工具"}
O -->|"是"| F
O -->|"否"| X
N --> P["证据去重、过滤、重排和预算裁剪"]
P --> X
X --> Q["构建回答上下文"]
Q --> R["生成 Draft"]
R --> T["格式与确定性校验"]
T -->|"格式问题"| R
T -->|"通过"| U["事实与引用校验"]
U -->|"需要补充证据"| V{"仍有重规划预算"}
V -->|"是"| F
V -->|"否"| W["基于现有证据收敛回答"]
U -->|"仅回答内容问题"| R
U -->|"通过"| Y["最终回答"]
W --> Y
Y --> Z["Session Memory Writer"]
Z --> AA["生成精简 TurnRecord"]
AA --> AB["更新 SessionState"]
AB --> AC{"上下文是否超过预算"}
AC -->|"是"| AD["更新 SessionSummary 并裁剪旧 TurnRecord"]
AC -->|"否"| AE["等待下一次用户输入"]
AD --> AE
目标链路组件来源
| 本项目组件 | 主要参考项目 |
|---|---|
| Router、工具选择和工具白名单 | Khoj |
| 复杂任务 Planner 和并行研究 | Open Deep Research |
| 多视角报告模式 | STORM |
| Tool Loop、Evidence ID 和引用映射 | Onyx |
| 文档解析、混合检索和重排 | RAGFlow |
| Workspace 和 Query 模式 | AnythingLLM |
| 长期事实记忆 | Mem0 |
| 上下文窗口和记忆分层 | Letta |
目标统一数据结构
class ToolResult:
tool_call_id: str
tool_name: str
status: str
data: object
evidence: tuple["Evidence", ...]
error_code: str | None
error_message: str | None
retryable: bool
fingerprint: str
metadata: dict
class Evidence:
evidence_id: str
turn_id: str
tool_call_id: str
source_type: str
source_uri: str | None
title: str | None
content: str
score: float | None
query: str
citation_required: bool
metadata: dict
class GroundingDecision:
action: str # pass / regenerate / retrieve_more
grounded: bool
citations_valid: bool
issues: tuple[str, ...]
retry_instruction: str
suggested_queries: tuple[str, ...]
claims: tuple["ClaimCheck", ...]
Validator 默认只读取:
evidence.turn_id == current_turn_id
历史消息用于理解对话,历史工具结果和历史 RAG 结果默认不作为本轮事实证据。 需要引用历史来源时,应在本轮重新检索并注册新的 Evidence。
阶段完成情况
| 阶段 | 状态 | 主要内容 |
|---|---|---|
| 第一阶段 | 已完成 | SessionContext、最近对话和 LLM 结构化摘要 |
| 第二阶段 | 已完成 | TurnState、ToolResult、ToolExecutor、Evidence Registry |
| 第三阶段 | 已完成基础版 | 四分类 Router、Coverage Gate、Planner、Loop Guard、失败策略 |
| 第四阶段 | 已完成基础版 | Answer Context、确定性校验、事实引用校验、Session Writer |
| 工具扩展 | 已完成首版 | Search、SQLite、File、静态 Browser、Python Code 与 Coding 工具箱;MCP 留在后续阶段 |
| 工具批次并发 | 已完成受控版 | 连续独立段、有界线程池、写入失败屏障、顺序提交、single-flight、同轮缓存、调用上限和物理失败预算去重 |
| Coding Agent | 已完成增强版 | 并行只读定位、Glob、Grep、Read、Write、Edit、受约束 Command、结构化 PowerShell、Interpreter 和即时语法反馈 |
| Skills | 已完成显式选择版 | 多目录发现、安全 YAML、/skills 选择、渐进披露和工具交集 |
| DamnatioX TUI | 已完成全屏版 | 固定 Composer、到底自动跟随、输入队列、模型/effort 浮层、思考显示、流式回答和时间统计 |
| 后续研究模式 | 待实施 | 带依赖边的 PlanStep DAG、STORM 风格报告、多 Researcher |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file damnatiox_agent-0.1.2.tar.gz.
File metadata
- Download URL: damnatiox_agent-0.1.2.tar.gz
- Upload date:
- Size: 486.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c376b18afcab71c9ee2a74bdecee55cbc7002af54680018a559f476273237fe3
|
|
| MD5 |
f043da1aab3db0f05587ac0974fd7d12
|
|
| BLAKE2b-256 |
510971bb96f4f6ee744f2fd13ee86cf50aa6103eb21fe85483784404dec050d1
|
Provenance
The following attestation bundles were made for damnatiox_agent-0.1.2.tar.gz:
Publisher:
publish.yml on jame100101/agent_learning
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
damnatiox_agent-0.1.2.tar.gz -
Subject digest:
c376b18afcab71c9ee2a74bdecee55cbc7002af54680018a559f476273237fe3 - Sigstore transparency entry: 2317709425
- Sigstore integration time:
-
Permalink:
jame100101/agent_learning@c3c2e6b6f83485408d651df1716f5f5d5ae10337 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/jame100101
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c3c2e6b6f83485408d651df1716f5f5d5ae10337 -
Trigger Event:
release
-
Statement type:
File details
Details for the file damnatiox_agent-0.1.2-py3-none-any.whl.
File metadata
- Download URL: damnatiox_agent-0.1.2-py3-none-any.whl
- Upload date:
- Size: 400.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e92e48bbf6403952461fbc4778852f839388cb3117adc21831c9da2dfaa5a76
|
|
| MD5 |
6b6a0aa650ed9780eda67d59c5a9a0b4
|
|
| BLAKE2b-256 |
65b60a2c090cb816a40b4e2200a52cb719665a3b32e21605791b102520447936
|
Provenance
The following attestation bundles were made for damnatiox_agent-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on jame100101/agent_learning
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
damnatiox_agent-0.1.2-py3-none-any.whl -
Subject digest:
9e92e48bbf6403952461fbc4778852f839388cb3117adc21831c9da2dfaa5a76 - Sigstore transparency entry: 2317709680
- Sigstore integration time:
-
Permalink:
jame100101/agent_learning@c3c2e6b6f83485408d651df1716f5f5d5ae10337 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/jame100101
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c3c2e6b6f83485408d651df1716f5f5d5ae10337 -
Trigger Event:
release
-
Statement type: