@smyslenny/agent-memory 4.2.0 → 4.3.1
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.
- package/README.md +1 -1
- package/dist/bin/agent-memory.js +66 -9
- package/dist/bin/agent-memory.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +65 -9
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +66 -9
- package/dist/mcp/server.js.map +1 -1
- package/package.json +2 -2
- package/docs/design/.next-id +0 -1
- package/docs/design/0004-agent-memory-integration.md +0 -316
- package/docs/design/0005-reranker-api-integration.md +0 -276
- package/docs/design/0006-multi-provider-embedding.md +0 -196
- package/docs/design/0014-memory-core-dedup.md +0 -722
- package/docs/design/0015-v4-overhaul.md +0 -631
- package/docs/design/0016-v41-warm-boot-surface-emotion.md +0 -228
- package/docs/design/TEMPLATE.md +0 -67
- package/docs/roadmap/integration-plan-v1.md +0 -139
- package/docs/roadmap/memory-architecture.md +0 -168
- package/docs/roadmap/warm-boot.md +0 -135
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# DD-0006: Multi-Provider Embedding + Instruction-Aware Query
|
|
2
|
-
|
|
3
|
-
**Status:** Draft
|
|
4
|
-
**Author:** Noah (Claude Opus)
|
|
5
|
-
**Date:** 2026-02-22
|
|
6
|
-
**Repo:** agent-memory
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 1. Background / 背景
|
|
11
|
-
|
|
12
|
-
agent-memory v2.1.0 的 embedding provider 目前只支持 `openai`(OpenAI 兼容 API)和 `dashscope`(通义专用 API)两种 provider,且 query embedding 时不带任何 instruction prefix。
|
|
13
|
-
|
|
14
|
-
### 基准测试结果(2026-02-22,12 题中文困难检索集)
|
|
15
|
-
|
|
16
|
-
| 模型 | 模式 | Hit@1 | MRR | 延迟 |
|
|
17
|
-
|------|------|-------|-----|------|
|
|
18
|
-
| gemini-embedding-001 | plain | **91.7%** | **0.9583** | 430ms |
|
|
19
|
-
| gemini-embedding-001 | instruction | 83.3% ↓ | 0.9167 ↓ | 418ms |
|
|
20
|
-
| Qwen3-Embedding-8B | plain | 66.7% | 0.8333 | 804ms |
|
|
21
|
-
| Qwen3-Embedding-8B | instruction | **91.7%** | **0.9583** | 857ms |
|
|
22
|
-
|
|
23
|
-
**关键发现:**
|
|
24
|
-
1. Qwen3 加 instruction prefix 后 Hit@1 从 66.7% → 91.7%(+25%),追平 Gemini
|
|
25
|
-
2. Gemini 加 instruction 反而下降 91.7% → 83.3%(-8.4%),不应该给它加
|
|
26
|
-
3. 不同模型需要不同的 instruction 策略,不能一刀切
|
|
27
|
-
|
|
28
|
-
### 当前问题
|
|
29
|
-
1. `providers.ts` 中没有 `gemini` provider(只能用 `openai` 兼容模式凑合)
|
|
30
|
-
2. embed() 不支持 instruction prefix,Qwen3 无法发挥全部实力
|
|
31
|
-
3. 没有模型感知的 instruction 策略(该加的不加,不该加的加了都会出问题)
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 2. Goals / 目标
|
|
36
|
-
|
|
37
|
-
- 在 `providers.ts` 中为 Gemini 新增专用 provider 支持(`AGENT_MEMORY_EMBEDDINGS_PROVIDER=gemini`),通过 OpenAI 兼容端点
|
|
38
|
-
- 为 `EmbeddingProvider` 接口新增可选的 `instructionPrefix` 字段
|
|
39
|
-
- 实现模型感知的 instruction 策略:Qwen 系列自动加 instruction prefix,Gemini 系列不加
|
|
40
|
-
- 更新 `getEmbeddingProviderFromEnv()` 支持 `gemini` provider 类型
|
|
41
|
-
- 新增环境变量 `AGENT_MEMORY_EMBEDDINGS_INSTRUCTION` 允许用户自定义或禁用 instruction
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 3. Non-Goals / 非目标
|
|
46
|
-
|
|
47
|
-
- 不改变 hybrid search / rerank 逻辑(DD-0005 刚完成的)
|
|
48
|
-
- 不改变数据库 schema 或 embeddings 表结构
|
|
49
|
-
- 不支持 Gemini 原生 API(用 OpenAI 兼容端点即可,因为我们走 momo)
|
|
50
|
-
- 不引入 A/B 测试框架
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 4. Proposal / 方案
|
|
55
|
-
|
|
56
|
-
### 4.1 方案概述
|
|
57
|
-
|
|
58
|
-
核心思路:让 `EmbeddingProvider.embed(text)` 在内部根据模型类型自动决定是否给 query 加上 instruction prefix。
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
用户调用 embed("害怕失去重要的人")
|
|
62
|
-
↓
|
|
63
|
-
Provider 检查 instructionPrefix 配置
|
|
64
|
-
↓
|
|
65
|
-
Qwen → "Instruct: Given a query, retrieve the most semantically relevant document\nQuery: 害怕失去重要的人"
|
|
66
|
-
Gemini → "害怕失去重要的人"(原样发送)
|
|
67
|
-
↓
|
|
68
|
-
调用 API → 返回向量
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### 4.2 详细设计
|
|
72
|
-
|
|
73
|
-
#### 4.2.1 修改 `EmbeddingProvider` 接口
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
export interface EmbeddingProvider {
|
|
77
|
-
id: string;
|
|
78
|
-
model: string;
|
|
79
|
-
dimension?: number;
|
|
80
|
-
instructionPrefix?: string | null; // null = 不加; string = 自动前缀
|
|
81
|
-
embed(text: string): Promise<number[]>;
|
|
82
|
-
embedQuery?(query: string): Promise<number[]>; // 带 instruction 的 query embedding
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
新增 `embedQuery()` 方法:
|
|
87
|
-
- 如果有 `instructionPrefix`,自动拼接 `Instruct: {prefix}\nQuery: {text}` 再调 API
|
|
88
|
-
- 如果没有,退化为普通 `embed(text)`
|
|
89
|
-
- `embed()` 始终是 plain 模式(用于 document embedding,不加 instruction)
|
|
90
|
-
|
|
91
|
-
#### 4.2.2 模型感知的 instruction 策略
|
|
92
|
-
|
|
93
|
-
在 `getEmbeddingProviderFromEnv()` 中,根据模型名自动判断:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
function getDefaultInstruction(model: string): string | null {
|
|
97
|
-
const m = model.toLowerCase();
|
|
98
|
-
// Qwen 系列:需要 instruction
|
|
99
|
-
if (m.includes("qwen")) {
|
|
100
|
-
return "Given a query, retrieve the most semantically relevant document";
|
|
101
|
-
}
|
|
102
|
-
// Gemini 系列:不需要 instruction(加了反而变差)
|
|
103
|
-
if (m.includes("gemini")) {
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
// 其他模型:默认不加(安全策略)
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
用户可通过环境变量 `AGENT_MEMORY_EMBEDDINGS_INSTRUCTION` 强制覆盖:
|
|
112
|
-
- `"none"` / `"off"` → 禁用
|
|
113
|
-
- 其他字符串 → 使用该字符串作为 instruction
|
|
114
|
-
- 未设置 → 走模型自动检测
|
|
115
|
-
|
|
116
|
-
#### 4.2.3 新增 `gemini` provider 类型
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
if (provider === "gemini" || provider === "google") {
|
|
120
|
-
const apiKey = process.env.GEMINI_API_KEY ?? process.env.OPENAI_API_KEY;
|
|
121
|
-
const model = process.env.AGENT_MEMORY_EMBEDDINGS_MODEL ?? "gemini-embedding-001";
|
|
122
|
-
const baseUrl = process.env.GEMINI_BASE_URL ?? process.env.OPENAI_BASE_URL ?? "https://generativelanguage.googleapis.com/v1beta";
|
|
123
|
-
if (!apiKey) return null;
|
|
124
|
-
return createOpenAIProvider({ apiKey, model, baseUrl, instruction: null }); // Gemini 不加 instruction
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
注意:由于 momo 的 Gemini 走的是 OpenAI 兼容端点,实际上 `gemini` provider 底层复用 `createOpenAIProvider`,区别仅在默认 model 名和 instruction 策略。
|
|
129
|
-
|
|
130
|
-
#### 4.2.4 修改搜索调用
|
|
131
|
-
|
|
132
|
-
在 `hybrid.ts` 的 `searchHybrid()` 中,query embedding 使用 `embedQuery()` 而非 `embed()`:
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
// Before:
|
|
136
|
-
const qVec = Float32Array.from(await provider.embed(query));
|
|
137
|
-
|
|
138
|
-
// After:
|
|
139
|
-
const embedFn = provider.embedQuery ?? provider.embed;
|
|
140
|
-
const qVec = Float32Array.from(await embedFn.call(provider, query));
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Document embedding(remember 时)继续使用 `embed()`。
|
|
144
|
-
|
|
145
|
-
#### 4.2.5 环境变量
|
|
146
|
-
|
|
147
|
-
| 变量 | 必填 | 默认值 | 说明 |
|
|
148
|
-
|------|------|--------|------|
|
|
149
|
-
| `AGENT_MEMORY_EMBEDDINGS_PROVIDER` | 否 | `"none"` | 新增 `"gemini"` / `"google"` |
|
|
150
|
-
| `AGENT_MEMORY_EMBEDDINGS_MODEL` | 否 | 按 provider 不同 | gemini → `gemini-embedding-001`; openai → `text-embedding-3-small`; qwen → `text-embedding-v3` |
|
|
151
|
-
| `AGENT_MEMORY_EMBEDDINGS_INSTRUCTION` | 否 | 自动检测 | `"none"` 禁用; 自定义字符串覆盖 |
|
|
152
|
-
| `GEMINI_API_KEY` | 否 | 继承 `OPENAI_API_KEY` | Gemini 专用 key(走 momo 时可共用) |
|
|
153
|
-
| `GEMINI_BASE_URL` | 否 | 继承 `OPENAI_BASE_URL` | Gemini 端点 |
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## 5. Risks / 风险
|
|
158
|
-
|
|
159
|
-
| 风险 | 影响 | 缓解措施 |
|
|
160
|
-
|------|------|----------|
|
|
161
|
-
| instruction 对新模型行为未知 | 可能降低精度 | 默认不加(null),只对已验证的 Qwen 加 |
|
|
162
|
-
| embedQuery 与 embed 的向量空间不一致 | document 用 plain、query 用 instruction 可能有偏移 | Qwen 官方推荐此用法;可通过 env 禁用 |
|
|
163
|
-
| 已有 embedding 向量是 plain 模式生成的 | 切换 instruction 后需要 reindex | 文档说明;提供 `agent-memory reindex` 命令 |
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## 6. Test Plan / 测试方案
|
|
168
|
-
|
|
169
|
-
- [ ] Unit test: `getEmbeddingProviderFromEnv()` 对 `gemini`/`google` 类型的处理
|
|
170
|
-
- [ ] Unit test: `getDefaultInstruction()` 对各模型名的返回值
|
|
171
|
-
- [ ] Unit test: `embedQuery()` 正确拼接 instruction prefix
|
|
172
|
-
- [ ] Unit test: `embedQuery()` 在 instruction=null 时退化为 embed()
|
|
173
|
-
- [ ] Integration test: hybrid search 使用 embedQuery 而非 embed
|
|
174
|
-
- [ ] Manual: 对比 reindex 前后搜索结果变化
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 7. Rollback Plan / 回滚方案
|
|
179
|
-
|
|
180
|
-
- 删除 `AGENT_MEMORY_EMBEDDINGS_INSTRUCTION` 环境变量 → 走自动检测
|
|
181
|
-
- 设置 `AGENT_MEMORY_EMBEDDINGS_INSTRUCTION=none` → 完全禁用 instruction
|
|
182
|
-
- 代码层面:`embedQuery` 是新增方法,不影响原有 `embed()`
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## 8. Decision Log / 决策变更记录
|
|
187
|
-
|
|
188
|
-
| 日期 | 变更 | 原因 |
|
|
189
|
-
|------|------|------|
|
|
190
|
-
| 2026-02-22 | Gemini 走 OpenAI 兼容端点而非原生 API | momo 统一用 /v1/embeddings |
|
|
191
|
-
| 2026-02-22 | instruction 策略默认不加(只对 Qwen 加) | 基准测试证实 Gemini 加了反而变差 |
|
|
192
|
-
| 2026-02-22 | embedQuery 作为可选方法而非替换 embed | 保持 document embedding 不受影响 |
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
_Generated by DD workflow · Noah (Claude Opus)_
|