Langchain流式处理问题:前端无法显示分词消息求助
LangChain流式输出前端不显示分词消息的解决方案
问题根源
你的代码存在两个核心问题导致流式输出失效:
- 使用
conversation.run()同步方法,该方法会等待模型返回完整结果后才执行后续逻辑,无法触发流式回调的逐token输出。 - 冗余的
token_generator(MyCallbackHander())调用,不仅无效,还实例化了新的回调实例,和LLM初始化时传入的回调无关联。
修复步骤
1. 确保回调类正确实现逐token处理
确认MyCallbackHander继承自BaseCallbackHandler,并正确实现on_llm_new_token方法,用于将每个生成的token传递给前端(示例以打印为例,实际需替换为前端通信逻辑,比如WebSocket推送、HTTP流写入):
from langchain.callbacks.base import BaseCallbackHandler class MyCallbackHandler(BaseCallbackHandler): def on_llm_new_token(self, token: str, **kwargs) -> None: # 替换为前端通信逻辑,比如通过WebSocket发送token print(token, end='', flush=True)
2. 替换同步调用为流式生成
删除conversation.run()和token_generator(...),改用conversation.stream()方法遍历生成的token片段:
def generate_message(query, history, behavior, temp, chat): template = """{behavior} Training data: {examples} Chathistory: {history} Human: {human_input} Assistant:""" prompt = PromptTemplate( input_variables=["history", "examples", "human_input", "behavior"], template=template) langchain.llm_cache = GPTCache(init_gptcache) llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=temp, openai_api_key=OPENAI_API_KEY, streaming=True, callbacks=[MyCallbackHandler()]) conversation = LLMChain( llm=llm, verbose=True, prompt=prompt ) embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY) docsearch = Pinecone.from_existing_index( index_name=PINECONE_INDEX_NAME, namespace = PINECONE_NAMESPACE, embedding=embeddings) docs = docsearch.similarity_search(query=query, k=10) examples = "" for doc in docs: doc.page_content = doc.page_content.replace('\n\n', ' ') examples += doc.page_content + '\n' # 用stream()替代run(),遍历逐token输出 for chunk in conversation.stream( human_input=query, history=history, behavior=behavior, examples=examples ): # 若不需要额外处理,回调会自动触发;如需自定义处理可在此操作chunk pass
3. 前端配合接收流式数据
前端需支持流式响应接收,比如使用Fetch API的ReadableStream:
async function fetchStream() { const response = await fetch('/your-api-endpoint', { method: 'POST', body: JSON.stringify({/* 请求参数 */}) }); const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const token = decoder.decode(value); // 将token追加到页面元素中 document.getElementById('chat-output').textContent += token; } }
内容的提问来源于stack exchange,提问作者Andy Wood
相关产品推荐
相关产品推荐

