如何从Streamlit向Snowflake传递对象列表与字典以实现AI聊天机器人功能?
如何从Streamlit向Snowflake传递对象列表与字典以实现AI聊天机器人功能?
看起来你已经搭好了Streamlit聊天界面的基础框架,也规划好了初始提示词和对话历史的追加逻辑,核心问题就是怎么把这个messages列表正确传给Snowflake的COMPLETE函数对吧?我来一步步帮你捋清楚:
第一步:先把初始消息格式改对,适配Snowflake要求
你之前写的初始消息用了{'system': 'xxx'}这种格式,这会导致Snowflake解析失败——因为Snowflake的CORTEX COMPLETE函数要求每个消息必须是包含role(可选值为system/user/assistant)和content两个键的字典。
修正后的初始消息列表应该是这样的:
# 统一格式:每个消息都有role和content字段 messages = [ {'role': 'system', 'content': 'act like a database professional'}, {'role': 'user', 'content': 'context: I have a database containing sales data. I need you to answer user questions based on the input data between <data> </data> tags'}, {'role': 'user', 'content': '<data>\n actual data ...\n </data>'}, {'role': 'user', 'content': 'provide the answer in markdown format'} ]
第二步:用Snowpark或Snowflake连接器传递列表参数
在Streamlit里,你可以用Snowpark(推荐,更简洁)或者传统的Snowflake Python连接器,把这个messages列表直接作为参数传给Snowflake的SQL语句,不需要手动序列化,工具会帮你完成Python对象到Snowflake数据类型的转换。
用Snowpark的实现示例
from snowflake.snowpark import Session import streamlit as st # 用Streamlit Secrets存储Snowflake凭证,避免硬编码 session = Session.builder.configs(st.secrets["snowflake"]).create() # 初始化聊天历史到Streamlit的session_state,防止页面刷新丢失 if "chat_history" not in st.session_state: st.session_state.chat_history = [ {'role': 'system', 'content': 'act like a database professional'}, {'role': 'user', 'content': 'context: I have a database containing sales data. I need you to answer user questions based on the input data between <data> </data> tags'}, {'role': 'user', 'content': '<data>\n actual data ...\n </data>'}, {'role': 'user', 'content': 'provide the answer in markdown format'} ] # 处理用户输入 user_question = st.chat_input("问我关于销售数据的问题吧:") if user_question: # 把用户提问追加到聊天历史 st.session_state.chat_history.append({'role': 'user', 'content': user_question}) # 调用Snowflake的COMPLETE函数,传入聊天历史和配置参数 result = session.sql(""" SELECT SNOWFLAKE.CORTEX.COMPLETE( 'llama3-70b', -- 替换成你实际使用的模型 ?, -- 绑定聊天历史参数 { 'temperature': 0, 'max_tokens': 128 } -- 模型配置项 ) AS assistant_reply """, params=[st.session_state.chat_history]).collect() # 提取助手回复并追加到聊天历史 assistant_msg = result[0]["ASSISTANT_REPLY"] st.session_state.chat_history.append({'role': 'assistant', 'content': assistant_msg}) # 渲染整个聊天记录 for msg in st.session_state.chat_history: with st.chat_message(msg["role"]): st.markdown(msg["content"])
用传统Snowflake连接器的实现示例
如果你习惯用普通的snowflake-connector-python,代码逻辑类似:
import snowflake.connector import streamlit as st # 初始化聊天历史 if "chat_history" not in st.session_state: st.session_state.chat_history = [ {'role': 'system', 'content': 'act like a database professional'}, {'role': 'user', 'content': 'context: I have a database containing sales data. I need you to answer user questions based on the input data between <data> </data> tags'}, {'role': 'user', 'content': '<data>\n actual data ...\n </data>'}, {'role': 'user', 'content': 'provide the answer in markdown format'} ] user_question = st.chat_input("问我关于销售数据的问题吧:") if user_question: st.session_state.chat_history.append({'role': 'user', 'content': user_question}) # 建立Snowflake连接 conn = snowflake.connector.connect(**st.secrets["snowflake"]) cur = conn.cursor() # 执行SQL并绑定参数 cur.execute(""" SELECT SNOWFLAKE.CORTEX.COMPLETE( 'llama3-70b', ?, { 'temperature': 0, 'max_tokens': 128 } ) AS assistant_reply """, (st.session_state.chat_history,)) # 获取回复 assistant_msg = cur.fetchone()[0] st.session_state.chat_history.append({'role': 'assistant', 'content': assistant_msg}) # 关闭连接 cur.close() conn.close() # 渲染聊天记录 for msg in st.session_state.chat_history: with st.chat_message(msg["role"]): st.markdown(msg["content"])
几个要注意的避坑点
- 格式统一:所有消息必须严格遵循
{'role': 'xxx', 'content': 'xxx'}的格式,不能混用{'system': 'xxx'}这种写法,Snowflake会无法识别角色。 - 权限问题:确保你的Snowflake角色拥有
SNOWFLAKE.CORTEX.COMPLETE函数的调用权限,不然会报错。 - Token限制:
max_tokens的设置要考虑初始提示词的Token用量,如果初始提示词已经很长,要适当调大这个值,避免回复被截断。 - 温度参数:你设的
temperature: 0会让回复非常确定但缺乏灵活性,如果需要一些创造性的回复,可以微调这个值(比如0.3-0.7)。
备注:内容来源于stack exchange,提问作者Julian Eccleshall
相关产品推荐
相关产品推荐

