feat: protocol base lib + rule-based parser MVP + 31 tests
This commit is contained in:
@ -147,9 +147,9 @@ LIMIT 10
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| **输入1** | 查询张量(来自 Core,含查询意图、种子实体、上下文) |
|
||||
| **输入2** | 新信息张量(来自 Core,含本轮标签和子网结果;**不含具体写入指令**) |
|
||||
| **输出** | `memory_result` 张量(包含检索到的实体/关系/向量结果) |
|
||||
| **输入1** | 查询张量,fmt_id=2,来自 Core(编码后的查询意图、种子实体) |
|
||||
| **输入2** | 新信息张量,fmt_id=3,来自 Core(编码后的本轮更新数据;**不含具体写入指令**) |
|
||||
| **输出** | 记忆结果张量,fmt_id=1,编码检索到的实体/关系向量 |
|
||||
| **自治** | 记忆子网自行决定如何写入、更新、删除、修改记忆 |
|
||||
|
||||
## 训练目标
|
||||
@ -301,37 +301,63 @@ class Neo4jGraph:
|
||||
|
||||
## 新信息张量格式
|
||||
|
||||
Core 传递给记忆子网的**新信息张量**(Core 不发送
|
||||
Core 传递给记忆子网的**新信息张量**遵循统一通信张量协议:
|
||||
|
||||
```json
|
||||
{
|
||||
"header": {
|
||||
"source": "core",
|
||||
"target": "memory",
|
||||
"tensor_type": "memory_update",
|
||||
"trace_id": "trace-uuid",
|
||||
"timestamp": 1717200000
|
||||
},
|
||||
"payload": {
|
||||
### 协议定义
|
||||
|
||||
```
|
||||
格式: 统一通信张量 (纯数值张量)
|
||||
prefix[0] = fmt_id = 3 (memory_update)
|
||||
prefix[1] = parser_id = 3 (memory_update_parser)
|
||||
payload: 编码后的记忆更新数据
|
||||
实体编码: [entity_ids..., entity_embeddings...]
|
||||
关系编码: [relation_ids..., relation_embeddings...]
|
||||
会话标识: [session_tag, turn_tag, ...]
|
||||
```
|
||||
|
||||
实体、关系、会话信息通过子网内部的编解码适配器转为张量表示。
|
||||
|
||||
### 记忆子网内部格式(私有)
|
||||
|
||||
记忆子网内部维护以下私有数据结构,但**对外通信时始终通过统一协议编解码为纯张量**:
|
||||
|
||||
```python
|
||||
# 内部数据模型(子网私有,不对外暴露)
|
||||
@Entity
|
||||
default_graph = {
|
||||
"entities": [
|
||||
{"name": "用户_张三", "type": "PersonaNode", "attributes": {"preference": "摇滚音乐"}},
|
||||
{"name": "项目_NextAgent", "type": "EntityNode", "attributes": {}}
|
||||
{"name": "用户_张三", "type": "PersonaNode", "preference": "摇滚音乐"},
|
||||
{"name": "项目_NextAgent", "type": "EntityNode"}
|
||||
],
|
||||
"relations": [
|
||||
{"subject": "用户_张三", "relation": "HAS_PERSONA", "object": "喜欢_摇滚", "confidence": 0.95},
|
||||
{"subject": "用户_张三", "relation": "RELATES_TO", "object": "项目_NextAgent", "confidence": 0.9}
|
||||
],
|
||||
"session_id": "session-20260601-xxxx",
|
||||
"turn_id": 42,
|
||||
"metadata": {
|
||||
"source_subnets": ["routing", "logic_trace", "core"],
|
||||
"aggregation_strategy": "merge"
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"entity_count": 3,
|
||||
"relation_count": 2,
|
||||
"upsert_mode": "merge"
|
||||
}
|
||||
{"subject": "用户_张三", "relation": "HAS_PERSONA", "object": "喜欢_摇滚", "confidence": 0.95},
|
||||
{"subject": "用户_张三", "relation": "RELATES_TO", "object": "项目_NextAgent", "confidence": 0.9}
|
||||
]
|
||||
}
|
||||
|
||||
# 编码适配器将内部数据 → 统一通信张量
|
||||
# 解码适配器将统一通信张量 → 内部查询结构
|
||||
def encode_memory_update(entities, relations, session_id, turn_id) -> Tensor:
|
||||
"""内部格式 → 统一通信张量
|
||||
|
||||
1. 将实体名/关系名编码为 embedding 向量
|
||||
2. 拼接会话标识和时间戳
|
||||
3. 编码适配器: 查表 fmt_id=3, 拼接前缀
|
||||
"""
|
||||
entity_embeds = embed_entity_names(entities) # [n_entities, 768]
|
||||
relation_embeds = encode_relations(relations) # [n_relations, 768]
|
||||
meta = tensor([session_hash, turn_id]) # [2]
|
||||
return codec.encode(fmt_id=3, parser_id=3,
|
||||
data=concat(entity_embeds, relation_embeds, meta))
|
||||
|
||||
def decode_memory_query(comm_tensor: Tensor) -> QueryIntent:
|
||||
"""统一通信张量 → 内部查询意图
|
||||
|
||||
1. codec.decode(comm_tensor) 剥离前缀
|
||||
2. 将 payload 张量解码为查询条件
|
||||
3. 返回: 图DB检索参数 / 向量检索参数
|
||||
"""
|
||||
payload = codec.decode(comm_tensor) # 剥离 fmt_id=2
|
||||
query_embed = payload[:768]
|
||||
return self.query_embed_to_params(query_embed)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user