基于Langchain+Streamlit的分析ChatBot提速及禁用中间步骤问题
分析型ChatBot性能优化与中间步骤禁用问题解答
问题背景
基于Langchain(集成Agents和Tools)+ Streamlit开发的分析型ChatBot,存在部分查询响应缓慢(如逐条打印40条评论耗时达1分钟),且已设置return_intermediate_steps=False、verbose=False和expand_new_thoughts=False仍显示中间步骤的问题。
1. 提升ChatBot运行速度的方法
- 严格限制数据返回量并优化工具提示词:
进一步降低提示词中的max_number_of_rows(如改为10-20行),明确要求LLM返回统计结论(如关键词出现次数、趋势总结)而非原始数据行;强制提示词中使用head()或sample()限制返回行数,避免全量数据处理。 - 优化Pandas Agent配置:
- 启用
max_iterations:取消注释max_iterations=2(可根据需求调整数值),避免Agent无意义的循环尝试; - 确保
reduce_k_below_max_tokens参数生效,避免因Token超限导致重复调用LLM。
- 启用
- 避免重复初始化核心组件:
当前每次用户输入都会重新创建AzureChatOpenAI、agent_analytics_node、chat_agent和executor,增加额外开销。将这些初始化代码移到if "df" in st.session_state:块的顶部,仅在加载数据后初始化一次,而非每次输入都重建。 - 关闭不必要的流式传输:
若无需实时输出LLM思考过程,将streaming=True改为False,减少前端渲染和数据传输的耗时。 - 预处理数据集:
对CSV数据提前预处理,如过滤无关列、压缩文本字段、预计算常用统计指标,减少Agent需要处理的数据量。
2. 彻底禁用中间步骤输出的方法
- 移除StreamlitCallbackHandler:
当前代码中使用的StreamlitCallbackHandler即使设置expand_new_thoughts=False,仍会输出部分中间状态。直接删除callbacks=[st_cb]参数,即可阻止中间步骤在前端显示。 - 确保所有层级的verbose参数关闭:
确认create_pandas_dataframe_agent、AgentExecutor的verbose=False已设置,Tool的return_intermediate_steps=False已配置(当前代码已满足,需确保无遗漏)。 - 封装Pandas Agent的输出:
自定义包装函数替代agent_analytics_node.run,过滤中间步骤文本,仅返回最终结果:
然后将def run_agent_silently(prompt): try: result = agent_analytics_node.run(prompt) # 过滤可能包含的中间步骤,仅保留最终答案 return result.split("Final Answer:")[-1].strip() if "Final Answer:" in result else result except Exception as e: return str(e)tool_analytics_node的func改为run_agent_silently。
原ChatBot代码
def load_data(path): return pd.read_csv(path) if st.sidebar.button('Use Data'): # If button is clicked, load the EDW.csv file st.session_state["df"] = load_data('./data/EDW.csv') uploaded_file = st.sidebar.file_uploader("Choose a CSV file", type="csv") if "df" in st.session_state: msgs = StreamlitChatMessageHistory() memory = ConversationBufferWindowMemory(chat_memory=msgs, return_messages=True, k=5, memory_key="chat_history", output_key="output") if len(msgs.messages) == 0 or st.sidebar.button("Reset chat history"): msgs.clear() msgs.add_ai_message("How can I help you?") st.session_state.steps = {} avatars = {"human": "user", "ai": "assistant"} # Display a chat input widget if prompt := st.chat_input(placeholder=""): st.chat_message("user").write(prompt) llm = AzureChatOpenAI( deployment_name = "gpt-4", model_name = "gpt-4", openai_api_key = os.environ["OPENAI_API_KEY"], openai_api_version = os.environ["OPENAI_API_VERSION"], openai_api_base = os.environ["OPENAI_API_BASE"], temperature = 0, streaming=True ) max_number_of_rows = 40 agent_analytics_node = create_pandas_dataframe_agent( llm, st.session_state["df"], verbose=False, agent_type=AgentType.OPENAI_FUNCTIONS, reduce_k_below_max_tokens=True, # to not exceed token limit max_execution_time = 20, early_stopping_method="generate", # will generate a final answer after the max_execution_time has been surpassed # max_iterations=2, # to cap an agent at taking a certain number of steps ) tool_analytics_node = Tool( return_intermediate_steps=False, name='Analytics Node', func=agent_analytics_node.run, description=f''' This tool is useful when you need to answer questions about data stored in a pandas dataframe, referred to as 'df'. 'df' comprises the following columns: {st.session_state["df"].columns.to_list()}. Here is a sample of the data: {st.session_state["df"].head(5)}. When working with df, ensure not to output more than {max_number_of_rows} rows at once, either in intermediate steps or in the final answer. This is because df could contain too many rows, which could potentially overload memory, for example instead of `df[df['survey_comment'].str.contains('wet', na=False, case=False)]['survey_comment'].tolist()` use `df[df['survey_comment'].str.contains('wet', na=False, case=False)]['survey_comment'].head({max_number_of_rows}).tolist()`. ''' ) tools = [tool_analytics_node] chat_agent = ConversationalChatAgent.from_llm_and_tools(llm=llm, tools=tools, return_intermediate_steps=False) executor = AgentExecutor.from_agent_and_tools( agent=chat_agent, tools=tools, memory=memory, return_intermediate_steps=False, handle_parsing_errors=True, verbose=False, ) with st.chat_message("assistant"): st_cb = StreamlitCallbackHandler(st.container(), expand_new_thoughts=False) response = executor(prompt, callbacks=[st_cb]) st.write(response["output"])
内容的提问来源于stack exchange,提问作者illuminato
相关产品推荐
相关产品推荐

