增加了新的会话记忆方式 fixed #3
This commit is contained in:
parent
69864b26e3
commit
894f6dd0ef
@ -5,8 +5,11 @@ DIFY_API_KEYS=app-xxxxxxxxxxxxxxxx,app-yyyyyyyyyyyyyyyy,app-zzzzzzzzzzzzzzzz
|
||||
# Dify API Base URL
|
||||
DIFY_API_BASE="https://api.dify.example.com/v1"
|
||||
|
||||
# Keep Conversation(true/false)
|
||||
ENABLE_CONVERSATION_MEMORY=true
|
||||
# 会话记忆功能模式
|
||||
# 0: 不开启会话记忆
|
||||
# 1: 构造history_message附加到消息中的模式
|
||||
# 2: 当前的零宽字符模式(默认)
|
||||
CONVERSATION_MEMORY_MODE=2
|
||||
|
||||
# Server Configuration
|
||||
SERVER_HOST="127.0.0.1"
|
||||
|
||||
20
README.md
20
README.md
@ -136,21 +136,25 @@ for chunk in response:
|
||||
|
||||
### 会话记忆功能
|
||||
|
||||
该代理支持自动记忆会话上下文,无需客户端进行额外处理。当启用此功能时:
|
||||
该代理支持自动记忆会话上下文,无需客户端进行额外处理。提供了三种会话记忆模式:
|
||||
|
||||
- 在每个新会话的第一条回复中,会自动嵌入不可见的会话ID
|
||||
- 后续的消息会自动继承会话上下文,保持对话连贯性
|
||||
- 使用零宽字符编码,(大部分情况下)不会影响消息的正常显示
|
||||
1. **不开启会话记忆**:每次对话都是独立的,无上下文关联
|
||||
2. **history_message模式**:将历史消息直接附加到当前消息中,支持客户端编辑历史消息
|
||||
3. **零宽字符模式**:在每个新会话的第一条回复中,会自动嵌入不可见的会话ID,后续消息自动继承上下文
|
||||
|
||||
可以通过环境变量控制此功能:
|
||||
|
||||
```shell
|
||||
# 在 .env 文件中设置
|
||||
ENABLE_CONVERSATION_MEMORY=true # 启用会话记忆功能
|
||||
ENABLE_CONVERSATION_MEMORY=false # 禁用会话记忆功能
|
||||
# 在 .env 文件中设置会话记忆模式
|
||||
# 0: 不开启会话记忆
|
||||
# 1: 构造history_message附加到消息中的模式
|
||||
# 2: 当前的零宽字符模式(默认)
|
||||
CONVERSATION_MEMORY_MODE=2
|
||||
```
|
||||
|
||||
默认情况下此功能是启用的。如果您的应用场景不需要保持会话上下文,可以选择关闭此功能。
|
||||
默认情况下使用零宽字符模式。对于需要支持客户端编辑历史消息的场景,推荐使用history_message模式。
|
||||
|
||||
> 注意:history_message模式会将所有历史消息追加到当前消息中,可能会消耗更多的token。
|
||||
|
||||
### 流式输出优化
|
||||
|
||||
|
||||
80
main.py
80
main.py
@ -24,8 +24,11 @@ load_dotenv()
|
||||
# 从环境变量读取有效的API密钥(逗号分隔)
|
||||
VALID_API_KEYS = [key.strip() for key in os.getenv("VALID_API_KEYS", "").split(",") if key]
|
||||
|
||||
# 获取会话ID记忆功能开关配置
|
||||
ENABLE_CONVERSATION_MEMORY = os.getenv('ENABLE_CONVERSATION_MEMORY', 'true').lower() == 'true'
|
||||
# 获取会话记忆功能模式配置
|
||||
# 0: 不开启会话记忆
|
||||
# 1: 构造history_message附加到消息中的模式
|
||||
# 2: 当前的零宽字符模式(默认)
|
||||
CONVERSATION_MEMORY_MODE = int(os.getenv('CONVERSATION_MEMORY_MODE', '2'))
|
||||
|
||||
class DifyModelManager:
|
||||
def __init__(self):
|
||||
@ -117,23 +120,56 @@ def transform_openai_to_dify(openai_request, endpoint):
|
||||
|
||||
# 尝试从历史消息中提取conversation_id
|
||||
conversation_id = None
|
||||
if len(messages) > 1:
|
||||
# 遍历历史消息,找到最近的assistant消息
|
||||
for msg in reversed(messages[:-1]): # 除了最后一条消息
|
||||
if msg.get("role") == "assistant":
|
||||
content = msg.get("content", "")
|
||||
# 尝试解码conversation_id
|
||||
conversation_id = decode_conversation_id(content)
|
||||
if conversation_id:
|
||||
break
|
||||
|
||||
dify_request = {
|
||||
"inputs": {},
|
||||
"query": messages[-1]["content"] if messages else "",
|
||||
"response_mode": "streaming" if stream else "blocking",
|
||||
"conversation_id": conversation_id,
|
||||
"user": openai_request.get("user", "default_user")
|
||||
}
|
||||
if CONVERSATION_MEMORY_MODE == 2: # 零宽字符模式
|
||||
if len(messages) > 1:
|
||||
# 遍历历史消息,找到最近的assistant消息
|
||||
for msg in reversed(messages[:-1]): # 除了最后一条消息
|
||||
if msg.get("role") == "assistant":
|
||||
content = msg.get("content", "")
|
||||
# 尝试解码conversation_id
|
||||
conversation_id = decode_conversation_id(content)
|
||||
if conversation_id:
|
||||
break
|
||||
|
||||
dify_request = {
|
||||
"inputs": {},
|
||||
"query": messages[-1]["content"] if messages else "",
|
||||
"response_mode": "streaming" if stream else "blocking",
|
||||
"conversation_id": conversation_id,
|
||||
"user": openai_request.get("user", "default_user")
|
||||
}
|
||||
elif CONVERSATION_MEMORY_MODE == 1: # history_message模式
|
||||
# 使用history_messages直接作为上下文
|
||||
user_query = messages[-1]["content"] if messages else ""
|
||||
|
||||
if len(messages) > 1:
|
||||
# 构造历史消息
|
||||
history_messages = []
|
||||
for msg in messages[:-1]: # 除了最后一条消息
|
||||
role = msg.get("role", "")
|
||||
content = msg.get("content", "")
|
||||
if role and content:
|
||||
history_messages.append(f"{role}: {content}")
|
||||
|
||||
# 将历史消息添加到查询中
|
||||
if history_messages:
|
||||
history_context = "\n\n".join(history_messages)
|
||||
user_query = f"<history>\n{history_context}\n</history>\n\n用户当前问题: {user_query}"
|
||||
|
||||
dify_request = {
|
||||
"inputs": {},
|
||||
"query": user_query,
|
||||
"response_mode": "streaming" if stream else "blocking",
|
||||
"user": openai_request.get("user", "default_user")
|
||||
}
|
||||
else: # 不开启会话记忆
|
||||
dify_request = {
|
||||
"inputs": {},
|
||||
"query": messages[-1]["content"] if messages else "",
|
||||
"response_mode": "streaming" if stream else "blocking",
|
||||
"user": openai_request.get("user", "default_user")
|
||||
}
|
||||
|
||||
return dify_request
|
||||
|
||||
@ -145,8 +181,8 @@ def transform_dify_to_openai(dify_response, model="claude-3-5-sonnet-v2", stream
|
||||
if not stream:
|
||||
answer = dify_response.get("answer", "")
|
||||
|
||||
# 只在启用会话记忆功能时处理conversation_id
|
||||
if ENABLE_CONVERSATION_MEMORY:
|
||||
# 只在零宽字符会话记忆模式时处理conversation_id
|
||||
if CONVERSATION_MEMORY_MODE == 2:
|
||||
conversation_id = dify_response.get("conversation_id", "")
|
||||
history = dify_response.get("conversation_history", [])
|
||||
|
||||
@ -495,8 +531,8 @@ def chat_completions():
|
||||
yield send_char(char, msg_id)
|
||||
time.sleep(0.001) # 固定使用最小延迟快速输出剩余内容
|
||||
|
||||
# 只在启用会话记忆功能时处理conversation_id
|
||||
if ENABLE_CONVERSATION_MEMORY:
|
||||
# 只在零宽字符会话记忆模式时处理conversation_id
|
||||
if CONVERSATION_MEMORY_MODE == 2:
|
||||
conversation_id = dify_chunk.get("conversation_id")
|
||||
history = dify_chunk.get("conversation_history", [])
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user