knight-agent 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/Host.d.ts +23 -0
  2. package/Host.d.ts.map +1 -0
  3. package/Host.js +23 -0
  4. package/Host.js.map +1 -0
  5. package/base/AbstractAgent.d.ts +100 -0
  6. package/base/AbstractAgent.d.ts.map +1 -0
  7. package/base/AbstractAgent.js +23 -0
  8. package/base/AbstractAgent.js.map +1 -0
  9. package/base/AbstractDialog.d.ts +54 -0
  10. package/base/AbstractDialog.d.ts.map +1 -0
  11. package/base/AbstractDialog.js +86 -0
  12. package/base/AbstractDialog.js.map +1 -0
  13. package/base/AbstractModule.d.ts +7 -0
  14. package/base/AbstractModule.d.ts.map +1 -0
  15. package/base/AbstractModule.js +13 -0
  16. package/base/AbstractModule.js.map +1 -0
  17. package/base/AbstractObject.d.ts +18 -0
  18. package/base/AbstractObject.d.ts.map +1 -0
  19. package/base/AbstractObject.js +25 -0
  20. package/base/AbstractObject.js.map +1 -0
  21. package/base/AbstractReason.d.ts +44 -0
  22. package/base/AbstractReason.d.ts.map +1 -0
  23. package/base/AbstractReason.js +23 -0
  24. package/base/AbstractReason.js.map +1 -0
  25. package/base/AbstractSkill.d.ts +25 -0
  26. package/base/AbstractSkill.d.ts.map +1 -0
  27. package/base/AbstractSkill.js +3 -0
  28. package/base/AbstractSkill.js.map +1 -0
  29. package/base/AbstractTool.d.ts +34 -0
  30. package/base/AbstractTool.d.ts.map +1 -0
  31. package/base/AbstractTool.js +3 -0
  32. package/base/AbstractTool.js.map +1 -0
  33. package/base/index.d.ts +8 -0
  34. package/base/index.d.ts.map +1 -0
  35. package/base/index.js +24 -0
  36. package/base/index.js.map +1 -0
  37. package/docs/ARCHITECTURE.md +601 -0
  38. package/docs/README.md +562 -0
  39. package/index.d.ts +4 -0
  40. package/index.d.ts.map +1 -0
  41. package/index.js +25 -0
  42. package/index.js.map +1 -0
  43. package/module/AgentModule/Agent.d.ts +55 -0
  44. package/module/AgentModule/Agent.d.ts.map +1 -0
  45. package/module/AgentModule/Agent.js +210 -0
  46. package/module/AgentModule/Agent.js.map +1 -0
  47. package/module/AgentModule/AgentModule.d.ts +26 -0
  48. package/module/AgentModule/AgentModule.d.ts.map +1 -0
  49. package/module/AgentModule/AgentModule.js +66 -0
  50. package/module/AgentModule/AgentModule.js.map +1 -0
  51. package/module/AgentModule/Memory.d.ts +55 -0
  52. package/module/AgentModule/Memory.d.ts.map +1 -0
  53. package/module/AgentModule/Memory.js +288 -0
  54. package/module/AgentModule/Memory.js.map +1 -0
  55. package/module/AgentModule/index.d.ts +2 -0
  56. package/module/AgentModule/index.d.ts.map +1 -0
  57. package/module/AgentModule/index.js +18 -0
  58. package/module/AgentModule/index.js.map +1 -0
  59. package/module/DialogModule/Dialog.d.ts +14 -0
  60. package/module/DialogModule/Dialog.d.ts.map +1 -0
  61. package/module/DialogModule/Dialog.js +27 -0
  62. package/module/DialogModule/Dialog.js.map +1 -0
  63. package/module/DialogModule/DialogModule.d.ts +39 -0
  64. package/module/DialogModule/DialogModule.d.ts.map +1 -0
  65. package/module/DialogModule/DialogModule.js +118 -0
  66. package/module/DialogModule/DialogModule.js.map +1 -0
  67. package/module/DialogModule/index.d.ts +3 -0
  68. package/module/DialogModule/index.d.ts.map +1 -0
  69. package/module/DialogModule/index.js +19 -0
  70. package/module/DialogModule/index.js.map +1 -0
  71. package/module/ReasonModule/ChainReason.d.ts +11 -0
  72. package/module/ReasonModule/ChainReason.d.ts.map +1 -0
  73. package/module/ReasonModule/ChainReason.js +34 -0
  74. package/module/ReasonModule/ChainReason.js.map +1 -0
  75. package/module/ReasonModule/CommanderReason.d.ts +15 -0
  76. package/module/ReasonModule/CommanderReason.d.ts.map +1 -0
  77. package/module/ReasonModule/CommanderReason.js +151 -0
  78. package/module/ReasonModule/CommanderReason.js.map +1 -0
  79. package/module/ReasonModule/CompetitiveReason.d.ts +13 -0
  80. package/module/ReasonModule/CompetitiveReason.d.ts.map +1 -0
  81. package/module/ReasonModule/CompetitiveReason.js +133 -0
  82. package/module/ReasonModule/CompetitiveReason.js.map +1 -0
  83. package/module/ReasonModule/PlanReason.d.ts +25 -0
  84. package/module/ReasonModule/PlanReason.d.ts.map +1 -0
  85. package/module/ReasonModule/PlanReason.js +133 -0
  86. package/module/ReasonModule/PlanReason.js.map +1 -0
  87. package/module/ReasonModule/ReasonModule.d.ts +41 -0
  88. package/module/ReasonModule/ReasonModule.d.ts.map +1 -0
  89. package/module/ReasonModule/ReasonModule.js +83 -0
  90. package/module/ReasonModule/ReasonModule.js.map +1 -0
  91. package/module/ReasonModule/ReflectReason.d.ts +15 -0
  92. package/module/ReasonModule/ReflectReason.d.ts.map +1 -0
  93. package/module/ReasonModule/ReflectReason.js +86 -0
  94. package/module/ReasonModule/ReflectReason.js.map +1 -0
  95. package/module/ReasonModule/TreeReason.d.ts +16 -0
  96. package/module/ReasonModule/TreeReason.d.ts.map +1 -0
  97. package/module/ReasonModule/TreeReason.js +139 -0
  98. package/module/ReasonModule/TreeReason.js.map +1 -0
  99. package/module/ReasonModule/index.d.ts +8 -0
  100. package/module/ReasonModule/index.d.ts.map +1 -0
  101. package/module/ReasonModule/index.js +24 -0
  102. package/module/ReasonModule/index.js.map +1 -0
  103. package/module/SkillModule/SkillModule.d.ts +42 -0
  104. package/module/SkillModule/SkillModule.d.ts.map +1 -0
  105. package/module/SkillModule/SkillModule.js +134 -0
  106. package/module/SkillModule/SkillModule.js.map +1 -0
  107. package/module/SkillModule/index.d.ts +2 -0
  108. package/module/SkillModule/index.d.ts.map +1 -0
  109. package/module/SkillModule/index.js +18 -0
  110. package/module/SkillModule/index.js.map +1 -0
  111. package/module/ToolModule/ToolModule.d.ts +57 -0
  112. package/module/ToolModule/ToolModule.d.ts.map +1 -0
  113. package/module/ToolModule/ToolModule.js +220 -0
  114. package/module/ToolModule/ToolModule.js.map +1 -0
  115. package/module/ToolModule/ToolRAG.d.ts +38 -0
  116. package/module/ToolModule/ToolRAG.d.ts.map +1 -0
  117. package/module/ToolModule/ToolRAG.js +124 -0
  118. package/module/ToolModule/ToolRAG.js.map +1 -0
  119. package/module/ToolModule/index.d.ts +3 -0
  120. package/module/ToolModule/index.d.ts.map +1 -0
  121. package/module/ToolModule/index.js +19 -0
  122. package/module/ToolModule/index.js.map +1 -0
  123. package/module/index.d.ts +6 -0
  124. package/module/index.d.ts.map +1 -0
  125. package/module/index.js +22 -0
  126. package/module/index.js.map +1 -0
  127. package/package.json +19 -0
  128. package/utility/InterfaceUtility.d.ts +14 -0
  129. package/utility/InterfaceUtility.d.ts.map +1 -0
  130. package/utility/InterfaceUtility.js +3 -0
  131. package/utility/InterfaceUtility.js.map +1 -0
  132. package/utility/LogUtility.d.ts +41 -0
  133. package/utility/LogUtility.d.ts.map +1 -0
  134. package/utility/LogUtility.js +70 -0
  135. package/utility/LogUtility.js.map +1 -0
  136. package/utility/NetworkUtility.d.ts +91 -0
  137. package/utility/NetworkUtility.d.ts.map +1 -0
  138. package/utility/NetworkUtility.js +104 -0
  139. package/utility/NetworkUtility.js.map +1 -0
  140. package/utility/ObjectUtility.d.ts +134 -0
  141. package/utility/ObjectUtility.d.ts.map +1 -0
  142. package/utility/ObjectUtility.js +313 -0
  143. package/utility/ObjectUtility.js.map +1 -0
  144. package/utility/OpenAIUtility.d.ts +333 -0
  145. package/utility/OpenAIUtility.d.ts.map +1 -0
  146. package/utility/OpenAIUtility.js +95 -0
  147. package/utility/OpenAIUtility.js.map +1 -0
  148. package/utility/PromiseUtility.d.ts +9 -0
  149. package/utility/PromiseUtility.d.ts.map +1 -0
  150. package/utility/PromiseUtility.js +16 -0
  151. package/utility/PromiseUtility.js.map +1 -0
  152. package/utility/StringUtility.d.ts +10 -0
  153. package/utility/StringUtility.d.ts.map +1 -0
  154. package/utility/StringUtility.js +42 -0
  155. package/utility/StringUtility.js.map +1 -0
  156. package/utility/TimeUtility.d.ts +10 -0
  157. package/utility/TimeUtility.d.ts.map +1 -0
  158. package/utility/TimeUtility.js +24 -0
  159. package/utility/TimeUtility.js.map +1 -0
  160. package/utility/index.d.ts +9 -0
  161. package/utility/index.d.ts.map +1 -0
  162. package/utility/index.js +25 -0
  163. package/utility/index.js.map +1 -0
