Closed cristianohello closed 6 months ago
嘿,@cristianohello!很高兴再次遇到你,希望一切都好!
您的curl调用返回内容前面有"data",这是因为服务器正在使用服务器发送事件(Server-Sent Events,SSE)将响应流式传输到客户端。在提供的上下文中,EventSourceResponse
被用来实时向客户端发送更新。根据SSE规范,服务器使用SSE发送的每条消息都以"data: "为前缀。这在代码片段中很明显,其中在agent_chat_iterator
函数内部产生的JSON数据,然后被EventSourceResponse
包装。
如果要从响应中删除"data"前缀,您需要从使用SSE(服务器发送事件)切换到不会自动在每条消息前添加"data: "的其他发送数据到客户端的方法。这可能涉及使用简单的HTTP响应进行一次性获取,或者使用WebSockets进行无需SSE特定格式的连续的双向通信。然而,这将需要对服务器和客户端代码进行重大修改,以适应新的通信协议。
在Langchain-Chatchat代码库中,负责向客户端发送响应的特定函数是file_chat
。
相关源代码:
请注意,这可能需要对代码进行重大修改,以适应新的通信协议。
能够通过前处理去掉吗?这样会不会有不好的地方
stream=true时,不建议去除掉data 这是sse的消息格式 stream=false时,可以把代码修改成
yield bytes(json.dumps({"answer": answer,"docs": source_documents},ensure_ascii=False), 'utf-8')
看代码EventSourceResponse->ensure_bytes
def ensure_bytes(data: Union[bytes, dict, ServerSentEvent, Any], sep: str) -> bytes:
if isinstance(data, bytes):
return data
elif isinstance(data, ServerSentEvent):
return data.encode()
elif isinstance(data, dict):
data["sep"] = sep
return ServerSentEvent(**data).encode()
else:
return ServerSentEvent(str(data), sep=sep).encode()
这里会根据类型,直接返回值 就不带data前缀了 可以尝试看下
@litterGuy
感谢大佬。已经解决这个问题。 还有一个小疑问: curl -X 'POST' 'http://127.0.0.1:7861/chat/knowledge_base_chat' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"query": "你是谁?", "knowledge_base_name": "samples", "top_k": 2, "score_threshold": 0.9, "history": [ {"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好"} ], "stream": false, "model_name": "Qwen1.5-1.8B-Chat", "temperature": 0.1, "max_tokens": 10000, "prompt_name": "default" }' : ping - 2024-03-13 02:50:35.285414
怎么把: ping - 2024-03-13 02:50:35.285414“”这种中间输出去掉,不让他输出这些内容?
通过EventSourceResponse函数跳转,可以看到 ping值是这里产生的。所以需要实现一个ping_message_factory传递过去。
实现的话,类似这种
def ping_message_factory() -> Callable[[], ServerSentEvent]:
return custom_ping_message_factory
def custom_ping_message_factory() -> ServerSentEvent:
return ServerSentEvent()
在chat最后的返回值做下修改
return EventSourceResponse(content=chat_iterator(), ping_message_factory=None if stream else ping_message_factory())
这样,可以在stream=false的情况下去除掉ping值的返回。有个问题是,这样修改最终返回字符串还是会多一个'/r/n' 因为这里的step必须要有个值 所以这个问题没做处理
以上参考下
@litterGuy 你好,我问一下,这些中间ping值,不影响我给后端提供curl调用时候,造成错误吧?也就是后端调用answer返回的答案时候,不会取到ping值吧?
不做处理的话,当stream=false调用时 是会影响解析结果的。 默认是15s输出一个ping值 不想做处理,可以在调用程序那里做处理、过滤掉这部分
@litterGuy 那我把15设置一个比较大的值,也可以不让输出ping值了吧
这个问题解决了么,难道只能在返回值中判断了手动去除,这也太矬了
去除外面的内容你直接提取json内部data字段就行了,在调用API后加这个处理就行
源:yield json.dumps({"answer": answer, "docs": source_documents}, ensure_ascii=False)
返回:data: {"answer": "可以"} 怎么把data去掉