- تُعد Streamlit طريقة سريعة لإنشاء واجهات مستخدم مخصصة chatbot لية بالذكاء الاصطناعي ولكنها تحتاج إلى مرونة تتجاوز مكونات الدردشة المدمجة.
- تعمل واجهة برمجة تطبيقاتChat Botpress Chat API على تشغيل منطق chatbot واسترجاعها وسير العمل بها، ويتم عرضها عبر عميل Python مخصص.
- يدير تطبيق Streamlit المحادثات وتدفق الردود ويتكامل مع جلسات المستخدم الديناميكية.
على حد علمي، فإن Streamlit هو أسرع طريقة للحصول على تطبيق ويب قابل للتخصيص على أرض الواقع. إذا كنت تتطلع إلى إنشاء chatbot يعمل بالذكاء الاصطناعي ونشره على الواجهة الأمامية الخاصة بك، فلا يمكنني التفكير في خيار أفضل.
العائق الوحيد هو مكتبة عناصر الدردشة. فهي مضبوطة بشكل خاص جدًا على واجهة برمجة تطبيقات OpenAIوعميل Python
وهو أمر رائع، فوجود بضعة أسطر من التعليمات البرمجية للتفاعل مع بعض من أرقى التقنيات المتاحة هو أمر رائع.
ولكن هذا ليس كل شيء.
ماذا لو كنت تريد المزيد من التحكم في الروبوت الخاص بك؟ على سبيل المثال، قد ترغب في سير عمل متعدد الخطوات، أو التوليد المعزز للاسترجاع (RAG). هذه الطبقات المضافة من الوظائف تعني عمومًا تجميع مكتبات مع جميع أنواع التبعيات.
أم أنها كذلك؟
في هذا البرنامج التعليمي، سأقوم ببناء عميل chatbot مستضاف من Streamlit. سأعرض لك واجهة للتكرار السريع وروبوتات الدردشة الآلية القابلة للتخصيص بشكل كبير. بعد ذلك، ستتعلم كيفية دمج chatbot الدردشة الآلي باستخدام عميل Python مصمم خصيصًا OpenAI.
إذا كنت تقوم بوضع النماذج الأولية، فلا ينبغي أن تعيقك التبعيات والجوانب التقنية.
وانطلاقًا من روح النماذج الأولية السريعة، إذا كنت ترغب في تخطي البرنامج التعليمي والبدء في العبث بالرمز، فالكود موجود على GitHub.
القنابل بعيدًا 💣
الخطوة 1: بناء منطق Chatbot
سواءً كان ذلك لأتمتة سير العمل أو chatbotلي لحجز المواعيد، فالعالم حقاً هو محارتك هنا.
أحثك على استكشاف اتساع نطاق حالات استخدام روبوتات الدردشة الآلية من GenAI إذا كنت تبحث عن الإلهام. من أجل التبسيط، سأعود إليكم مع الساقي الذي نأمل أن يكون مشهورًا الآن، وينونا.
يمكن تحقيق روبوتنا الصغير المتطور والمفيد في بضع خطوات فقط. سأكون مختصراً، ولكن هناك العديد من البرامج التعليمية المطولة والمفيدة للغاية التي يمكنك تصفحها.
1. إعطاء التعليمات
في الاستوديو، سننتقل إلى الصفحة الرئيسية في الشريط الجانبي الأيسر.

يجب أن ترى قسم التعليمات في المقدمة والوسط. انقر عليه لإضافة التعليمات أو تعديلها بنص عادي.

هذا يعطي الروبوت الخاص بنا توجيهات وشخصية وحواجز حماية. باستخدام لغة بسيطة، يمكنك توجيه الروبوت الخاص بك بفعالية كبيرة نحو السلوك المطلوب. اجعله يبدو أكثر إنسانية، و
2. بناء التدفق
هذا هو المكان الذي توجد فيه صواميل ومسامير شخصية الروبوت: الوصول إلى معلومات محددة، وخطوات صارمة بخطوة، وتنفيذ التعليمات البرمجية، وما إلى ذلك.
لا تستهين بقوة البساطة. عقدة مستقلة واحدة تنافس وظائف وكلاء التفكير. لدي واحدة موصولة بقاعدة المعرفة (KB).

