برنامه نویسی

ساخت یک چت بات با معماری AWS با LangChain

اگر با چارچوب AWS Well-Architected Framework آشنا هستید، می‌دانید که مجموعه‌ای از بهترین روش‌ها را ارائه می‌دهد که به شما کمک می‌کند تا زیرساخت‌های امن، با کارایی بالا، انعطاف‌پذیر و کارآمد را برای برنامه‌هایتان به دست آورید. اما با حجم وسیعی از اطلاعات موجود، پیمایش در چارچوب می تواند یک کار دلهره آور باشد.

به همین دلیل است که تصمیم گرفتم یک ربات چت برای پاسخ به سؤالات مربوط به چارچوب ایجاد کنم و به توسعه دهندگان پاسخ های سریع و دقیق را با پیوندهای سند پشتیبانی ارائه دهد. اگر به چگونگی شروع این پروژه علاقه مند هستید، توصیه می کنم پست قبلی من را بررسی کنید.

اکنون، در این مقاله بعدی، من شما را از طریق فرآیند ساخت یک نسخه پیشرفته از چت بات با استفاده از کتابخانه منبع باز، LangChain، راهنمایی می کنم.

مکالمه چت بات چارچوب با معماری خوب AWS

LangChain عملکرد برنامه‌های کاربردی مدل زبان بزرگ (LLM) را افزایش می‌دهد و ویژگی‌هایی مانند مدیریت سریع، زنجیره‌ای برای دنباله‌های تماس و تولید داده‌های افزوده را ارائه می‌دهد. این راهنمای گام به گام شامل موارد زیر می شود:

• جمع آوری داده ها
• ایجاد جاسازی متن
• مهندسی سریع
• توسعه رابط چت

می توانید چت بات را در اینجا امتحان کنید.

و مخزن GitHub را با کد اینجا بررسی کنید.

جمع آوری داده ها: حذف وب

برای به دست آوردن تمام پیوندهای لازم از چارچوب Well-Architected، تمام URL ها را از نقشه سایت استخراج کردم. نقشه های سایت لیستی از تمام پیوندهای موجود در صفحه را ارائه می دهند که به من امکان می دهد به طور موثر یک اسکریپت برای واکشی تمام متن برای هر صفحه ایجاد کنم. در اینجا تابع پایتونی است که من استفاده کردم:

def extract_urls_from_sitemap(sitemap_url):
    response = requests.get(sitemap_url)
    if response.status_code != 200:
        print(f"Failed to fetch sitemap: {response.status_code}")
        return []

    sitemap_content = response.content
    root = ET.fromstring(sitemap_content)

    # Extract the URLs from the sitemap
    urls = [
        elem.text
        for elem in root.iter("{http://www.sitemaps.org/schemas/sitemap/0.9}loc")
    ]

    return urls


 # Site maps for the AWS Well-Architected Framework
    sitemap_url_list = [
        "https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sitemap.xml",
        "https://docs.aws.amazon.com/wellarchitected/latest/framework/sitemap.xml",
        "https://docs.aws.amazon.com/wellarchitected/latest/operational-excellence-pillar/sitemap.xml",
        "https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/sitemap.xml",
        "https://docs.aws.amazon.com/wellarchitected/latest/performance-efficiency-pillar/sitemap.xml",
        "https://docs.aws.amazon.com/wellarchitected/latest/cost-optimization-pillar/sitemap.xml",
        "https://docs.aws.amazon.com/wellarchitected/latest/sustainability-pillar/sitemap.xml",
    ]

    # Get all links from the sitemaps
    full_sitemap_list = []
    for sitemap in sitemap_url_list:
        full_sitemap_list.extend(extract_urls_from_sitemap(sitemap))
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

هنگامی که فهرست را گردآوری کردم، از لودر سند سلنیوم LangChain برای استخراج تمام متن از هر صفحه استفاده کردم و متن را به قطعات 1000 کاراکتری تقسیم کردم. شکستن متن به قطعات 1000 کاراکتری، مدیریت حجم زیادی از داده ها را ساده می کند و تضمین می کند که متن در بخش های قابل هضم مفیدی برای پردازش مدل قرار دارد.

