You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit表单提交后用户输入重复显示问题求助

问题描述
  • 预期流程:用户输入「指定城市之一的太阳能」,机器人展示表单提示输入所需数据;用户提交后,机器人显示「太阳能为XX数值」。
  • 实际问题:点击提交后,机器人会重复用户最初的「XX城市太阳能」消息,再显示太阳能数值。
问题代码
import os
import streamlit as st
from displayer import bot_template, user_template
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.schema import SystemMessage, HumanMessage, AIMessage
from ML.Ml import CityWeatherData

def init():
    load_dotenv()

    # Loading OpenAI API key
    if os.getenv("OPENAI_API_KEY") is None or os.getenv("OPENAI_API_KEY") == "":
        print("OPENAI_API_KEY is not set yet")
        exit(1)
    else:
        print("OPENAI_API_KEY is set")

def main():
    init()

    # Initialize LangChain Chat
    chat = ChatOpenAI(temperature=0)
    
    if "messages" not in st.session_state:
        st.session_state.messages = [
            SystemMessage(content="You are a helpful assistant.")
        ]
    
    st.header("Green Optimizer 🤖")
    
    with st.sidebar:
        # CHATTING CODE
        user_input = st.text_input("Enter your message:")
        cities = "jeddah", "skaka", "riyadh", "dammam"
    
        if user_input:
            st.session_state.messages.append(HumanMessage(content=user_input))
            with st.spinner("Thinking.."):
                if any(city in user_input.lower() for city in cities):
                    user_city = None
                    for city in cities:
                        if city in user_input.lower():
                            user_city = city
                            break
    
                    # If city name is found, proceed with solar energy analysis
                    if user_city:
                        # Display the form for user input
                        st.write(f"Welcome! Please enter the following information for {user_city.capitalize()}:")
                        with st.form(key='weather_form'):
                            ALLSKY = st.number_input("Enter ALLSKY:")
                            CLRSKY = st.number_input("Enter CLRSKY:")
                            pressure = st.number_input("Enter pressure:")
                            temperature = st.number_input("Enter temperature:")
                            moisture = st.number_input("Enter moisture:")
    
                            submit_button = st.form_submit_button(label='Submit')
    
                        # If the form is submitted, calculate and display the result
                        if submit_button:
                            # Create CityWeatherData instance
                            weather_data = CityWeatherData(city=user_city)
    
                            # Analyze weather for the selected city
                            solar_energy = weather_data.analyze_weather(
                                ALLSKY=ALLSKY, CLRSKY=CLRSKY, temperature=temperature, pressure=pressure, moisture=moisture
                            )
                            # Append the user and AI messages to the conversation
                            st.session_state.messages.append(AIMessage(content=f"The Solar Energy in {user_city.capitalize()} is: {solar_energy}"))
    
    
    
                    else:
                        # If no valid city name is found, proceed with regular chat
                        response = chat(st.session_state.messages)
                        st.session_state.messages.append(AIMessage(content=response.content))
                else:
                    # If no city name is mentioned, proceed with regular chat
                    response = chat(st.session_state.messages)
                    st.session_state.messages.append(AIMessage(content=response.content))
    
    # Displaying all the messages the user had by fetching them
    messages = st.session_state.get("messages", [])
    
    # Looping through all the messages, if 1 user(odd number) display it from the human position.
    # If two users(even number) display it from the bot position.
    for i, msgs in enumerate(messages[1:]):
        if i % 2 == 0:
            st.markdown(user_template.replace("{{MSG}}", msgs.content), unsafe_allow_html=True)
        else:
            st.markdown(bot_template.replace("{{MSG}}", msgs.content), unsafe_allow_html=True)

if __name__ == '__main__':
    main()
解决方案

问题根源

Streamlit每次触发页面刷新(比如提交表单)时,会重新执行整个脚本,之前的user_input值会被保留,导致代码再次进入if user_input:分支,重复将用户初始查询消息添加到对话历史中。

修改后代码

import os
import streamlit as st
from displayer import bot_template, user_template
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.schema import SystemMessage, HumanMessage, AIMessage
from ML.Ml import CityWeatherData

def init():
    load_dotenv()

    # Loading OpenAI API key
    if os.getenv("OPENAI_API_KEY") is None or os.getenv("OPENAI_API_KEY") == "":
        print("OPENAI_API_KEY is not set yet")
        exit(1)
    else:
        print("OPENAI_API_KEY is set")

def main():
    init()

    # Initialize LangChain Chat
    chat = ChatOpenAI(temperature=0)
    
    # 初始化对话历史和流程状态
    if "messages" not in st.session_state:
        st.session_state.messages = [
            SystemMessage(content="You are a helpful assistant.")
        ]
    if "current_city" not in st.session_state:
        st.session_state.current_city = None
    
    st.header("Green Optimizer 🤖")
    
    with st.sidebar:
        user_input = st.text_input("Enter your message:")
        cities = ("jeddah", "skaka", "riyadh", "dammam")
    
        # 仅在未处理城市查询时,处理用户输入
        if user_input and st.session_state.current_city is None:
            st.session_state.messages.append(HumanMessage(content=user_input))
            with st.spinner("Thinking.."):
                user_city = None
                for city in cities:
                    if city in user_input.lower():
                        user_city = city
                        break
        
                if user_city:
                    # 标记进入城市查询流程
                    st.session_state.current_city = user_city
                else:
                    # 常规聊天逻辑
                    response = chat(st.session_state.messages)
                    st.session_state.messages.append(AIMessage(content=response.content))
    
        # 如果处于城市查询流程,单独显示表单
        if st.session_state.current_city:
            user_city = st.session_state.current_city
            st.write(f"Welcome! Please enter the following information for {user_city.capitalize()}:")
            with st.form(key='weather_form'):
                ALLSKY = st.number_input("Enter ALLSKY:")
                CLRSKY = st.number_input("Enter CLRSKY:")
                pressure = st.number_input("Enter pressure:")
                temperature = st.number_input("Enter temperature:")
                moisture = st.number_input("Enter moisture:")
    
                submit_button = st.form_submit_button(label='Submit')
    
            if submit_button:
                weather_data = CityWeatherData(city=user_city)
                solar_energy = weather_data.analyze_weather(
                    ALLSKY=ALLSKY, CLRSKY=CLRSKY, temperature=temperature, pressure=pressure, moisture=moisture
                )
                # 添加AI结果到对话历史
                st.session_state.messages.append(AIMessage(content=f"The Solar Energy in {user_city.capitalize()} is: {solar_energy}"))
                # 重置流程状态,恢复正常输入
                st.session_state.current_city = None
    
    # 渲染对话历史
    messages = st.session_state.get("messages", [])
    for i, msgs in enumerate(messages[1:]):
        if i % 2 == 0:
            st.markdown(user_template.replace("{{MSG}}", msgs.content), unsafe_allow_html=True)
        else:
            st.markdown(bot_template.replace("{{MSG}}", msgs.content), unsafe_allow_html=True)

if __name__ == '__main__':
    main()

修改要点

  1. 新增st.session_state.current_city状态变量,标记是否处于城市太阳能查询流程中
  2. 将用户输入处理与表单展示逻辑分离,仅在未处理城市查询时,才处理用户输入并添加消息到历史
  3. 表单提交完成后重置current_city,恢复正常输入状态,避免重复触发原始输入逻辑

内容的提问来源于stack exchange,提问作者Eva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 21:06:03