3. إضافة قاعدة المعرفة
إذا كانت التعليمات تتعلق بالمشاعر، فإن الـ KB تتعلق بالحقائق الباردة والقاسية. في حالتي، الحقائق المعنية هي النبيذ الموجود في مجموعة بيانات مراجعات النبيذ، وهي قائمة بالنبيذ وأوصافه وأسعاره. سوف أتعامل مع هذا كمخزون فعلي للنبيذ من أجل الروبوت الخاص بنا لتحويله إلى سوميلير.
سأنقر على الجداول في اللوحة اليمنى وأضغط على جدول جديد في أعلى يسار الصفحة، وأطلق عليه اسمًا وصفيًا.

انقر على علامة الحذف الرأسية (⋮) في أعلى اليمين، واضغط على استيراد.

قم بسحب ملف .csv الخاص بك إلى النموذج المنبثق واتبع الخطوات التي تظهر على الشاشة.
لجعل الجدول في متناول الروبوت الخاص بك، انتقل إلى قواعد المعرفة في الشريط الجانبي الأيسر.

انقر على أيقونة الجدول الأخضر الصغير وحدد المصدر ذي الصلة. انقر فوق إضافة جداول.

تأكد من أن التدفق لديك إمكانية الوصول إلى قاعدة المعرفة وستكون جاهزاً للعمل.

الخطوة 2: إضافة تكامل واجهة برمجة تطبيقات Chat
نقطة الاتصال بين البوت وعميلنا المحلي هي واجهة برمجة تطبيقات Chat . لإضافة ذلك إلى الروبوت الخاص بنا، سأقوم بالتمرير إلى قنوات الاتصال واضغط على ... المزيد.

اطلع على عمليات التكامل إذا كنت ترغب في ذلك. نحن نبحث عن Chat. اضطررت إلى التمرير قليلاً للعثور عليه.

انقر على التكامل واضغط على تثبيت التكامل في النموذج المنبثق.