def load_html_text(sitemap_urls):
    loader = SeleniumURLLoader(urls=sitemap_urls)
    data = loader.load()

    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20)
    texts = text_splitter.split_documents(data)

    return texts
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد جاسازی متن

در مرحله بعد، با استفاده از API تعبیه‌سازی OpenAI، برای هر یک از صفحات، جاسازی‌های متنی ایجاد کردم. تعبیه‌های متن بردار (فهرست) اعداد ممیز شناور هستند که برای اندازه‌گیری ارتباط رشته‌های متنی استفاده می‌شوند. آنها معمولاً برای کارهای مختلفی مانند جستجو، خوشه بندی، توصیه ها، تشخیص ناهنجاری، اندازه گیری تنوع و طبقه بندی استفاده می شوند. هنگامی که جاسازی‌ها ایجاد شدند، از کتابخانه جستجوی برداری Faiss برای ایجاد نمایه استفاده کردم که امکان جستجوی سریع متن برای هر درخواست کاربر را فراهم می‌کرد.

def embed_text(texts, save_loc):
    embeddings = OpenAIEmbeddings(openai_api_key=os.environ["OPENAI_API_KEY"])
    docsearch = FAISS.from_documents(texts, embeddings)

    docsearch.save_local(save_loc)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خط لوله انتقال کامل را در اینجا بررسی کنید.

ساخت زنجیره LLM: مهندسی سریع

با آماده بودن داده ها، زمان ساخت زنجیره LLM برای پاسخ به پرسش های کاربر فرا رسیده بود. اولین مرحله شامل ایجاد یک PromptTemplate است، که طرحی است که نشان دهنده یک درخواست است که می تواند به یک LLM ارسال شود. این الگو شامل یک دستور سیستم و دو متغیر بود: سوال کاربر و زمینه از چارچوب Well-Architected مربوط به سوال.

TEMPLATE = """You are an AWS Certified Solutions Architect. Your role is to help customers understand best practices on building on AWS. Return your response in markdown, so you can bold and highlight important steps for customers. If the answer cannot be found within the context, write 'I could not find an answer' 

Use the following context from the AWS Well-Architected Framework to answer the user's query. Make sure to read all the context before providing an answer.\nContext:\n{context}\nQuestion: {question}
"""

QA_PROMPT = PromptTemplate(template=TEMPLATE, input_variables=["question", "context"])
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در مرحله بعد، من این فرآیند را برای استفاده از LLM برای پاسخ به سؤالات کاربر تنظیم کردم. من مدل OpenAI را با استفاده از ChatOpenAI کلاس و پارامترها را تنظیم کنید (توجه داشته باشید: شما به کلید OpenAI API خود نیاز دارید). سپس، نقطه پایانی embeddings را برای پرس و جوهای کاربر و ذخیره برداری محلی از داده های خراشیده شده ایجاد کردم. در نهایت، من راه اندازی ConversationalRetrievalChain، که ایجاد یک ربات چت را با استفاده از تولید افزوده بازیابی (RAG) با استفاده از اسناد برای پاسخ آن تسهیل می کند.

def setup_chain():
    llm = ChatOpenAI(
        temperature=0.7,
        openai_api_key=os.environ["OPENAI_API_KEY"],
        model_name="gpt-3.5-turbo",
    )
    embeddings = OpenAIEmbeddings(openai_api_key=os.environ["OPENAI_API_KEY"])
    vectorstore = FAISS.load_local("local_index", embeddings)

    chain = ConversationalRetrievalChain.from_llm(
        llm, vectorstore.as_retriever(), return_source_documents=True
    )

    return chain

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کد کامل اینجاست

ایجاد رابط چت

