forked from QwenLM/Qwen-Agent
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add memory-related agents: super-long dialogue and virtual memory
- Loading branch information
Showing
19 changed files
with
464 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from qwen_agent.agents import Assistant | ||
from qwen_agent.gui import WebUI | ||
|
||
|
||
def test(): | ||
bot = Assistant(llm={'model': 'qwen-plus'}) | ||
messages = [{'role': 'user', 'content': [{'text': '介绍图一'}, {'file': 'https://arxiv.org/pdf/1706.03762.pdf'}]}] | ||
for rsp in bot.run(messages): | ||
print(rsp) | ||
|
||
|
||
def app_gui(): | ||
# Define the agent | ||
bot = Assistant(llm={'model': 'qwen-plus'}, | ||
name='Assistant', | ||
description='使用RAG检索并回答,支持文件类型:PDF/Word/PPT/TXT/HTML。') | ||
chatbot_config = { | ||
'prompt.suggestions': [ | ||
{ | ||
'text': '介绍图一' | ||
}, | ||
{ | ||
'text': '第二章第一句话是什么?' | ||
}, | ||
] | ||
} | ||
WebUI(bot, chatbot_config=chatbot_config).run() | ||
|
||
|
||
if __name__ == '__main__': | ||
# test() | ||
app_gui() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from qwen_agent.agents import DialogueRetrievalAgent | ||
from qwen_agent.gui import WebUI | ||
|
||
|
||
def test(): | ||
# Define the agent | ||
bot = DialogueRetrievalAgent(llm={'model': 'qwen-max'}) | ||
|
||
# Chat | ||
long_text = ','.join(['这是干扰内容'] * 1000 + ['小明的爸爸叫大头'] + ['这是干扰内容'] * 1000) | ||
messages = [{'role': 'user', 'content': f'小明爸爸叫什么?\n{long_text}'}] | ||
|
||
for response in bot.run(messages): | ||
print('bot response:', response) | ||
|
||
|
||
def app_tui(): | ||
bot = DialogueRetrievalAgent(llm={'model': 'qwen-max'}) | ||
|
||
# Chat | ||
messages = [] | ||
while True: | ||
query = input('user question: ') | ||
messages.append({'role': 'user', 'content': query}) | ||
response = [] | ||
for response in bot.run(messages=messages): | ||
print('bot response:', response) | ||
messages.extend(response) | ||
|
||
|
||
def app_gui(): | ||
# Define the agent | ||
bot = DialogueRetrievalAgent(llm={'model': 'qwen-max'}) | ||
|
||
WebUI(bot).run() | ||
|
||
|
||
if __name__ == '__main__': | ||
# test() | ||
# app_tui() | ||
app_gui() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
"""A retrieval docqa assistant implemented by virtual memory agent""" | ||
|
||
import os | ||
|
||
from qwen_agent.agents import VirtualMemoryAgent | ||
from qwen_agent.gui import WebUI | ||
|
||
ROOT_RESOURCE = os.path.join(os.path.dirname(__file__), 'resource') | ||
|
||
|
||
def init_agent_service(): | ||
llm_cfg = {'model': 'qwen-max'} | ||
system = '一个文档问答助手。' | ||
bot = VirtualMemoryAgent( | ||
llm=llm_cfg, | ||
system_message=system, | ||
) | ||
|
||
return bot | ||
|
||
|
||
def test(query='简单列出这篇文章的贡献https://qianwen-res.oss-cn-beijing.aliyuncs.com/QWEN_TECHNICAL_REPORT.pdf',): | ||
# Define the agent | ||
bot = init_agent_service() | ||
|
||
# Chat | ||
messages = [{'role': 'user', 'content': query}] | ||
|
||
for response in bot.run(messages): | ||
print('bot response:', response) | ||
|
||
|
||
def app_tui(): | ||
# Define the agent | ||
bot = init_agent_service() | ||
|
||
# Chat | ||
messages = [] | ||
while True: | ||
# Query example: 简单列出这篇文章的贡献https://qianwen-res.oss-cn-beijing.aliyuncs.com/QWEN_TECHNICAL_REPORT.pdf | ||
query = input('user question: ') | ||
# File example: resource/poem.pdf | ||
file = input('file url (press enter if no file): ').strip() | ||
if not query: | ||
print('user question cannot be empty!') | ||
continue | ||
if not file: | ||
messages.append({'role': 'user', 'content': query}) | ||
else: | ||
messages.append({'role': 'user', 'content': [{'text': query}, {'file': file}]}) | ||
|
||
response = [] | ||
for response in bot.run(messages): | ||
print('bot response:', response) | ||
messages.extend(response) | ||
|
||
|
||
def app_gui(): | ||
# Define the agent | ||
bot = init_agent_service() | ||
chatbot_config = { | ||
'prompt.suggestions': ['简单列出这篇文章的贡献https://qianwen-res.oss-cn-beijing.aliyuncs.com/QWEN_TECHNICAL_REPORT.pdf'] | ||
} | ||
|
||
WebUI( | ||
bot, | ||
chatbot_config=chatbot_config, | ||
).run() | ||
|
||
|
||
if __name__ == '__main__': | ||
# test() | ||
# app_tui() | ||
app_gui() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import datetime | ||
import os | ||
from typing import Iterator, List | ||
|
||
from qwen_agent.agents.assistant import Assistant | ||
from qwen_agent.llm.schema import SYSTEM, USER, ContentItem, Message | ||
from qwen_agent.settings import DEFAULT_WORKSPACE | ||
from qwen_agent.utils.utils import extract_text_from_message, save_text_to_file | ||
|
||
MAX_TRUNCATED_QUERY_LENGTH = 1000 | ||
|
||
EXTRACT_QUERY_TEMPLATE_ZH = """<给定文本> | ||
{ref_doc} | ||
上面的文本是包括一段材料和一个用户请求,这个请求一般在最开头或最末尾,请你帮我提取出那个请求,你不需要回答这个请求,只需要打印出用户的请求即可!""" | ||
|
||
EXTRACT_QUERY_TEMPLATE_EN = """<Given Text> | ||
{ref_doc} | ||
The text above includes a section of reference material and a user request. The user request is typically located either at the beginning or the end. Please extract that request for me. You do not need to answer the request, just print out the user's request!""" | ||
|
||
EXTRACT_QUERY_TEMPLATE = {'zh': EXTRACT_QUERY_TEMPLATE_ZH, 'en': EXTRACT_QUERY_TEMPLATE_EN} | ||
|
||
|
||
# TODO: merge to retrieval tool | ||
class DialogueRetrievalAgent(Assistant): | ||
"""This is an agent for super long dialogue.""" | ||
|
||
def _run(self, | ||
messages: List[Message], | ||
lang: str = 'en', | ||
session_id: str = '', | ||
**kwargs) -> Iterator[List[Message]]: | ||
"""Process messages and response | ||
Answer questions by storing the long dialogue in a file | ||
and using the file retrieval approach to retrieve relevant information | ||
""" | ||
assert messages and messages[-1].role == USER | ||
new_messages = [] | ||
content = [] | ||
for msg in messages[:-1]: | ||
if msg.role == SYSTEM: | ||
new_messages.append(msg) | ||
else: | ||
content.append(f'{msg.role}: {extract_text_from_message(msg, add_upload_info=True)}') | ||
# Process the newest user message | ||
text = extract_text_from_message(messages[-1], add_upload_info=False) | ||
if len(text) <= MAX_TRUNCATED_QUERY_LENGTH: | ||
query = text | ||
else: | ||
if len(text) <= MAX_TRUNCATED_QUERY_LENGTH * 2: | ||
latent_query = text | ||
else: | ||
latent_query = f'{text[:MAX_TRUNCATED_QUERY_LENGTH]} ... {text[-MAX_TRUNCATED_QUERY_LENGTH:]}' | ||
|
||
*_, last = self._call_llm( | ||
messages=[Message(role=USER, content=EXTRACT_QUERY_TEMPLATE[lang].format(ref_doc=latent_query))]) | ||
query = last[-1].content | ||
# A little tricky: If the extracted query is different from the original query, it cannot be removed | ||
text = text.replace(query, '') | ||
content.append(text) | ||
|
||
# Save content as file: This file is related to the session and the time | ||
content = '\n'.join(content) | ||
file_path = os.path.join(DEFAULT_WORKSPACE, f'dialogue_history_{session_id}_{datetime.datetime.now()}.txt') | ||
save_text_to_file(file_path, content) | ||
|
||
new_content = [ContentItem(text=query), ContentItem(file=file_path)] | ||
if isinstance(messages[-1].content, list): | ||
for item in messages[-1].content: | ||
if item.file or item.image: | ||
new_content.append(item) | ||
new_messages.append(Message(role=USER, content=new_content)) | ||
|
||
return super()._run(messages=new_messages, lang=lang, **kwargs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.