بمجرد التثبيت، سترى معرّف واجهة برمجة تطبيقاتChat في نهاية عنوان URL الخاص webhook . ستحتاج إلى ذلك في وقت لاحق.
الخطوة 3: اكتب عميل بايثون
تعرض واجهة برمجة التطبيقات Chat عددًا من نقاط النهاية لإجراء عمليات غير مفيدة على المستخدمين والمحادثات والرسائل. كما وعدتك، سأقوم بتجميعها في عميل Python يمكن أن يحل محل عميل OpenAI .
1. أضف أوراق اعتمادك
class BotpressClient:
def __init__(self, api_id=None, user_key=None):
self.api_id = api_id or os.getenv("CHAT_API_ID")
self.user_key = user_key or os.getenv("USER_KEY")
self.base_url = f"{BASE_URI}/{self.api_id}"
self.headers = {
**HEADERS,
"x-user-key": self.user_key,
}
لك مطلق الحرية في إضافة معرف واجهة برمجة تطبيقات Chat إلى ملف .env - فهو يساعد في تصحيح الأخطاء، ولكنه ليس ضروريًا تمامًا. سنتعامل مع معرف واجهة برمجة التطبيقات ومفتاح المستخدم عندما ننشئ تطبيق Streamlit.
أحتفظ BASE_URI
و الرؤوس
في ملف منفصل الثوابت.py
ملف، للفوضى.
# constants.py
BASE_URI = "https://chat.botpress.cloud"
HEADERS = {
"accept": "application/json",
"Content-Type": "application/json",
}
2. إنشاء طرق الطلب
def _request(self, method, path, json=None):
url = f"{self.base_url}{path}"
try:
response = requests.request(method, url, headers=self.headers, json=json)
response.raise_for_status()
return response.json()
except requests.HTTPError:
return response.status_code, response.text
# --- Core API Methods ---
def get_user(self):
return self._request("GET", "/users/me")
def create_user(self, name, id):
user_data = {"name": name, "id": id}
return self._request("POST", "/users", json=user_data)
def set_user_key(self, key):
self.user_key = key
self.headers["x-user-key"] = key
def create_and_set_user(self, name, id):
new_user = self.create_user(name, id)
self.set_user_key(new_user["key"])
def create_conversation(self):
return self._request("POST", "/conversations", json={"body": {}})
def list_conversations(self):
return self._request("GET", "/conversations")
def get_conversation(self, conversation_id):
return self._request("GET", f"/conversations/{conversation_id}")
def create_message(self, message, conversation_id):
payload = {
"payload": {"type": "text", "text": message},
"conversationId": conversation_id,
}
return self._request("POST", "/messages", json=payload)
def list_messages(self, conversation_id):
return self._request("GET", f"/conversations/{conversation_id}/messages")
كما ذكرنا، جميع هذه الخوادم تقريبًا مرتبطة بنقطة نهاية في واجهة برمجة التطبيقات. أنا فقط أقوم بتغليفها في فئة.
3. إنشاء مستمع SSE
هذا هو مدى الاختراق. للاستماع إلى تحديثات المحادثة والتكرار في واجهة Streamlit الأمامية، يحتاج العميل إلى طريقة للاستماع إلى - وإنتاج - الأحداث المرسلة من الخادم من الروبوت الخاص بنا.
def listen_conversation(self, conversation_id):
url = f"{self.base_url}/conversations/{conversation_id}/listen"
for event in sseclient.SSEClient(url, headers=self.headers):
print(event.data)
if event.data == "ping":
continue
data = json.loads(event.data)["data"]
yield {"id": data["id"], "text": data["payload"]["text"]}
تأخذ هذه الدالة معرف_المحادثة (الذي سيتم الوصول إليه برمجيًا داخل التطبيق) وتنتج البيانات الواردة عند حدوثها.
الخطوة 4: إنشاء تطبيق Streamlit
بعد أن وضعنا كل شيء في صف واحد، حان الوقت لبناء chatbot. لاحظ أنني أتبع دليل Streamlit الخاص بـ Streamlit حول إنشاء تطبيق دردشة LLM -مع بعض الميزات المضافة.
1. تكييف الكود النموذجي
من الناحية النظرية، يمكنك تشغيل التطبيق بأقل قدر من التغييرات على القالب في مثال Streamlit.
# app.py
from client import BotpressClient
import streamlit as st
from constants import CONVERSATION_ID
st.title("Botpress Front-end for Streamlit")
client = BotpressClient(
api_id=st.secrets["CHAT_API_ID"], user_key=st.secrets["USER_KEY"]
)
if "messages" not in st.session_state:
messages = client.list_messages(CONVERSATION_ID)
next_token = messages["meta"]["nextToken"]
st.session_state.messages = messages["messages"][::-1]
for message in st.session_state.messages:
with st.chat_message(message["userId"]):
st.markdown(message["payload"]["text"])
if prompt := st.chat_input("*wine*-d it up"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
client.create_message(prompt, conversation_id=CONVERSATION_ID)
with st.chat_message("assistant"):
response_box = st.empty()
last_rendered = ""
for message in client.listen_conversation(CONVERSATION_ID):
message_id = message["id"]
message_text = message["text"]
if message_id != last_rendered:
last_rendered = message_id
response_box.markdown(message_text)
st.session_state.messages.append(
{"role": "assistant", "content": message_text}
)
نحن نقرأ المتغيرات السرية هنا. لذا أنشئ ملف .streamlit/secrets.toml وضع متغيراتك بداخله:
CHAT_API_ID = "معرّف_API_خاص بك"
USER_KEY = "مفتاح_المستخدم_خاص بك"
يتم رفع الأحمال الثقيلة في:
with st.chat_message("assistant"):
response_box = st.empty()
last_rendered = ""
for message in client.listen_conversation(CONVERSATION_ID):
message_id = message["id"]
message_text = message["text"]
if message_id != last_rendered:
last_rendered = message_id
response_box.markdown(message_text)
st.session_state.messages.append(
{"role": "assistant", "content": message_text}
)
حيث يتصل العميل بعناصر الدردشة لتسليم واستقبال الرسائل.
هذا يعمل، ولكن هذا ليس مثاليًا لعدة أسباب:
- يجب أن تكون قد أنشأت محادثة جديدة بشكل منفصل.
- سيتم تنسيق الرسائل القديمة بشكل مختلف عن الرسائل الجديدة، لأنها لا تحتوي على تعيين الدور (مستخدم أو مساعد).
- لا يمكنك تبديل المحادثات.
2. إنشاء المحادثات بشكل ديناميكي
عند البدء من الصفر، سأقوم تلقائيًا بإنشاء محادثة جديدة أو فتح أحدث محادثة:
# app.py
from client import BotpressClient
import streamlit as st
st.title("Botpress Front-end for Streamlit")
client = BotpressClient(
api_id=st.secrets["CHAT_API_ID"], user_key=st.secrets["users"][0]["key"]
)
# user info
user = client.get_user()
user_id = user["user"]["id"]
conversations = client.list_conversations()["conversations"]
conversation_ids = [conv["id"] for conv in conversations]
# conversation
def create_conversation():
res = client.create_conversation()
print(f"Created new conversation: {res}")
conversation_id = res["conversation"]["id"]
st.session_state.active_conversation = conversation_id
st.session_state.messages = []
st.rerun()
if not conversations:
create_conversation()
if "active_conversation" not in st.session_state:
st.session_state["active_conversation"] = conversations[0]["id"]
لاحظ أنني قمت بتعديل المفاتيح السرية لتتمكن من تخزين عدة مستخدمين. ستحتاج إلى تعديل .streamlit/أسرار.toml
الملف ليعكس ذلك:
[[المستخدمون]]
المفتاح = "مفتاح_مستخدمك"
يمكنك تكرار هذه الكتلة بقدر ما تريد، وتخزين المستخدمين كمصفوفة من الجداول.
3. السماح للمستخدمين بإنشاء المحادثات والتبديل بينها
كما يقول العنوان، يؤدي هذا إلى إنشاء قائمة منسدلة في الأعلى مع زر للسماح لك باختيار محادثتك.
col1, col2 = st.columns([5, 1])
with col1:
conversation_id = st.selectbox(
"Select Conversation",
options=[conv["id"] for conv in conversations],
index=conversation_ids.index(st.session_state.active_conversation),
)
with col2:
st.markdown("<div style='height: 1.9em'></div>", unsafe_allow_html=True)
if st.button("➕"):
create_conversation()
selected_conversation = client.get_conversation(conversation_id)
4. تعيين الدور الصحيح للرسائل السابقة
سنحل مشكلة التنسيق من أعلاه عن طريق تعيين دور المستخدم أو المساعد لكل من الرسائل السابقة:
if (
"messages" not in st.session_state
or st.session_state.get("active_conversation") != conversation_id
):
st.session_state.active_conversation = conversation_id
st.session_state.messages = []
messages = client.list_messages(conversation_id)
next_token = messages["meta"].get("nextToken")
for message in messages["messages"][::-1]:
role = "user" if message["userId"] == user_id else "assistant"
text = message["payload"]["text"]
st.session_state.messages.append({"role": role, "content": text})
هذا يطابق الكود الخاص بنا مع البنية التي يتوقعها Streamlit.
5. إضافة منطق المراسلة
هذا هو نفسه تقريبًا كما كان من قبل، مع تكييفه مع الهيكل الجديد.
# display chat history
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("*wine*-d it up"):
st.session_state.messages.append({"role": "user", "content": prompt})
client.create_message(prompt, conversation_id=conversation_id)
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
stream = client.listen_conversation(conversation_id=conversation_id)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})
5. إنشاء مستخدم
المنطق جاهز، ولكنك ستحتاج إلى إنشاء مستخدم لتشغيل التطبيق. اخترت إضافة هذا بشكل منفصل لمحاكاة تجربة الاشتراك في الخدمة. لحسن حظك، كتبت أيضًا نصًا برمجيًا:
# create_user.py
import argparse
from pathlib import Path
from client import *
from constants import *
secrets_path = Path(".streamlit") / "secrets.toml"
template = """[[users]]
key="{}"
"""
client = BotpressClient()
def create_user(name, id, add_to_secrets=True):
res = client.create_user(name, id)
if not add_to_secrets:
return res
secrets_path.touch(exist_ok=True)
with open(secrets_path, "a") as f:
f.write(template.format(res["user"]["id"], res["key"]))
return res
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Create a Botpress user and optionally store secrets."
)
parser.add_argument("--name", required=True, help="Display name of the user.")
parser.add_argument(
"--id", required=True, help="User ID. If omitted, one is generated by the API."
)
parser.add_argument("--chat_api_id", help="ID for the Botpress Chat API integration. Taken from `.env` file if not provided.")
parser.add_argument(
"--no-secrets",
action="store_true",
help="Do not append to .streamlit/secrets.toml.",
)
args = parser.parse_args()
print(f"Creating user: {args.name} (ID: {args.id or 'auto-generated'})")
result = create_user(name=args.name, id=args.id, add_to_secrets=not args.no_secrets)
print("✅ User created:")
print(result)
شريطة أن يكون لديك معرّف واجهة برمجة تطبيقات Chat الخاص بك، يمكنك التشغيل:
python create_user.py -اسمك_اسمك-اسمك-اسمك-معرف SOME_USER_ID -chat_API_ID YOUR_CHAT_API_ID
سيتعامل هذا مع إنشاء المستخدم وإضافته إلى ملف الأسرار الخاص بك.
الخطوة 5: تشغيل التطبيق
بعد بناء المنطق الخاص بك وإنشاء المستخدم الخاص بك، حان الوقت لتجربة هذا التطبيق. قم بتثبيت التبعيات وتشغيله:
Streamlit تشغيل التطبيق.py
وبهذه البساطة، سترى الروبوت الخاص بنا بكل مجده.