package/docs/README.md ADDED
@@ -0,0 +1,562 @@
1
+ # Knight Agent 2.0 — 使用手册
2
+
3
+ 基于 DeepSeek API 的模块化 TypeScript AI Agent 框架。提供 6 种内置推理策略、工具管理、技能能力包、对话持久化和多级 Token 优化。
4
+
5
+ ---
6
+
7
+ ## 目录
8
+
9
+ - [架构概览](#架构概览)
10
+ - [快速开始](#快速开始)
11
+ - [配置](#一配置-agentconfig)
12
+ - [工具 Tool](#二工具-tool)
13
+ - [技能 Skill](#三技能-skill)
14
+ - [对话 Dialog](#四对话-dialog)
15
+ - [推理策略 Reason](#五推理策略-reason)
16
+ - [两个执行路径对比](#六两个执行路径对比)
17
+ - [Token 优化体系](#七token-优化体系)
18
+ - [持久化与快照](#八持久化与快照)
19
+ - [完整示例](#九完整示例多设备控制场景)
20
+ - [Host 模块一览](#十host-模块一览)
21
+
22
+ ---
23
+
24
+ ## 架构概览
25
+
26
+ ```
27
+ ┌─────────────────────────────────────────────────┐
28
+ │ Host (单例) │
29
+ │ .toolModule .skillModule .reasonModule │
30
+ │ .agentModule .dialogModule │
31
+ └─────────────────────────────────────────────────┘
32
+ ↑ 业务层通过 Host.Instance 访问所有模块
33
+
34
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
35
+ │ Tool │ │ Skill │ │ Reason │
36
+ │ 单函数 │───→│ 工具包 │ │ 推理策略 │
37
+ │ 描述符 │ │ +prompt │ │ 6种模式 │
38
+ └──────────┘ └────┬─────┘ └────┬─────┘
39
+ │ │
40
+ ▼ ▼
41
+ ┌──────────────────────────┐
42
+ │ Dialog │
43
+ │ 持久化 Agent + 策略绑定 │
44
+ │ Skill 作用域控制工具可见 │
45
+ └──────────┬───────────────┘
46
+
47
+
48
+ ┌──────────────────────────┐
49
+ │ Agent │
50
+ │ 消息缓存 + ReAct 主循环 │
51
+ │ 上下文窗口自动优化 │
52
+ └──────────────────────────┘
53
+
54
+ 工具选择管线:
55
+ 用户输入
56
+ → Skill 过滤: resolveTools(dialogId) → 候选工具名
57
+ → ToolRAG 语义排序: selectTools(query, candidates, topK) → Top-K
58
+ → Compact Schema: ToAPITools(names, compact=true) → 精简定义
59
+ → LLM 调用
60
+ ```
61
+
62
+ ---
63
+
64
+ ## 快速开始
65
+
66
+ ```typescript
67
+ import Host from "knight-agent";
68
+
69
+ // 1. 注册工具
70
+ Host.toolModule.register({
71
+ name: "web/search",
72
+ description: "Search the web for information",
73
+ schema: {
74
+ type: "object",
75
+ properties: { query: { type: "string" } },
76
+ required: ["query"],
77
+ },
78
+ handler: async (args) => {
79
+ const res = await fetch(`https://api.search.com?q=${args.query}`);
80
+ return JSON.stringify(await res.json());
81
+ },
82
+ cacheable: true,
83
+ parallelizable: true,
84
+ });
85
+
86
+ // 2. 注册技能
87
+ Host.skillModule.register({
88
+ name: "web-research",
89
+ description: "Web search and browsing capability",
90
+ tools: ["web/search"],
91
+ systemPrompt: "You can use web/search to find up-to-date information.",
92
+ });
93
+
94
+ // 3. 创建对话
95
+ const dialog = Host.dialogModule.create(
96
+ "Research Task",
97
+ {
98
+ address: "https://api.deepseek.com/v1/chat/completions",
99
+ apiKey: "sk-xxx",
100
+ model: "deepseek-chat",
101
+ temperature: 0.6,
102
+ maxTurns: 20,
103
+ },
104
+ "ChainReason"
105
+ );
106
+
107
+ // 4. 启用技能
108
+ Host.skillModule.enable(dialog.id, "web-research");
109
+
110
+ // 5. 发送消息 (自动: Skill过滤→RAG排序→Compact Schema→LLM)
111
+ const result = await dialog.send("What is the latest news about AI?");
112
+ console.log(result.content);
113
+
114
+ // 6. 切换策略 (不影响消息历史)
115
+ dialog.switchStrategy("ReflectReason");
116
+ await dialog.send("Refine the answer with more details.");
117
+
118
+ // 7. 销毁
119
+ Host.dialogModule.destroy(dialog.id);
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 一、配置 (AgentConfig)
125
+
126
+ 创建 Agent / Dialog 时的统一配置:
127
+
128
+ | 字段 | 类型 | 必填 | 说明 |
129
+ |---|---|---|---|
130
+ | `address` | `string` | ✅ | API 端点地址 |
131
+ | `apiKey` | `string` | ✅ | API 密钥 |
132
+ | `model` | `string` | ✅ | 模型名称 |
133
+ | `systemPrompt` | `string` | | 系统提示词 |
134
+ | `enableThinking` | `boolean` | | 思考模式开关,默认 `true` |
135
+ | `reasoningEffort` | `"high" \| "max"` | | 推理强度 |
136
+ | `temperature` | `number` | | 采样温度 (0~2) |
137
+ | `maxTokens` | `number` | | 最大输出 token |
138
+ | `maxTurns` | `number` | | 最大对话轮次 |
139
+
140
+ ---
141
+
142
+ ## 二、工具 (Tool)
143
+
144
+ ### 注册工具
145
+
146
+ ```typescript
147
+ Host.toolModule.register({
148
+ name: "pc/screenshot", // 支持命名空间: "namespace/name"
149
+ description: "Capture a screenshot of the current desktop",
150
+ schema: {
151
+ type: "object",
152
+ properties: {
153
+ region: { type: "string", enum: ["full", "active", "selection"] }
154
+ },
155
+ required: ["region"],
156
+ },
157
+ handler: async (args) => { /* 调 MCP / API / 本地逻辑 */ return "..."; },
158
+
159
+ // 可选属性
160
+ cacheable: true, // 相同参数缓存结果 (默认 60s TTL)
161
+ retryable: true, // 失败可重试
162
+ maxRetries: 3, // 最大重试次数 (默认 1)
163
+ parallelizable: true, // 可与其他工具并行执行
164
+ requiresApproval: false, // 需人工审批 (预留)
165
+ category: "desktop", // 分类标签
166
+ });
167
+ ```
168
+
169
+ ### 管理工具
170
+
171
+ ```typescript
172
+ Host.toolModule.registerAll([tool1, tool2]); // 批量注册
173
+ Host.toolModule.unregister("toolName"); // 移除 (自动清缓存+去索引)
174
+ Host.toolModule.get("toolName"); // 获取定义
175
+ Host.toolModule.list(); // 全部
176
+ Host.toolModule.listByCategory("desktop"); // 按分类
177
+ Host.toolModule.count; // 数量
178
+ Host.toolModule.clear(); // 清空全部
179
+ Host.toolModule.invalidateCache(); // 清空全部缓存
180
+ Host.toolModule.invalidateCache("pc/screenshot"); // 精确清除某个工具缓存
181
+ ```
182
+
183
+ ### 语义检索 (ToolRAG)
184
+
185
+ 当候选工具数 > topK 时自动排序,选择最相关的工具发送给 LLM:
186
+
187
+ ```typescript
188
+ // 默认: 内置关键词匹配 (零依赖)
189
+ const names = await Host.toolModule.selectTools(
190
+ "take a screenshot",
191
+ ["pc/screenshot", "file/read", "web/search"],
192
+ 5 // topK
193
+ );
194
+
195
+ // 可选: 接入真实 Embedding API 提升精度
196
+ Host.toolModule.setEmbeddingProvider({
197
+ dims: 1536,
198
+ embed: async (text) => fetch("https://api.openai.com/v1/embeddings", {
199
+ method: "POST",
200
+ headers: { "Authorization": `Bearer ${key}` },
201
+ body: JSON.stringify({ model: "text-embedding-3-small", input: text }),
202
+ }).then(r => r.json()).then(d => d.data[0].embedding),
203
+ });
204
+ ```
205
+
206
+ ### 导出为 OpenAI API 格式
207
+
208
+ ```typescript
209
+ const apiTools = Host.toolModule.ToAPITools(["tool1", "tool2"], true);
210
+ // compact=true 时自动裁剪 schema (移除 description/default)
211
+ ```
212
+
213
+ ---
214
+
215
+ ## 三、技能 (Skill)
216
+
217
+ Skill 是工具能力包 + 使用指导的组合体。框架通过 Skill 控制每个对话可见的工具范围。
218
+
219
+ ### 注册技能
220
+
221
+ ```typescript
222
+ Host.skillModule.register({
223
+ name: "Windows Control",
224
+ description: "Control Windows desktop: screenshot, clipboard, window management",
225
+ version: "1.0.0",
226
+ tools: ["pc/screenshot", "pc/clipboard", "pc/window"], // 精确匹配
227
+ systemPrompt: "PC 文件操作前先确认路径是否存在。",
228
+ category: "desktop",
229
+ constraints: {
230
+ maxCallsPerTurn: 5,
231
+ requireApproval: false,
232
+ },
233
+ });
234
+ ```
235
+
236
+ ### 工具匹配规则
237
+
238
+ ```typescript
239
+ tools: ["pc/screenshot", "pc/clipboard"] // 精确匹配
240
+ tools: ["pc/*"] // 通配: 匹配所有 "pc/" 前缀的工具
241
+ tools: ["pc/screenshot", "android/*"] // 混合
242
+ ```
243
+
244
+ ### 对话级启用/禁用
245
+
246
+ ```typescript
247
+ Host.skillModule.enable(dialogId, "Windows Control"); // 启用
248
+ Host.skillModule.disable(dialogId, "Windows Control"); // 禁用
249
+ Host.skillModule.getEnabled(dialogId); // 获取启用的技能列表
250
+ Host.skillModule.resolveTools(dialogId); // → ToolDefinition[] (自动展开通配符)
251
+ Host.skillModule.buildPrompt(dialogId); // → 聚合的 systemPrompt 文本
252
+ Host.skillModule.clearDialog(dialogId); // 清理对话绑定
253
+ ```
254
+
255
+ > **没有启用任何技能时**,`resolveTools` 返回空数组,Agent 无法调用任何工具。
256
+
257
+ ---
258
+
259
+ ## 四、对话 (Dialog)
260
+
261
+ Dialog = 持久化 Agent + 绑定推理策略 + Skill 作用域。Agent 随对话存在,不随消息销毁。
262
+
263
+ ### 创建
264
+
265
+ ```typescript
266
+ const dialog = Host.dialogModule.create(
267
+ "标题", // 对话标题
268
+ { // AgentConfig (含 apiKey/address)
269
+ address: "https://api.deepseek.com/v1/chat/completions",
270
+ apiKey: "sk-xxx",
271
+ model: "deepseek-chat",
272
+ systemPrompt: "You are a helpful assistant.",
273
+ },
274
+ "ChainReason" // 初始策略 (可选,默认 ChainReason)
275
+ );
276
+ ```
277
+
278
+ ### 发送消息
279
+
280
+ ```typescript
281
+ const result = await dialog.send("你好");
282
+
283
+ // DialogResult {
284
+ // success: boolean;
285
+ // content: string; // 助手回复
286
+ // thinking?: string; // CoT 思考过程
287
+ // toolCalls?: ...; // 工具调用记录
288
+ // usage?: { prompt_tokens, completion_tokens, total_tokens };
289
+ // finishReason?: string;
290
+ // strategy: string; // 使用的策略名
291
+ // dialogId: string; // 对话 ID
292
+ // trace?: string[]; // 推理追踪日志
293
+ // reflectionRounds?: number; // 反思轮次 (仅 ReflectReason)
294
+ // }
295
+ ```
296
+
297
+ ### 切换策略
298
+
299
+ ```typescript
300
+ dialog.switchStrategy("ReflectReason"); // 返回 true/false
301
+ dialog.strategy; // 读取当前策略名
302
+ ```
303
+
304
+ ### 生命周期
305
+
306
+ ```typescript
307
+ Host.dialogModule.get(dialogId); // 获取 Dialog 实例
308
+ Host.dialogModule.list(); // 列出全部 [{dialogId, title, strategy}]
309
+ Host.dialogModule.count; // 数量
310
+ Host.dialogModule.destroy(dialogId); // 销毁 (内部自动销毁 Agent)
311
+ Host.dialogModule.destroyAll(); // 销毁全部
312
+ ```
313
+
314
+ ---
315
+
316
+ ## 五、推理策略 (Reason)
317
+
318
+ 6 种内置策略,不创建 Dialog 也可直接使用 (一次性 Agent,用完即毁)。
319
+
320
+ ### 策略列表
321
+
322
+ | 策略 | 键名 | 适合场景 | Agent 数 |
323
+ |---|---|---|---|
324
+ | **ChainReason** | `"ChainReason"` | 简单问答、事实查询、单步推理 | 1 |
325
+ | **ReflectReason** | `"ReflectReason"` | 代码生成、写作、翻译 (质量敏感) | 1 |
326
+ | **TreeReason** | `"TreeReason"` | 方案设计、多方案对比、开放探索 | 1 |
327
+ | **PlanReason** | `"PlanReason"` | 多步骤任务、开发流程、配置部署 | 1 |
328
+ | **CompetitiveReason** | `"CompetitiveReason"` | 方案决策、多角度分析 | N+1 (裁判) |
329
+ | **CommanderReason** | `"CommanderReason"` | 复杂多模块任务、分工协作 | 1+N (工人) |
330
+
331
+ ### 一次性执行 (不创建 Dialog)
332
+
333
+ ```typescript
334
+ const result = await Host.reasonModule.execute(
335
+ "Write a debounce function in TypeScript",
336
+ {
337
+ baseConfig: {
338
+ address: "https://api.deepseek.com/v1/chat/completions",
339
+ apiKey: "sk-xxx",
340
+ model: "deepseek-chat",
341
+ },
342
+ // 策略特定参数 (可选)
343
+ competitorCount: 3, // CompetitiveReason: 竞争者数量
344
+ varyTemperature: true, // CompetitiveReason: 温度差异化
345
+ maxWorkers: 3, // CommanderReason: 最大工人数
346
+ },
347
+ "ReflectReason" // 策略名,默认 ChainReason
348
+ );
349
+ ```
350
+
351
+ ### 注册自定义策略
352
+
353
+ ```typescript
354
+ import { AbstractReason, ReasonConfig, ReasonResult } from "knight-agent";
355
+
356
+ class MyReason extends AbstractReason {
357
+ public readonly type = "MyReason";
358
+ async execute(input: string, config: ReasonConfig): Promise<ReasonResult> {
359
+ // ... 自定义推理逻辑
360
+ }
361
+ }
362
+
363
+ Host.reasonModule.register("MyReason", new MyReason());
364
+ ```
365
+
366
+ ### 策略管理
367
+
368
+ ```typescript
369
+ Host.reasonModule.register("name", reason); // 注册
370
+ Host.reasonModule.unregister("name"); // 注销
371
+ Host.reasonModule.has("ChainReason"); // 存在检查
372
+ Host.reasonModule.get("ReflectReason"); // 获取实例
373
+ Host.reasonModule.list(); // [{name, type}, ...]
374
+ Host.reasonModule.count; // 数量
375
+ ```
376
+
377
+ ---
378
+
379
+ ## 六、两个执行路径对比
380
+
381
+ | | **一次性 (ReasonModule)** | **持久化 (Dialog)** |
382
+ |---|---|---|
383
+ | Agent 生命周期 | 创建 → 执行 → 销毁 | 创建 → 常驻 → destroy |
384
+ | 消息历史 | 单次,不保留 | 跨轮次累积 |
385
+ | 工具可见 | 全部注册的工具 | 由启用的 Skill 过滤 |
386
+ | RAG 工具排序 | ❌ 不经过 | ✅ 自动排序 |
387
+ | Skill 作用域 | ❌ 不支持 | ✅ 支持 |
388
+ | 快照持久化 | ❌ | ✅ |
389
+ | 使用 | `reasonModule.execute()` | `dialog.send()` |
390
+
391
+ ---
392
+
393
+ ## 七、Token 优化体系
394
+
395
+ 框架内置 4 级 Token 开销优化,在 `dialog.send()` 路径上自动生效。
396
+
397
+ ### P0 — Compact Tool Schema
398
+
399
+ `ToolModule.ToAPITools(names, compact=true)` 递归裁剪 JSONSchema,移除 `description` 和 `default` 字段,仅保留 `type/enum/required/properties/items`。Agent 在每次 `OnSendRequest` 中始终传入 `compact=true`。
400
+
401
+ ```
402
+ 原始: {"type":"string","description":"Search keywords","default":""}
403
+ 精简: {"type":"string"}
404
+ ```
405
+
406
+ ### P1 — MemoryPressure 三级阈值
407
+
408
+ `Memory.checkPressure()` 返回 4 级压力状态,触发分级压缩:
409
+
410
+ | 级别 | 阈值 | 操作 | LLM 调用 |
411
+ |------|------|------|---------|
412
+ | `None` | < 70% | 无操作 | 0 |
413
+ | `Mild` | 70-85% | 压缩前 30% 消息为摘要 | 1 |
414
+ | `Moderate` | 85-95% | 压缩远期 + 摘要中间轮次 + 提取实体 | 1-2 |
415
+ | `Critical` | > 95% | 激进裁剪,仅保留最近 3 轮 + 纯文本摘要 | 0-1 |
416
+
417
+ 发送请求前自动检测并执行,无需手动干预。
418
+
419
+ ### P2 — tiktoken 精确计数
420
+
421
+ 使用 tiktoken (`cl100k_base`) 进行字节级 Token 估算,兼容 DeepSeek/OpenAI。
422
+
423
+ ```typescript
424
+ import { MemoryPressure } from "knight-agent";
425
+
426
+ const tokens = agent.memory.estimateTokens(); // 精确 Token 数
427
+ const level = agent.memory.checkPressure(); // MemoryPressure 枚举
428
+ if (level > MemoryPressure.None) {
429
+ await agent.memory.optimize(level); // 按级别压缩
430
+ }
431
+ ```
432
+
433
+ ### P3 — ToolRAG 语义检索
434
+
435
+ 当候选工具数 > topK 时自动排序选择最相关工具。默认使用零依赖关键词匹配,可接入 Embedding API 提升精度。
436
+
437
+ **优化效果**: 100 个工具注册 → Skill 过滤至 20 个 → RAG 排序取 Top-10 → Compact 裁剪 → 最终 Token 开销约 3% 原始量。
438
+
439
+ ---
440
+
441
+ ## 八、持久化与快照
442
+
443
+ 框架支持 Dialog 级别的快照导出/恢复 (不含 `apiKey`/`address`)。
444
+
445
+ ### 导出
446
+
447
+ ```typescript
448
+ const snapshot = Host.dialogModule.export(dialogId);
449
+ // DialogSnapshot {
450
+ // version, createdAt, dialogId, title, strategy,
451
+ // agentSnapshot: { version, createdAt, agentId, turnCount,
452
+ // messages, scratchpad, toolResults, config }
453
+ // }
454
+
455
+ // 保存到数据库
456
+ await db.save("snapshots", snapshot.dialogId, snapshot);
457
+ ```
458
+
459
+ ### 恢复
460
+
461
+ ```typescript
462
+ // 需重新提供 apiKey/address (快照中已剥离)
463
+ const config: AgentConfig = {
464
+ address: "https://api.deepseek.com/v1/chat/completions",
465
+ apiKey: "sk-xxx",
466
+ model: "...",
467
+ };
468
+
469
+ const restored = Host.dialogModule.import(snapshot, config);
470
+ await restored.send("Continue from where we left off.");
471
+ ```
472
+
473
+ ---
474
+
475
+ ## 九、完整示例:多设备控制场景
476
+
477
+ ```typescript
478
+ import Host from "knight-agent";
479
+
480
+ // ---- 注册工具 ----
481
+ Host.toolModule.registerAll([
482
+ {
483
+ name: "pc/screenshot",
484
+ description: "截取 PC 当前屏幕",
485
+ schema: { type: "object", properties: { region: { type: "string" } } },
486
+ handler: async (args) => await pcMcp.call("screenshot", args),
487
+ cacheable: true,
488
+ },
489
+ {
490
+ name: "pc/file_read",
491
+ description: "读取 PC 上的文件内容",
492
+ schema: { type: "object", properties: { filePath: { type: "string" } }, required: ["filePath"] },
493
+ handler: async (args) => await pcMcp.call("file_read", args),
494
+ },
495
+ {
496
+ name: "android/screenshot",
497
+ description: "截取 Android 当前屏幕",
498
+ schema: { type: "object", properties: {} },
499
+ handler: async () => await androidMcp.call("screenshot", {}),
500
+ },
501
+ {
502
+ name: "android/app_install",
503
+ description: "在 Android 设备上安装应用",
504
+ schema: { type: "object", properties: { packageName: { type: "string" } }, required: ["packageName"] },
505
+ handler: async (args) => await androidMcp.call("app_install", args),
506
+ },
507
+ ]);
508
+
509
+ // ---- 注册技能 (工具能力包) ----
510
+ Host.skillModule.register({
511
+ name: "PC Control",
512
+ description: "控制 PC 设备",
513
+ tools: ["pc/screenshot", "pc/file_read"],
514
+ systemPrompt: "PC 文件操作前先确认路径是否存在。",
515
+ });
516
+
517
+ Host.skillModule.register({
518
+ name: "Android Control",
519
+ description: "控制 Android 设备",
520
+ tools: ["android/screenshot", "android/app_install"],
521
+ });
522
+
523
+ // ---- 创建对话 ----
524
+ const dialog = Host.dialogModule.create("设备管理", {
525
+ address: "https://api.deepseek.com/v1/chat/completions",
526
+ apiKey: "sk-xxx",
527
+ model: "deepseek-chat",
528
+ systemPrompt: "你是设备管理助手。",
529
+ });
530
+
531
+ Host.skillModule.enable(dialog.id, "PC Control");
532
+ Host.skillModule.enable(dialog.id, "Android Control");
533
+
534
+ // ---- 使用 ----
535
+ const r1 = await dialog.send("给 PC 和 Android 都截个屏");
536
+ console.log(r1.content);
537
+
538
+ dialog.switchStrategy("PlanReason");
539
+ const r2 = await dialog.send("先在 PC 上读取配置文件,根据配置在 Android 上安装对应应用");
540
+ console.log(r2.content);
541
+ console.log(r2.trace); // 计划执行追踪
542
+
543
+ // ---- 导出快照 ----
544
+ const snapshot = Host.dialogModule.export(dialog.id);
545
+ await saveToDatabase(snapshot);
546
+ ```
547
+
548
+ ---
549
+
550
+ ## 十、Host 模块一览
551
+
552
+ ```typescript
553
+ import Host from "knight-agent";
554
+
555
+ Host.toolModule // 工具注册表 + 执行调度 + 缓存 + RAG 检索
556
+ Host.skillModule // 技能注册 + 对话级启用/禁用
557
+ Host.reasonModule // 推理策略注册 + 一次性执行
558
+ Host.dialogModule // 对话池 + 生命周期 + 快照导入导出
559
+ Host.agentModule // Agent 创建/销毁/查询
560
+ ```
561
+
562
+ 每个模块继承 `AbstractModule` → `AbstractObject`,自动分配 `id` 并注册到全局对象池,可通过 `Host.Instance` 直接访问。
package/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./Host";
2
+ export * from "./module";
3
+ export { default } from "./Host";
4
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC"}
package/index.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.default = void 0;
21
+ __exportStar(require("./Host"), exports);
22
+ __exportStar(require("./module"), exports);
23
+ var Host_1 = require("./Host");
24
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(Host_1).default; } });
25
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,2CAAyB;AACzB,+BAAiC;AAAxB,gHAAA,OAAO,OAAA"}
@@ -0,0 +1,55 @@
1
+ import { AbstractAgent, AgentConfig, AgentRunOptions, AgentSnapshot, AgentRunResult, AgentState } from "../../base";
2
+ import { NetworkUtility, OpenAIUtility } from "../../utility";
3
+ import { Memory } from "./Memory";
4
+ /** 智能体类 */
5
+ export declare class Agent extends AbstractAgent {
6
+ /** 智能体配置 */
7
+ readonly config: AgentConfig;
8
+ /** 记忆管理器(消息缓存 + 草稿区 + 上下文优化) */
9
+ readonly memory: Memory;
10
+ /** 运行状态 */
11
+ private _state;
12
+ /** 对话轮次 */
13
+ private _turnCount;
14
+ /** 当前 run() 的执行选项 */
15
+ private _runOptions?;
16
+ /** 构造函数 */
17
+ constructor(config: AgentConfig);
18
+ /** 当前状态 */
19
+ get state(): AgentState;
20
+ /** 对话轮次 */
21
+ get turnCount(): number;
22
+ /** 思考模式是否开启 */
23
+ get thinkingEnabled(): boolean;
24
+ /** @internal 发送用户消息(缓存→发送→缓存回复) */
25
+ sendUserMessage(content: string): Promise<NetworkUtility.HTTP.Response<OpenAIUtility.OpenAI.ChatResponse>>;
26
+ /** @internal 发送当前消息缓存 */
27
+ sendRequest(): Promise<NetworkUtility.HTTP.Response<OpenAIUtility.OpenAI.ChatResponse>>;
28
+ /** 发送消息缓存中的消息到LLM */
29
+ protected OnSendRequest(overrides?: Partial<OpenAIUtility.OpenAI.ChatRequest>): Promise<NetworkUtility.HTTP.Response<OpenAIUtility.OpenAI.ChatResponse>>;
30
+ /** 发送用户消息(自动缓存用户消息和助手回复) */
31
+ protected OnSend(content: string): Promise<NetworkUtility.HTTP.Response<OpenAIUtility.OpenAI.ChatResponse>>;
32
+ /** 模型基础请求(HTTP POST) */
33
+ OnBaseRequest(apiKey: string, chatRequest: OpenAIUtility.OpenAI.ChatRequest): Promise<NetworkUtility.HTTP.Response<OpenAIUtility.OpenAI.ChatResponse>>;
34
+ /** @internal 执行工具调用(含缓存+重试) */
35
+ executeTool(toolCall: OpenAIUtility.OpenAI.ToolResponse): Promise<string>;
36
+ /** @internal 添加工具结果到消息缓存和记忆 */
37
+ addToolResult(result: string, toolCallId: string): void;
38
+ /** @internal 添加助手消息到缓存(含 tool_calls) */
39
+ addAssistantMessage(content: string, toolCalls?: Array<OpenAIUtility.OpenAI.ToolResponse>): void;
40
+ /** @internal 设置运行状态 */
41
+ setState(state: AgentState): void;
42
+ /**
43
+ * 运行 Agent 主循环
44
+ * 1. 发送用户消息
45
+ * 2. 检查响应
46
+ * 3. 如果模型要求工具调用 → 执行工具 → 继续发送
47
+ * 4. 返回最终结果
48
+ */
49
+ run(input: string, options?: AgentRunOptions): Promise<AgentRunResult>;
50
+ /** 导出当前状态为可序列化快照 */
51
+ snapshot(): AgentSnapshot;
52
+ /** 从快照恢复状态(需先构造 Agent 再调用此方法) */
53
+ restore(snapshot: AgentSnapshot): void;
54
+ }
55
+ //# sourceMappingURL=Agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Agent.d.ts","sourceRoot":"","sources":["../../../src/module/AgentModule/Agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAiB,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAkB,MAAM,UAAU,CAAC;AAElD,WAAW;AACX,qBAAa,KAAM,SAAQ,aAAa;IAEpC,YAAY;IACZ,SAAgB,MAAM,EAAE,WAAW,CAAC;IACpC,gCAAgC;IAChC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,WAAW;IACX,OAAO,CAAC,MAAM,CAA+B;IAC7C,WAAW;IACX,OAAO,CAAC,UAAU,CAAa;IAC/B,qBAAqB;IACrB,OAAO,CAAC,WAAW,CAAC,CAAkB;IAEtC,WAAW;gBACQ,MAAM,EAAE,WAAW;IAMtC,WAAW;IACX,IAAW,KAAK,IAAI,UAAU,CAAwB;IACtD,WAAW;IACX,IAAW,SAAS,IAAI,MAAM,CAA4B;IAC1D,eAAe;IACf,IAAW,eAAe,IAAI,OAAO,CAA+C;IAIpF,mCAAmC;IACtB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAIvH,yBAAyB;IACZ,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAIpG,qBAAqB;cACL,aAAa,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAuC9J,4BAA4B;cACZ,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAYjH,wBAAwB;IACX,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAiBnK,+BAA+B;IAClB,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAKtF,+BAA+B;IACxB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAM9D,wCAAwC;IACjC,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI;IAKvG,uBAAuB;IAChB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IASxC;;;;;;OAMG;IACU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IA0EnF,oBAAoB;IACb,QAAQ,IAAI,aAAa;IAuBhC,iCAAiC;IAC1B,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;CAUhD"}