THUDM / ChatGLM3

ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型
Apache License 2.0
13.31k stars 1.55k forks source link

chatglm3 openai流式对话接口chat数据建模的改进 #1162

Closed lilongxian closed 4 months ago

lilongxian commented 4 months ago

System Info / 系統信息

tsfm==4.37.0 sentencepiece>=0.1.99 fastapi>=0.108.0 openai>=1.6.1 pydantic>=2.5.3 sse-starlette>=1.8.2 uvicorn>=0.25.0 timm>=0.9.12 sentence_transformers==2.2.2 pytorch:1.13.0+cu117

Who can help? / 谁可以帮助到您?

openai

Information / 问题信息

Reproduction / 复现过程

原始代码位于 https://github.com/THUDM/ChatGLM3/tree/main/openai_api_demo/utils.py

def process_chatglm_messages(messages, tools=None): _messages = messages messages = [] if tools: messages.append( { "role": "system", "content": "Answer the following questions as best as you can. You have access to the following tools:", "tools": tools } ) for m in _messages: role, content, func_call = m.role, m.content, m.function_call if role == "function": messages.append( { "role": "observation", "content": content } )

    elif role == "assistant" and func_call is not None:
        for response in content.split("<|assistant|>"):
            metadata, sub_content = response.split("\n", maxsplit=1)
            messages.append(
                {
                    "role": role,
                    "metadata": metadata,
                    "content": sub_content.strip()
                }
            )
    else:
        messages.append({"role": role, "content": content})
return messages

导致情况:system指令信息被添加两次,并且第二次没有tools信息。没有tools信息的第二次system指令可以用于普通的chat场景,但第一次system信息是有tools的,虽然运行上没问题,但这是矛盾的,也不正确。

Expected behavior / 期待表现

原始代码位于 https://github.com/THUDM/ChatGLM3/tree/main/openai_api_demo/utils.py

修复代码:

def process_chatglm_messages(messages, tools=None): _messages = messages messages = [] msg_has_sys = False # 新加,表示system指令状态 if tools: messages.append( { "role": "system", "content": "Answer the following questions as best as you can. You have access to the following tools:", "tools": tools } ) msg_has_sys = True # system指令状态:已添加

for m in _messages:
    role, content, func_call = m.role, m.content, m.function_call
    if role == "function":
        messages.append(
            {
                "role": "observation",
                "content": content
            }
        )

    elif role == "assistant" and func_call is not None:
        for response in content.split("<|assistant|>"):
            metadata, sub_content = response.split("\n", maxsplit=1)
            messages.append(
                {
                    "role": role,
                    "metadata": metadata,
                    "content": sub_content.strip()
                }
            )
    else:
        # # 当没有tools时候,这里role也可以是system role,仅仅运行普通的chat场景,而非agent-chat场景。
        # # 但当在agent-chat场景时,因上面已经加入了sys信息,所以这里就不再添加,将system状态复位为0。
        if role == "system" and msg_has_sys:   # 
            msg_has_sys = False  #  system状态复位
            continue   #  
        messages.append({"role": role, "content": content})
return messages

以上的改进,可以兼容agent-chat工具调用场景多轮对话,也可以用于通用的有sys指令信息的对话场景。

经过改后的agent-chat运行效果如如下: agent-chat中第一次调用 messages after process_chatglm_messages: [ {'role': 'system', 'content': 'Answer the following questions as best as you can. You have access to the following tools:', 'tools': [{'name': 'track', 'description': '追踪指定股票的实时价格', 'parameters': {'type': 'object', 'properties': {'symbol': {'description': '需要追踪的股票代码'}}, 'required': []}}, {'name': 'Calculator', 'description': '数学计算器,计算数学问题', 'parameters': {'type': 'object', 'properties': {'symbol': {'description': '要计算的数学公式'}}, 'required': []}}]}, {'role': 'user', 'content': '你好!'}, {'role': 'assistant', 'content': '你好!请问有什么我可以帮助你的吗?'}, {'role': 'user', 'content': '37乘以8加7除2等于多少?'} ] agent-chat中第二次调用 messages after process_chatglm_messages: [ {'role': 'system', 'content': 'Answer the following questions as best as you can. You have access to the following tools:', 'tools': [{'name': 'track', 'description': '追踪指定股票的实时价格', 'parameters': {'type': 'object', 'properties': {'symbol': {'description': '需要追踪的股票代码'}}, 'required': []}}, {'name': 'Calculator', 'description': '数学计算器,计算数学问题', 'parameters': {'type': 'object', 'properties': {'symbol': {'description': '要计算的数学公式'}}, 'required': []}}]}, {'role': 'user', 'content': '你好!'}, {'role': 'assistant', 'content': '你好!请问有什么我可以帮助你的吗?'}, {'role': 'user', 'content': '37乘以8加7除2等于多少?'}, {'role': 'assistant', 'content': "Calculator\n python\ntool_call(symbol='37*8+7/2')\n"}, {'role': 'observation', 'content': '299.5'} ]

OK!

ToxicHu commented 4 months ago

您好,请问最后您提到的“agent-chat”部分指的是哪里呢?是源工程里openai_api_demo\langchain_openai_api.py的function_chat()函数吗?