قم بتشغيل chatbot Streamlit اليوم
إذا كنت تقوم بعمل نماذج أولية باستخدام Streamlit، فأنت تعلم أن قابلية التخصيص لا ينبغي أن تأتي على حساب الراحة. روبوتات الدردشة الآلية موجودة لحل المشاكل - وليس لخلقها.
يأتي Botpress مع أداة إنشاء مرئية بالسحب والإفلات، وعشرات من عمليات التكامل الرسمية، ونقاط نهاية واجهة برمجة التطبيقات التي يمكن الوصول إليها. بهذه الطريقة يمكنك البناء والتكرار والنشر عبر العديد من قنوات التواصل.
ابدأ البناء اليوم. إنه مجاني.
الأسئلة الأكثر تداولًا
لماذا أختار Streamlit بدلاً من أطر عمل الواجهة الأمامية الأخرى لإنشاء chatbot
يمكنك اختيار Streamlit لإنشاء chatbot إذا كنت تريد حلاً سريعًا قائمًا على Python يتيح لك وضع نموذج أولي لتطبيقات تفاعلية بسرعة دون الحاجة إلى خبرة في الواجهة الأمامية، لأنه يتعامل مع عناصر واجهة المستخدم مثل مكونات الدردشة وإدارة الحالة بأقل قدر من التعليمات البرمجية.
هل chatbot Streamlit مناسب للاستخدام في الإنتاج أم للنماذج الأولية فقط؟
يعد chatbot لي Streamlit رائعًا للنماذج الأولية والأدوات الداخلية، ولكن بالنسبة لتطبيقات الإنتاج التي تواجه الجمهور مع حركة مرور كثيفة أو تصميم متقدم، قد تحتاج إلى طبقات إضافية مثل البروكسيات العكسية وتقوية الأمان وربما إطار عمل أمامي أكثر قوة للتعامل مع الحجم.
ما مدى قابلية تخصيص شكل ومظهر chatbot الذي تم إنشاؤه باستخدام Streamlit؟
على الرغم من أن Streamlit يتيح لك ضبط التصميم الأساسي مثل الألوان والخطوط والتخطيط، إلا أنه أقل مرونة من أطر الويب التقليدية؛ للحصول على تصميمات مخصصة حقًا، ستحتاج إلى تضمين HTML / CSS أو JavaScript مخصص، وهو أمر يمكن القيام به ولكنه يضيف تعقيدًا مقارنة باستخدام أدوات Streamlit المدمجة.
هل يمكنني دمج chatbot Streamlit في موقع ويب موجود، أم يجب أن يعمل بشكل مستقل؟
عادةً ما يتم تشغيل chatbot Streamlit كتطبيق ويب مستقل على عنوان URL الخاص به، ولكن يمكنك تضمينه في موقع ويب موجود عبر إطار iframe، على الرغم من أن هذا يتطلب التعامل مع اعتبارات التصميم والأمان لجعل التجربة المدمجة سلسة للمستخدمين.
ما هي تكلفة نشر chatbot Streamlit للاستخدام العام؟
يمكن أن يكون نشر chatbot Streamlit مجانيًا إذا تمت استضافته محليًا أو على سحابة Streamlit Community Cloud للتطبيقات الأصغر، ولكن للاستخدام العام على نطاق واسع، تتراوح التكاليف بين 5 إلى 50 دولارًا أمريكيًا شهريًا على المنصات السحابية مثل Heroku أو AWS أو DigitalOcean، اعتمادًا على متطلبات حركة المرور ووقت التشغيل.