6 changed files with 540 additions and 36 deletions
@ -0,0 +1,138 @@ |
|||
import json |
|||
import time |
|||
from typing import Dict, List, Optional, Callable, Any |
|||
from enum import Enum |
|||
from dataclasses import dataclass, asdict |
|||
from datetime import datetime |
|||
|
|||
|
|||
class MessageType(Enum): |
|||
"""消息类型枚举""" |
|||
SEARCH = "search" |
|||
THINK = "think" |
|||
ANSWER = "answer" |
|||
|
|||
|
|||
@dataclass |
|||
class Message: |
|||
"""消息数据结构""" |
|||
type: MessageType |
|||
content: str |
|||
timestamp: float |
|||
metadata: Optional[Dict[str, Any]] = None |
|||
|
|||
def to_dict(self) -> Dict[str, Any]: |
|||
"""转换为字典格式""" |
|||
return { |
|||
"type": self.type.value, |
|||
"content": self.content, |
|||
"timestamp": self.timestamp, |
|||
"metadata": self.metadata or {} |
|||
} |
|||
|
|||
def to_json(self) -> str: |
|||
"""转换为JSON字符串""" |
|||
return json.dumps(self.to_dict(), ensure_ascii=False) |
|||
|
|||
|
|||
class MessageStream: |
|||
"""消息流管理器""" |
|||
|
|||
def __init__(self): |
|||
self._messages: List[Message] = [] |
|||
self._callbacks: List[Callable[[Message], None]] = [] |
|||
self._enabled = True |
|||
|
|||
def add_callback(self, callback: Callable[[Message], None]): |
|||
"""添加消息回调函数""" |
|||
self._callbacks.append(callback) |
|||
|
|||
def remove_callback(self, callback: Callable[[Message], None]): |
|||
"""移除消息回调函数""" |
|||
if callback in self._callbacks: |
|||
self._callbacks.remove(callback) |
|||
|
|||
def enable(self): |
|||
"""启用消息流""" |
|||
self._enabled = True |
|||
|
|||
def disable(self): |
|||
"""禁用消息流""" |
|||
self._enabled = False |
|||
|
|||
def send_message(self, msg_type: MessageType, content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""发送消息""" |
|||
if not self._enabled: |
|||
return |
|||
|
|||
message = Message( |
|||
type=msg_type, |
|||
content=content, |
|||
timestamp=time.time(), |
|||
metadata=metadata |
|||
) |
|||
|
|||
self._messages.append(message) |
|||
|
|||
# 调用所有回调函数 |
|||
for callback in self._callbacks: |
|||
try: |
|||
callback(message) |
|||
except Exception as e: |
|||
print(f"Error in message callback: {e}") |
|||
|
|||
def send_search(self, content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""发送搜索消息""" |
|||
self.send_message(MessageType.SEARCH, content, metadata) |
|||
|
|||
def send_think(self, content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""发送思考消息""" |
|||
self.send_message(MessageType.THINK, content, metadata) |
|||
|
|||
def send_answer(self, content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""发送答案消息""" |
|||
self.send_message(MessageType.ANSWER, content, metadata) |
|||
|
|||
def get_messages(self) -> List[Message]: |
|||
"""获取所有消息""" |
|||
return self._messages.copy() |
|||
|
|||
def get_messages_by_type(self, msg_type: MessageType) -> List[Message]: |
|||
"""根据类型获取消息""" |
|||
return [msg for msg in self._messages if msg.type == msg_type] |
|||
|
|||
def clear_messages(self): |
|||
"""清空所有消息""" |
|||
self._messages.clear() |
|||
|
|||
def get_messages_as_dicts(self) -> List[Dict[str, Any]]: |
|||
"""获取所有消息的字典格式""" |
|||
return [msg.to_dict() for msg in self._messages] |
|||
|
|||
def get_messages_as_json(self) -> str: |
|||
"""获取所有消息的JSON格式""" |
|||
return json.dumps(self.get_messages_as_dicts(), ensure_ascii=False) |
|||
|
|||
|
|||
# 全局消息流实例 |
|||
message_stream = MessageStream() |
|||
|
|||
|
|||
def send_search(content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""全局搜索消息发送函数""" |
|||
message_stream.send_search(content, metadata) |
|||
|
|||
|
|||
def send_think(content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""全局思考消息发送函数""" |
|||
message_stream.send_think(content, metadata) |
|||
|
|||
|
|||
def send_answer(content: str, metadata: Optional[Dict[str, Any]] = None): |
|||
"""全局答案消息发送函数""" |
|||
message_stream.send_answer(content, metadata) |
|||
|
|||
|
|||
def get_message_stream() -> MessageStream: |
|||
"""获取全局消息流实例""" |
|||
return message_stream |
@ -0,0 +1,197 @@ |
|||
# 消息流系统 (Message Stream System) |
|||
|
|||
## 概述 |
|||
|
|||
DeepSearcher 的消息流系统是一个新的消息传输机制,用于替代原来的日志传输方式。该系统支持三种类型的消息:`search`、`think` 和 `answer`,并提供了灵活的消息管理和传输功能。 |
|||
|
|||
## 消息类型 |
|||
|
|||
### 1. Search 消息 |
|||
- **类型**: `search` |
|||
- **用途**: 表示搜索相关的操作和状态 |
|||
- **示例**: |
|||
- "在向量数据库中搜索相关信息..." |
|||
- "找到5个相关文档片段" |
|||
- "搜索人工智能的定义..." |
|||
|
|||
### 2. Think 消息 |
|||
- **类型**: `think` |
|||
- **用途**: 表示思考和推理过程 |
|||
- **示例**: |
|||
- "开始处理查询: 什么是人工智能?" |
|||
- "分析搜索结果..." |
|||
- "生成子查询: 人工智能的定义、历史、应用" |
|||
|
|||
### 3. Answer 消息 |
|||
- **类型**: `answer` |
|||
- **用途**: 表示最终答案和结果 |
|||
- **示例**: |
|||
- "==== FINAL ANSWER====" |
|||
- "人工智能是计算机科学的一个分支..." |
|||
|
|||
## 核心组件 |
|||
|
|||
### MessageStream 类 |
|||
|
|||
主要的消息流管理器,提供以下功能: |
|||
|
|||
```python |
|||
from deepsearcher.utils.message_stream import MessageStream |
|||
|
|||
# 创建消息流实例 |
|||
message_stream = MessageStream() |
|||
|
|||
# 发送消息 |
|||
message_stream.send_search("搜索内容...") |
|||
message_stream.send_think("思考内容...") |
|||
message_stream.send_answer("答案内容...") |
|||
|
|||
# 获取消息 |
|||
messages = message_stream.get_messages() |
|||
messages_dict = message_stream.get_messages_as_dicts() |
|||
messages_json = message_stream.get_messages_as_json() |
|||
``` |
|||
|
|||
### 全局函数 |
|||
|
|||
为了方便使用,提供了全局函数: |
|||
|
|||
```python |
|||
from deepsearcher.utils.message_stream import send_search, send_think, send_answer |
|||
|
|||
# 直接发送消息 |
|||
send_search("搜索内容...") |
|||
send_think("思考内容...") |
|||
send_answer("答案内容...") |
|||
``` |
|||
|
|||
## API 接口 |
|||
|
|||
### 1. 获取消息 |
|||
``` |
|||
GET /messages/ |
|||
``` |
|||
|
|||
返回所有消息的列表: |
|||
```json |
|||
{ |
|||
"messages": [ |
|||
{ |
|||
"type": "search", |
|||
"content": "搜索内容...", |
|||
"timestamp": 1755043653.9606102, |
|||
"metadata": {} |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
### 2. 清空消息 |
|||
``` |
|||
POST /clear-messages/ |
|||
``` |
|||
|
|||
清空所有消息并返回成功状态: |
|||
```json |
|||
{ |
|||
"message": "Messages cleared successfully" |
|||
} |
|||
``` |
|||
|
|||
### 3. 查询接口(已更新) |
|||
``` |
|||
GET /query/?original_query=<query>&max_iter=<iterations> |
|||
``` |
|||
|
|||
现在返回结果包含消息流: |
|||
```json |
|||
{ |
|||
"result": "最终答案...", |
|||
"messages": [ |
|||
{ |
|||
"type": "search", |
|||
"content": "搜索内容...", |
|||
"timestamp": 1755043653.9606102, |
|||
"metadata": {} |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
## 前端集成 |
|||
|
|||
前端界面现在包含一个消息流显示区域,实时显示处理过程中的各种消息: |
|||
|
|||
### CSS 样式 |
|||
- `.message-search`: 搜索消息样式(蓝色边框) |
|||
- `.message-think`: 思考消息样式(黄色边框) |
|||
- `.message-answer`: 答案消息样式(绿色边框) |
|||
|
|||
### JavaScript 功能 |
|||
- `displayMessages(messages)`: 显示消息流 |
|||
- 自动滚动到最新消息 |
|||
- 时间戳显示 |
|||
|
|||
## 使用示例 |
|||
|
|||
### 后端使用 |
|||
|
|||
```python |
|||
from deepsearcher.utils.message_stream import send_search, send_think, send_answer |
|||
|
|||
# 在搜索过程中发送消息 |
|||
send_think("开始处理查询...") |
|||
send_search("在数据库中搜索...") |
|||
send_search("找到相关文档...") |
|||
send_think("分析结果...") |
|||
send_answer("最终答案...") |
|||
``` |
|||
|
|||
### 前端使用 |
|||
|
|||
```javascript |
|||
// 获取消息 |
|||
const response = await fetch('/query/?original_query=test&max_iter=3'); |
|||
const data = await response.json(); |
|||
|
|||
// 显示消息流 |
|||
if (data.messages && data.messages.length > 0) { |
|||
displayMessages(data.messages); |
|||
} |
|||
``` |
|||
|
|||
## 优势 |
|||
|
|||
1. **结构化数据**: 消息包含类型、内容、时间戳和元数据 |
|||
2. **类型安全**: 使用枚举确保消息类型的一致性 |
|||
3. **灵活传输**: 支持多种输出格式(字典、JSON) |
|||
4. **实时显示**: 前端可以实时显示处理过程 |
|||
5. **易于扩展**: 可以轻松添加新的消息类型和功能 |
|||
|
|||
## 迁移说明 |
|||
|
|||
从原来的日志系统迁移到新的消息流系统: |
|||
|
|||
### 原来的代码 |
|||
```python |
|||
log.color_print(f"<search> Search [{query}] in [{collection}]... </search>\n") |
|||
log.color_print(f"<think> Summarize answer... </think>\n") |
|||
log.color_print(f"<answer> Final answer... </answer>\n") |
|||
``` |
|||
|
|||
### 新的代码 |
|||
```python |
|||
send_search(f"Search [{query}] in [{collection}]...") |
|||
send_think("Summarize answer...") |
|||
send_answer("Final answer...") |
|||
``` |
|||
|
|||
## 测试 |
|||
|
|||
运行测试脚本验证系统功能: |
|||
|
|||
```bash |
|||
python test_message_stream.py |
|||
``` |
|||
|
|||
这将测试消息流的基本功能,包括消息发送、获取和格式化。 |
@ -0,0 +1,31 @@ |
|||
#!/usr/bin/env python3 |
|||
""" |
|||
测试迭代逻辑的脚本 |
|||
""" |
|||
|
|||
def test_iteration_logic(): |
|||
"""测试迭代逻辑""" |
|||
max_iter = 3 |
|||
|
|||
print(f"测试最大迭代次数: {max_iter}") |
|||
print("-" * 40) |
|||
|
|||
for it in range(max_iter): |
|||
print(f">> Iteration: {it + 1}") |
|||
|
|||
# 模拟搜索任务 |
|||
print(" 执行搜索任务...") |
|||
|
|||
# 检查是否达到最大迭代次数 |
|||
if it + 1 < max_iter: |
|||
print(" 反思并生成新的子查询...") |
|||
print(" 准备下一次迭代") |
|||
else: |
|||
print(" 达到最大迭代次数,退出") |
|||
break |
|||
|
|||
print("-" * 40) |
|||
print("测试完成!") |
|||
|
|||
if __name__ == "__main__": |
|||
test_iteration_logic() |
Loading…
Reference in new issue