当前位置:首页>python>【Python】Day26:Streamlit快速搭建聊天界面(下):对接大模型API与流式输出

【Python】Day26:Streamlit快速搭建聊天界面(下):对接大模型API与流式输出

  • 2026-10-11 06:21:01
【Python】Day26:Streamlit快速搭建聊天界面(下):对接大模型API与流式输出

🎯 学习目标

  1. 将 Day23 的 API 调用函数接入 Streamlit 界面
  2. 实现 流式输出:让 AI 回复像打字机一样逐字出现
  3. 掌握流式 API 的调用方式:stream=True
  4. 用st.write_stream或st.empty实现流式渲染

一、对接大模型 API

  1. .env文件
    • 在当前代码文件所处的目录(文件夹)下创建.env文件,写入API_KEY和BASE_URL
      API_KEY =需要修改成你自己的API_KEYBASE_URL =https://open.bigmodel.cn/api/paas/v4
    • 智谱API_KEY获取方法
      1. 浏览器访问`https://open.bigmodel.cn/`2. 有账号就登录,没账号就注册,注册后登录3. 点击【控制台】-【API Key】-【新建API Key】
  2. 在 Streamlit 中调用 API
    import streamlit as stimport requestsfrom dotenv import load_dotenvimport osload_dotenv()defcall_llm(messages):"""调用大模型API"""    api_key = os.getenv("API_KEY")    base_url = os.getenv("BASE_URL")    url = f"{base_url}/chat/completions"    headers = {"Authorization": f"Bearer {api_key}","Content-Type": "application/json"    }    data = {"model": "glm-4-flash","messages": messages,"temperature": 0.7    }    response = requests.post(url, headers=headers, json=data, timeout=60)    response.raise_for_status()return response.json()["choices"][0]["message"]["content"]

二、流式输出:原理与实现

  1. 为什么需要流式输出?
    • 非流式:等 AI 生成完所有内容才显示(等待时间长)
    • 流式:生成一个字就显示一个字(体验好)
  2. 流式 API 请求
    defcall_llm_stream(messages):"""流式调用大模型API"""    api_key = os.getenv("API_KEY")    base_url = os.getenv("BASE_URL")    url = f"{base_url}/chat/completions"    headers = {"Authorization": f"Bearer {api_key}","Content-Type": "application/json"    }    data = {"model": "gpt-3.5-turbo","messages": messages,"temperature": 0.7,"stream": True# 🔑 关键:开启流式    }    response = requests.post(url, headers=headers, json=data, stream=True, timeout=60)    response.raise_for_status()# 逐行读取 SSE 数据for line in response.iter_lines():if line:            line = line.decode("utf-8")if line.startswith("data: "):                data_str = line[6:]if data_str.strip() == "[DONE]":breaktry:import json                    chunk = json.loads(data_str)                    content = chunk["choices"][0].get("delta", {}).get("content", "")if content:yield content    # 用生成器逐字产出except json.JSONDecodeError:continue

三、在 Streamlit 中渲染流式输出

  1. 使用st.write_stream(推荐)
    if prompt := st.chat_input("请输入消息:"):# 显示用户消息    st.session_state.messages.append({"role": "user", "content": prompt})with st.chat_message("user"):        st.write(prompt)# AI流式回复with st.chat_message("assistant"):        response = st.write_stream(call_llm_stream(st.session_state.messages))    st.session_state.messages.append({"role": "assistant", "content": response})

⚠️ 常见坑

  1. 流式请求中response.json()会报错
    • 流式请求必须用response.iter_lines()逐行读取,不能用.json()
  2. SSE 数据格式解析
    • 每行以data:  开头
    • 结尾是data: [DONE]
    • 必须处理delta中content为空的情况

✍️ 实战练习

  1. 完成带流式输出的聊天应用
    • 要求:把上面的代码整合,确保能流式看到 AI 回复。
  2. 添加系统提示词
    • 要求:在侧边栏添加系统提示词输入框,影响 AI 的角色设定。
  • 示例
    import osimport streamlit as stimport requestsfrom dotenv import load_dotenvload_dotenv()defcall_llm_stream(messages):"""流式调用大模型API"""    api_key = os.getenv("API_KEY")    base_url = os.getenv("BASE_URL")    url = base_url + "/chat/completions"    headers = {"Authorization": f"Bearer {api_key}","Content-Type": "application/json"    }    data = {"model": "glm-4-flash","messages": messages,"temperature": 0.7,"stream": True# 🔑 关键:开启流式    }    response = requests.post(url, headers=headers, json=data, stream=True, timeout=60)# 逐行读取 SSE 数据for line in response.iter_lines():if line:            line = line.decode("utf-8")if line.startswith("data: "):                data_str = line[6:]                print('data_str:',data_str)if data_str.strip() == "[DONE]":breaktry:import json                    chunk = json.loads(data_str)                    content = chunk["choices"][0].get("delta", {}).get("content", "")if content:yield content  # 用生成器逐字产出except json.JSONDecodeError:continuest.title("💬 智能聊天助手")if"messages"notin st.session_state:    st.session_state.messages = []with st.sidebar:    system_info = st.text_input("AI 角色设定:")if system_info:        st.session_state.messages.insert(0, {"role": "system", "content": system_info})if st.button("清空对话"):        st.session_state.messages = []        st.rerun()  # 重新运行页面# 显示历史消息for msg in st.session_state.messages:if msg["role"] != "system":with st.chat_message(msg["role"]):            st.write(msg["content"])if prompt := st.chat_input("请输入问题:"):# 显示用户消息    st.session_state.messages.append({"role": "user", "content": prompt})with st.chat_message("user"):        st.write(prompt)# AI流式回复with st.chat_message("assistant"):        response = st.write_stream(call_llm_stream(st.session_state.messages))  # type: ignore    st.session_state.messages.append({"role": "assistant", "content": response})
    • 界面效果

✅ 自测清单

  • [ ] 能将 API 调用函数接入 Streamlit 界面
  • [ ] 理解流式输出的原理:生成一个字就显示一个字
  • [ ] 知道流式请求需要设stream=True,用iter_lines()读取
  • [ ] 能用st.write_stream渲染流式回复
  • [ ] 知道聊天历史和流式回复最终都要存入st.session_state

最新文章

随机文章