رابط چت با استفاده از Streamlit، یک ابزار همه کاره برای ساخت برنامه های کاربردی وب تعاملی پایتون، توسعه یافته است. این کد یک رابط ساده با یک ورودی متنی برای درخواست های کاربر و یک دکمه “ارسال” برای ارسال درخواست ایجاد می کند. هنگامی که دکمه “ارسال” کلیک می شود، پرس و جو به همراه سابقه چت به زنجیره LLM ارسال می شود که یک پاسخ همراه با اسناد ارجاع شده را برمی گرداند.

def app() -> None:
    """
    Purpose:
        Controls the app flow
    Args:
        N/A
    Returns:
        N/A
    """

    # Spin up the sidebar
    sidebar()

    with st.container():
        # Load chat history
        for index, chat in enumerate(st.session_state["chat_history"]):
            message_func(chat[0], True)
            message_func(chat[1], False)

            # st.write(chat[0])
            # st.write(chat[1])
            with st.expander("Resources"):
                for doc in st.session_state["docs"][index]:
                    st.write(doc.metadata["source"])
                    st.write(doc.page_content)

        with st.form(key="my_form", clear_on_submit=True):
            query = st.text_input(
                "Query: ",
                key="input",
                value="",
                placeholder="Type your query here...",
                label_visibility="hidden",
            )
            submit_button = st.form_submit_button(label="Submit")
        col1, col2 = st.columns([1, 3.2])
        reset_button = col1.button("Reset Chat History")

    if submit_button:
        with st.spinner("Generating..."):
            result = chain(
                {"question": query, "chat_history": st.session_state["chat_history"]}
            )
            st.session_state["chat_history"].append(
                (result["question"], result["answer"])
            )
            st.session_state["docs"].append(result["source_documents"])
            st.experimental_rerun()  # Add Chat to UI

    if reset_button:
        st.session_state["chat_history"] = []
        st.session_state["docs"] = []
        st.experimental_rerun()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شما می توانید کد کامل را در اینجا پیدا کنید.

نتیجه

در این راهنما، من شما را از طریق فرآیند ساخت ربات چت با معماری AWS با استفاده از LangChain، مدل OpenAI GPT و Streamlit آشنا کرده‌ام. ما با جمع‌آوری داده‌ها از چارچوب AWS Well-Architected شروع کردیم، به ایجاد تعبیه‌های متنی پرداختیم و در نهایت از LangChain برای فراخوانی OpenAI LLM برای تولید پاسخ‌ها به درخواست‌های کاربر استفاده کردیم.

در اینجا می توانید با ربات چت تعامل کنید.

اگر علاقه مند به ایجاد برنامه های کاربردی خود با استفاده از LangChain هستید، امیدوارم این راهنما بینش ها و دستورالعمل های مفیدی را ارائه کرده باشد. از کدنویسی و کاوش در امکانات مدل های زبان لذت ببرید!

به یاد داشته باشید، ربات‌های گفتگو ابزار قدرتمندی برای ساده‌سازی فرآیندهای پیچیده و دسترسی بیشتر به اطلاعات هستند. آنها را می توان برای رفع نیازهای مختلف طراحی کرد و با ابزارهای مناسب مانند LangChain و OpenAI، ایجاد یک ربات چت هوشمند و آگاه از زمینه آسان تر از آن چیزی است که فکر می کنید. ساخت ربات مبارک!

درباره نویسنده

بانجو یک مدافع توسعه‌دهنده ارشد در AWS است، جایی که به سازندگان کمک می‌کند تا در مورد استفاده از AWS هیجان‌زده شوند. بانجو علاقه زیادی به عملیاتی کردن داده ها دارد و یک پادکست، یک جلسه و پروژه های منبع باز را در مورد استفاده از داده ها راه اندازی کرده است. زمانی که بانجو چیز بزرگ بعدی را نمی سازد، دوست دارد با انجام بازی های ویدیویی، به خصوص JRPG، و کاوش در رویدادهایی که در اطرافش اتفاق می افتد، استراحت کند.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا