Bu yazıda size iki teknolojiyi ( LangChain ve Anthropic ) nasıl birleştireceğinizi ve arama destekli bir kişisel asistanın nasıl oluşturulacağını göstermek istiyoruz.
Hackathonlarımıza katılanlar tarafından giderek daha fazla yapay zeka ürünü oluşturuluyor. Geliştiriciler için bir sonraki fırsat, her katılımcının Google Cloud'un en son teknolojisini kullanarak kendi AI uygulamasını oluşturma şansına sahip olduğu Google Cloud Vertex AI ile ortak hackathonumuzdur. Burada yapay zekanın giderek önemi artan bir uygulamasından bahsedeceğiz: arama motorları .
Arama destekli kişisel asistan, kullanıcılara bilgi bulma, rezervasyon yapma, hatırlatıcı ayarlama ve mesaj gönderme gibi görevlerde yardımcı olmak için arama motoru teknolojisini kullanan bir dijital asistandır. Bu asistanlar, çeşitli kaynaklardan veri toplamak ve analiz etmek için arama algoritmalarını kullanır ve bu verileri kullanıcılara yararlı ve kısa bir şekilde sunar.
Arama destekli kişisel asistanların öne çıkan örnekleri Google Asistan , Siri , Alexa ve Cortana'dır . Bu asistanlar, doğru ve ilgili bilgileri sağlamak, görevleri tamamlamak ve kullanıcıyla etkileşimde bulunurken yanıtlarını geliştirmek için arama yeteneklerini etkili bir şekilde kullanır.
Anthropic, gelişmiş yapay zeka sistemleri geliştirmeye odaklanmış bir araştırma kuruluşudur. En son yarattıkları Claude, yardımsever, dürüst ve zararsız olacak şekilde tasarlanmış yeni nesil bir yapay zeka asistanıdır. Bu son teknoloji model, çeşitli görevlerde yüksek derecede güvenilirlik ve öngörülebilirlik sağlar.
Claude'un temel özellikleri şunlardır:
Çok yönlü konuşma ve metin işleme yetenekleri
Kullanıcı güvenliğini ve gizliliğini birinci öncelik olarak korumak
Claude'un birincil kullanım durumları şunlardır:
Özetleme
Aramak
Yaratıcı ve işbirlikçi yazma
Soru-Cevap
Kodlama yardımı
Bu özellikler, Claude'u çok çeşitli uygulamalar için ideal bir yapay zeka aracı haline getiriyor ve farklı alanlardaki kullanıcılara güç veriyor.
LangChain, uçtan uca dil modeli uygulamaları oluşturmaya yönelik çok yönlü bir araçtır. Dil Öğrenme Modellerini (LLM'ler) oluşturma, yönetme ve dağıtma sürecini basitleştiren sağlam bir çerçeve sağlar. LLM'ler, çeşitli dillerde ve görevlerde insan benzeri metinleri anlamak, oluşturmak ve işlemek için tasarlanmış gelişmiş yapay zeka modelleridir.
LLM'ler için istemlerin verimli yönetimi
Karmaşık iş akışları için görev zincirleri oluşturma yeteneği
Yapay zekaya durum ekleme, önceki etkileşimlerden gelen bilgileri hatırlamasına olanak sağlama
Bu yetenekler, LangChain'i çeşitli uygulamalardaki dil modellerinin potansiyelinden yararlanmak için güçlü ve kullanıcı dostu bir platform haline getirir.
Flask'ı Yükleyin : Başlamak için ortamınızda Flask'ın kurulu olduğundan emin olun. Bunu pip
kullanarak yapabilirsiniz:
pip install Flask
Yeni bir dizin oluşturun : Projeniz için yeni bir dizin oluşturun ve ona gidin:
mkdir claude-langchain cd claude-langchain
Sanal ortam oluşturun (isteğe bağlı) : Python projeleriyle çalışırken sanal ortam kullanmak iyi bir uygulamadır. venv
veya seçtiğiniz başka bir aracı kullanarak bir tane oluşturabilirsiniz:
python -m venv venv source venv/bin/activate (Linux/Mac) venv\Scripts\activate (Windows)
Bir main.py
dosyası oluşturun: Flask uygulama kodunuzu yazmak için bir main.py
dosyası oluşturun:
touch app.py # Linux/Mac echo.>app.py # Windows
Flask uygulama kodunuzu yazın : main.py
dosyasını favori kod düzenleyicinizde açın ve aşağıdaki kodu ekleyin:
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' if __name__ == '__main__': app.run()
Flask uygulamasını çalıştırın : main.py
dosyasını kaydedin ve terminalinizde/komut isteminizde aşağıdaki komutu çalıştırın:
python main.py
Tarayıcınızı açın : Tercih ettiğiniz web tarayıcısını açın ve http://127.0.0.1:5000/ adresine gidin. "Merhaba Dünya!" görmelisiniz. web sayfasında görüntülenir.
Ve bu kadar! Bir Flask projesini başarıyla başlattınız ve basit bir uygulama oluşturdunuz.
Python-dotenv ve langchain'i yükleyin : Ortam değişkenlerini bir .env
dosyasıyla kolayca yönetmek için python-dotenv
paketini kullanacağız. Aynı zamanda langchain
kurulumunu da yapalım. Her iki paketi de pip
kullanarak yükleyin:
pip install python-dotenv langchain
Bir .env
dosyası oluşturun: Projenizin kök dizininde bir .env
dosyası oluşturun:
touch .env # Linux/Mac echo.>.env # Windows
Ortam değişkenleri ekleyin : .env
dosyasını favori kod düzenleyicinizde açın ve ortam değişkenlerinizi ekleyin. Her değişken ANAHTAR=DEĞER biçiminde yeni bir satırda olmalıdır:
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxx SERPAPI_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Lütfen hem Anthropic'in Claude modeli hem de SerpAPI'nin web arama hizmeti için API anahtarına sahip olmanız gerektiğini unutmayın.
Ortam değişkenlerini yükleyin : python-dotenv
kullanarak ortam değişkenlerini .env
dosyasından yüklemek için main.py
dosyanızı değiştirin. main.py
dosyanızı aşağıdaki gibi güncelleyin:
import os from flask import Flask from dotenv import load_dotenv load_dotenv() app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' if __name__ == '__main__': app.run()
Sürüm kontrolünde .env
dosyasını dikkate almayın : Sürüm kontrolünde gizli anahtarlar gibi hassas bilgilerin paylaşılmaması önemlidir. Git kullanıyorsanız .gitignore
dosyanıza aşağıdaki satırı ekleyin (eğer yoksa bir tane oluşturun):
.env
Artık Flask projeniz .env
dosyasındaki ortam değişkenlerini kullanacak şekilde ayarlandı. Gerektiğinde daha fazla değişken ekleyebilir ve bunlara os.environ.get('KEY')
kullanarak erişebilirsiniz. .env
dosyasını gizli tutmayı ve onu hiçbir zaman sürüm kontrolüne devretmeyi unutmayın.
Bu eğitim, Node.js, npm, React ve Typescript hakkında temel bilgiye sahip olan orta düzey kullanıcılar için tasarlanmıştır. Stillendirme için Tailwind CSS ile birlikte bu teknolojileri içeren bir yığın kullanacağız. Bu yığın, sağlamlığı, çok yönlülüğü ve bu teknolojilere yönelik güçlü topluluk desteği nedeniyle seçildi. Ek olarak, uygulamamızın doğru, insan benzeri metin yanıtları oluşturmasına olanak tanıyacak iki güçlü yapay zeka teknolojisi olan Anthropic'in Claude modelini ve LangChain'i entegre edeceğiz.
İşletim sisteminiz için Node.js yükleyicisini resmi siteden indirin.
Node.js ve npm'yi yüklemek için kurulum talimatlarını izleyin. Çoğu kullanıcı için LTS (Uzun Süreli Destek) sürümü önerilir.
Kurulduktan sonra terminalinizden Node.js ve npm sürümlerini kontrol ederek kurulumu doğrulayın:
düğüm -v npm -v
Create React App (CRA), yeni bir React.js uygulaması oluşturmamıza yardımcı olan bir komut satırı yardımcı programıdır. Bunu global olarak npm aracılığıyla kuracağız:
npm install -g create-react-app
ai-assistant-claude
adında yeni bir proje oluşturmak için CRA'yı TypeScript şablonuyla birlikte kullanacağız.
npx create-react-app ai-assistant-claude --template typescript
Bu komut, mevcut dizinimizde ai-assistant-claude
adında, Typescript destekli yeni bir React uygulamasını barındıran yeni bir dizin oluşturur.
Bu eğitimde izlenen adımlar resmi Tailwind CSS belgelerine dayanmaktadır. Daha güncel talimatlar için bu belgelere bakın.
TailwindCSS'i yükleyerek ve kütüphaneyi projemizde başlatarak başlayacağız:
npm install -D tailwindcss npx tailwindcss init
Daha sonra şablon yollarımızı tailwind.config.js
dosyasına ekleyerek yapılandırıyoruz. ++
ekleyeceğiniz satırları belirtir:
/** @type {import('tailwindcss').Config} */ module.exports = { -- content: [], ++ content: [ ++ "./src/**/*.{js,jsx,ts,tsx}", ++ ], theme: { extend: {}, }, plugins: [], }
Son olarak, Tailwind katmanlarının her biri için @tailwind
yönergelerini ./src/index.css
dosyamıza ekleyeceğiz:
@tailwind base; @tailwind components; @tailwind utilities;
Ve işte! Tailwind CSS artık projemize entegre edildi.
Kodlama kısmına geçmeden önce fontawesome
, react-markdown
, axios
, react-hook-form
gibi gerekli kütüphaneleri yükleyerek hazırlıklarımızı tamamlayalım.
npm i --save @fortawesome/fontawesome-svg-core npm install --save @fortawesome/free-solid-svg-icons npm install --save @fortawesome/react-fontawesome
npm install --save react-markdown
Bu adımlar tamamlandıktan sonra projeniz gerekli tüm araç ve kütüphanelerle kurulur. Daha sonra, doğru ve insan benzeri metin yanıtları oluşturmak için Anthropic'in Claude API'sini ve LangChain'i kullanan yapay zeka asistanı uygulamasını oluşturmaya başlayacağız.
Yükleme veya kurulum sırasında herhangi bir sorunla karşılaşırsanız, işte birkaç genel çözüm:
Diğer sorunlar için ilgili kitaplıkların belgelerine bakın veya sorunlarınızı StackOverflow'a veya ilgili GitHub depolarına gönderin.
Bu bölümde daha önce başlattığımız Flask uygulamasına geri döneceğiz ve /ask
ve /search
gibi yeni uç noktalar ekleyeceğiz. Bunlar, basit sohbet ve gelişmiş sohbet özelliklerimiz (ikincisi Google arama sonuçları tarafından desteklenmektedir) için uç noktalar olarak hizmet verecektir.
Gerekli modüllerimizi içe aktararak başlayalım:
from flask import Flask, jsonify, request from dotenv import load_dotenv from langchain.chat_models import ChatAnthropic from langchain.chains import ConversationChain from langchain.agents import Tool from langchain.agents import AgentType from langchain.utilities import SerpAPIWrapper from langchain.agents import initialize_agent from langchain.memory import ConversationBufferMemory from langchain.prompts.chat import ( ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate, ) load_dotenv() app = Flask(__name__)
Yukarıdaki bölüm gerekli tüm paketleri içe aktarır ve Flask uygulamamızı başlatır.
Sunucumuzun düzgün çalışıp çalışmadığını test etmek için temel bir uç nokta ( /
) oluşturarak başlayacağız:
@app.route('/') def hello_world(): return 'Hello, World!'
Kök URL'yi ziyaret ettiğimizde, sunucumuzun beklendiği gibi çalıştığını belirten "Merhaba Dünya!" yanıtını almalıyız.
/ask
Uç Noktasını oluşturmaBu uç nokta, uygulamamızın temel sohbet özelliği için mesajları işler. İstekten JSON verilerini okur, mesajları işler ve Anthropic'in Claude modelini ve LangChain'i kullanarak bir yanıt oluşturur.
@app.route('/ask', methods=['POST']) def ask_assistant(): # The code for /ask endpoint goes here
İstekten Mesajları Çıkarma
Öncelikle herhangi bir verinin sağlanıp sağlanmadığını kontrol etmemiz ve mesajları buradan çıkarmamız gerekiyor.
data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message")
Yanıtın Oluşturulması
Aşağıdaki kod bölümü, LangChain'in ChatAnthropic()
modelini ve sohbetimizi yapılandırmak için ChatPromptTemplate
kullanarak sohbet yanıtını oluşturur. Konuşma geçmişi ConversationBufferMemory
kullanılarak saklanır.
llm = ChatAnthropic() input = "" message_list = [] for message in messages: if message['role'] == 'user': message_list.append( HumanMessagePromptTemplate.from_template(message['content']) ) input = message['content'] elif message['role'] == 'assistant': message_list.append( AIMessagePromptTemplate.from_template(message['content']) ) # Adding SystemMessagePromptTemplate at the beginning of the message_list message_list.insert(0, SystemMessagePromptTemplate.from_template( "The following is a friendly conversation between a human and an AI. The AI is talkative and " "provides lots of specific details from its context. The AI will respond with plain string, replace new lines with \\n which can be easily parsed and stored into JSON, and will try to keep the responses condensed, in as few lines as possible." )) message_list.insert(1, MessagesPlaceholder(variable_name="history")) message_list.insert(-1, HumanMessagePromptTemplate.from_template("{input}")) prompt = ChatPromptTemplate.from_messages(message_list) memory = ConversationBufferMemory(return_messages=True) conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm) result = conversation.predict(input=input)
Yanıtı oluşturduktan sonra sonuçtaki yeni satırları değiştirip onu bir JSON nesnesi olarak döndürüyoruz.
print(result) return jsonify({"status": "success", "message": result})
/search
Uç Noktasını oluşturma /search
uç noktası /ask
benzer ancak daha ayrıntılı yanıtlar sağlamak için arama işlevini içerir. Bu özelliği eklemek için SerpAPIWrapper
kullanıyoruz.
@app.route('/search', methods=['POST']) def search_with_assistant(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") llm = ChatAnthropic() # Get the last message with 'user' role user_messages = [msg for msg in messages if msg['role'] == 'user'] last_user_message = user_messages[-1] if user_messages else None # If there is no user message, return an error response if not last_user_message: return jsonify({"error": "No user message found"}), 400 input = last_user_message['content'] search = SerpAPIWrapper() tools = [ Tool( name = "Current Search", func=search.run, description="useful for when you need to answer questions about current events or the current state of the world" ), ] chat_history = MessagesPlaceholder(variable_name="chat_history") memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent_chain = initialize_agent( tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True, memory=memory, agent_kwargs = { "memory_prompts": [chat_history], "input_variables": ["input", "agent_scratchpad", "chat_history"] } ) result = agent_chain.run(input=input) print(result) return jsonify({"status": "success", "message": result})
Son olarak Flask uygulamamızı çalıştırmak için standart ortak metni ekliyoruz.
if __name__ == '__main__': app.run()
Her şey yolunda giderse işte son arka uç kodumuz.
from flask import Flask, jsonify, request from dotenv import load_dotenv from langchain.chat_models import ChatAnthropic from langchain.chains import ConversationChain from langchain.agents import Tool from langchain.agents import AgentType from langchain.utilities import SerpAPIWrapper from langchain.agents import initialize_agent from langchain.memory import ConversationBufferMemory from langchain.prompts.chat import ( ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate, ) load_dotenv() app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' @app.route('/ask', methods=['POST']) def ask_assistant(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") llm = ChatAnthropic() input = "" message_list = [] for message in messages: if message['role'] == 'user': message_list.append( HumanMessagePromptTemplate.from_template(message['content']) ) input = message['content'] elif message['role'] == 'assistant': message_list.append( AIMessagePromptTemplate.from_template(message['content']) ) # Adding SystemMessagePromptTemplate at the beginning of the message_list message_list.insert(0, SystemMessagePromptTemplate.from_template( "The following is a friendly conversation between a human and an AI. The AI is talkative and " "provides lots of specific details from its context. The AI will respond with plain string, replace new lines with \\n which can be easily parsed and stored into JSON, and will try to keep the responses condensed, in as few lines as possible." )) message_list.insert(1, MessagesPlaceholder(variable_name="history")) message_list.insert(-1, HumanMessagePromptTemplate.from_template("{input}")) prompt = ChatPromptTemplate.from_messages(message_list) memory = ConversationBufferMemory(return_messages=True) conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm) result = conversation.predict(input=input) print(result) return jsonify({"status": "success", "message": result}) @app.route('/search', methods=['POST']) def search_with_assistant(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") llm = ChatAnthropic() # Get the last message with 'user' role user_messages = [msg for msg in messages if msg['role'] == 'user'] last_user_message = user_messages[-1] if user_messages else None # If there is no user message, return an error response if not last_user_message: return jsonify({"error": "No user message found"}), 400 input = last_user_message['content'] search = SerpAPIWrapper() tools = [ Tool( name = "Current Search", func=search.run, description="useful for when you need to answer questions about current events or the current state of the world" ), ] chat_history = MessagesPlaceholder(variable_name="chat_history") memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent_chain = initialize_agent( tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True, memory=memory, agent_kwargs = { "memory_prompts": [chat_history], "input_variables": ["input", "agent_scratchpad", "chat_history"] } ) result = agent_chain.run(input=input) print(result) return jsonify({"status": "success", "message": result}) if __name__ == '__main__': app.run()
Şimdi uygulamamızı test edelim. Bu komutla arka uç uygulamasını çalıştırın, ayrıca lütfen sanal ortamımızın etkinleştirildiğinden emin olun.
flask run
Terminalimiz bu çıktıyı döndürürse her şeyin yoluna gireceğini bileceğiz.
Daha fazla uzatmadan, iki uç noktamızı, /ask
ve /search
test edelim. İkisini birbirinden ayırmak için her birine benzer payload gönderelim. REST API test ve dokümantasyon yazılımınızı açın veya yalnızca cURL'yi kullanın. Ancak bu derste Insomnia'yı kullanacağım.
Öncelikle /ask
uç noktasını aşağıdaki payload ile çağıralım. Diyelim ki " The Legend of Zelda: Breath of the Wild " adlı video oyununun devamı hakkında soru sordum. Yanlış cevap verecektir. Devam filmi hakkında henüz bir duyuru yapılmayan modelin 2021 yılı sonu itibarıyla eğitim kesintisi olması nedeniyle bu beklenen bir durumdur.
/search
uç noktasına ne dersiniz? Kodumuzu daha önce fark ettiyseniz, bu uç nokta Agent kullanan daha karmaşık bir zincirle yönetiliyor.
Agent'ı kullanarak, daha önce gösterdiğimiz gibi kendi kusurlarına sahip olan kendi modelinden daha fazla araç sağlayarak, yapay zekaya karar vermede daha fazla güç verebiliriz.
/search
uç noktasının nasıl çalıştığını göstermek için, onu öncekiyle aynı veri yüküyle çağıralım.
Bu sefer işe yaradı! Kaputun altında nasıl çalışıyor? terminalimizdeki çıktıya bakalım.
İlginçtir ki, bu sefer yapay zeka modeli hemen yanıt vermedi, ancak yanıt vermek için ne yapılması gerektiği konusunda 'düşünüyor' gibi görünüyordu. Web arama sonucunda "Haber aramasına göre The Legend of Zelda: Tears of the Kingdom adlı devam filmi duyurulmuş gibi görünüyor" gözlemini yaptıktan sonra cevap vermeye karar verdi.
Yani bu mantıkla /search
uç noktasını kullanmamız gerekmez mi? daha doğru ve dolayısıyla daha akıllı olduğu için mi? Pek değil. Normalde, sohbet robotu tabanlı bir uygulamada, botun önceki konuşmaların içeriğini koruması beklenir, böylece konuşmanın tüm içeriğini 'hatırlıyor'muş gibi yanıtlar verebilir. Bakalım /search
uç noktası bunu yapabilecek mi?
/search
uç noktasının az önce sorduğumuz şeyi hatırlayıp hatırlamadığını test edelim.
Bunun nedeni, LangChain kütüphanesinin geçmiş konuşmaları saklamak için kullanılabilecek bellek zinciri özelliğine sahip olmasına rağmen, web sunucusu ve bunun üzerine inşa edilen REST API hizmetinin doğası gereği durum bilgisiz olmasıdır. Bu, web sunucusunun her isteği yeni bir istek olarak ele alacağı anlamına gelir.
Ama daha önceki konuşmaları payload olarak dahil etmedik mi? Bu iyi bir soru. LangChain'de kullanılan Aracı zincirinin şu anda hem kullanıcının hem de yapay zekanın istek ve yanıtlarından oluşan oluşturulmuş istemlerin işlenmesini desteklemediği ortaya çıktı. Bunu esas olarak model için örnek konuşmalar sağlamak ve modeli istediğimiz yanıta göre daha da ayarlamak için kullanırız.
Ajan ise tek bir talimat alarak çalışır ve düşünce zincirlerini onun etrafında geliştirir. Bu nedenle görüşmelerimiz ne kadar uzun olursa olsun temsilci yalnızca en son talebe yanıt verecektir.
Farkı görmek için /ask
uç noktamızı test edelim.
Bu sefer, geçmiş konuşmalarımızı ek bağlam olarak kullanarak cevap verdi! Artık AI Assistant uygulamamızı oluşturmak için her iki uç noktaya da ihtiyacımız olduğunu fark ettik. Peki hem modası geçmiş ama her zaman hatırla /ask
uç noktasını unutkan ama kapsamlı ve güncel /search
uç noktasıyla nasıl birleştireceğiz? Elbette ön ucu oluşturarak!
ai-assistant-claude
proje dizinine geri dönelim. Bu projede, giriş noktası dosyası App.tsx
ile başlayarak React bileşenlerimizi değiştirmeye başlayacağız.
import React from 'react'; import logo from './logo.svg'; import './App.css'; import { ChatClient } from './ChatClient'; function App() { return ( <div> <ChatClient/> </div> ); } export default App;
Yukarıdaki kod parçasında bir sonraki adımda oluşturulacak olan ChatClient
bileşenini içe aktarıyoruz. Daha sonra <div>
öğesinin içine <ChatClient/>
bileşenini ekliyoruz. Bu, React bileşenlerini kullanan AI asistan uygulamamızın yapısını ayarlar.
import React, { useState } from 'react'; import { ChatInput } from './ChatInput'; import { ChatHistory } from './ChatHistory'; export interface Message { content: string; role: string; } export const ChatClient: React.FC = () => { const [messages, setMessages] = useState<Array<Message>>([]); const [isLoading, setIsLoading] = useState(false) const handleSimpleChat = (message: string) => { // Send the message and past chat history to the backend // Update messages state with the new message let newMessages = [...messages, { content: message, role: 'user' }] setMessages(newMessages); let postData = { message: newMessages } setIsLoading(true) fetch('/ask', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }) .then((response) => response.json()) .then((data) => { if (data.status === "success") { setMessages([...newMessages, { content: data.message, role: 'assistant' }]) } setIsLoading(false) console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); setIsLoading(false) }); }; const handleAdvancedChat = (message: string) => { // Trigger AI agent with Google Search functionality // Update messages state with the new message and AI response let newMessages = [...messages, { content: message, role: 'user' }] setMessages(newMessages); let postData = { message: newMessages } setIsLoading(true) fetch('/search', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }) .then((response) => response.json()) .then((data) => { if (data.status === "success") { setMessages([...newMessages, { content: data.message, role: 'assistant' }]) } console.log('Success:', data); setIsLoading(false) }) .catch((error) => { console.error('Error:', error); setIsLoading(false) }); }; return ( <div className="h-screen bg-gray-100 dark:bg-gray-900 flex items-center justify-center"> <div className='flex flex-col items-center gap-2'> <h1 className='text-white text-xl'>AI Assistant with Claude and LangChain</h1> <div className="w-full max-w-md h-[80vh] bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden flex flex-col"> <ChatHistory messages={messages} isLoading={isLoading} /> <ChatInput onSimpleChat={handleSimpleChat} onAdvancedChat={handleAdvancedChat} /> </div> </div> </div> ); };
Bu bileşen, yapay zeka asistanımız için birincil kullanıcı arayüzü görevi görür. Gösterildiği gibi, konuşma geçmişini görüntülemek için bir ChatHistory
bileşeni ve metin girişi için bir ChatInput
bileşeni içerir.
Bileşen, ChatInput
bileşeninden gelen girişi işler, bu girişi kullanarak arka uca istekler gönderir ve ardından bir yükleme durumu görüntüler. İstek başarılı bir şekilde işlenirse bileşen, arka uçtan alınan yanıtı da gösterecektir.
import React from 'react'; import { ReactMarkdown } from 'react-markdown/lib/react-markdown'; import { Message } from './ChatClient'; interface ChatHistoryProps { messages: Array<Message>; isLoading: boolean } export const ChatHistory: React.FC<ChatHistoryProps> = ({ messages, isLoading }) => { return ( <div className="p-4 h-full overflow-y-auto"> {messages.map((message, index) => ( <div key={index} className={`mb-3 ${ message.role === 'user' ? 'text-right' : 'text-left' }`} > <ReactMarkdown className={`inline-block px-3 py-2 rounded-md ${ index % 2 === 0 ? 'bg-gray-300 dark:bg-gray-700' : 'bg-blue-200 dark:bg-blue-900' }`} > {message.content} </ReactMarkdown> </div> ))} {isLoading && ( <div className="mb-3 text-left"> <ReactMarkdown className="inline-block px-3 py-2 rounded-md bg-blue-200 dark:bg-blue-900 animate-pulse" > {/* Put your desired loading content here */} Thinking... </ReactMarkdown> </div> )} </div> ); };
Neyse ki TailwindCSS, basit animasyonlar için animate-pulse
gibi yerleşik yardımcı sınıflar sunar. Bu sınıf, bir isteğin yanıt beklediğini zarif bir şekilde belirtmeye yardımcı olur. Bu bileşende mesajların konumlandırılmasını da "kullanıcı" ve "asistan"dan ayırıyoruz.
import React, { useState } from 'react'; interface ChatInputProps { onSimpleChat: (message: string) => void; onAdvancedChat: (message: string) => void; } export const ChatInput: React.FC<ChatInputProps> = ({ onSimpleChat, onAdvancedChat }) => { const [input, setInput] = useState(''); const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { setInput(event.target.value); }; const handleSubmit = (handler: (message: string) => void) => { handler(input); setInput(''); }; return ( <div className="flex p-4 border-t border-gray-200 dark:border-gray-700"> <input type="text" value={input} onChange={handleInputChange} placeholder="Type your message..." className="flex-grow px-3 py-2 rounded-md bg-gray-200 text-gray-900 dark:bg-gray-700 dark:text-gray-100 focus:outline-none" /> <button onClick={() => handleSubmit(onSimpleChat)} className="ml-2 px-4 py-2 font-semibold text-gray-600 bg-white dark:text-gray-400 dark:bg-gray-800 border border-gray-300 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none" > Ask </button> <button onClick={() => handleSubmit(onAdvancedChat)} className="ml-2 px-4 py-2 font-semibold text-white bg-blue-500 border border-blue-600 rounded-md hover:bg-blue-400 focus:outline-none" > Ask and Search </button> </div> ); };
Son olarak metin girişimize iki buton ekledik. İlk düğme, girişi herhangi bir ek geliştirme olmadan AI modelini kullanarak işleyen /ask
uç noktasına göndermek için kullanılır.
Bu uç nokta bağlama duyarlıdır. Uygun bir şekilde "Sor ve Ara" olarak adlandırılan ikinci düğme, girişi /search
uç noktasına gönderir. Bu düğme, girdiyi yapay zeka modeli aracılığıyla işlemenin yanı sıra, durum gerektiriyorsa yapay zeka odaklı bir web aramasını da tetikler.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <!-- manifest.json provides metadata used when your web app is installed on a user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> -- <title>React App</title> ++ <title>Claude AI Assistant</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> <!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the <body> tag. To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> </body> </html>
Son dokunuş olarak, index.html
sayfasındaki uygulamamızın başlığını " React App " yerine " Claude AI Assistant " olarak değiştirerek güncelliyoruz.
{ "name": "ai-assistant-claude", "version": "0.1.0", "private": true, ++ "proxy": "http://localhost:5000", "dependencies": {
Son olarak package.json
dosyasına proxy konfigürasyonunu ekleyip http://localhost:5000
olarak ayarlıyoruz. Bu, farklı bağlantı noktalarının kullanılmasından kaynaklanan CORS sınırlamalarını atlamamıza yardımcı olur.
Teste başlamak için öncelikle arka uç uygulamasının (claude-langchain) zaten çalıştığından emin olun.
Ardından dizini ön uç uygulamaya (ai-assistant-claude) değiştirin ve aşağıdaki komutu kullanarak uygulamayı başlatın:
npm start
Uygulamanın oluşturulması biraz zaman alabilir. Hazır olduğunda tarayıcınızda localhost:3000
konumunda otomatik olarak açılacaktır.
Hem bağlam farkındalığını hem de arama özelliğini test edelim! Öncelikle SEGA'nın son Yakuza oyununun devamı olan ve henüz 2021 yılında çıkacağı duyurulmayan başka bir video oyununa bakalım. Ayrıca bu oyunda önceki oyunlardan sevilen karakter Kazuma Kiryu'nun bulunup bulunmadığını da soracağız. Bunu yapmak için " Sor " düğmesini tıklayın.
Düşünmek için birkaç saniye verin...
Şaşırtıcı bir şekilde yapay zeka yanlış yanıt verdi. Yakuza: Like a Dragon gerçekten de en son Yakuza oyunudur ancak başrolde farklı bir kahraman olan Ichiban Kasuga yer almaktadır. Soruyu yeniden yazalım ve bu kez " Sor ve Ara " butonunu kullanalım.
Artık yapay zekanın internette arama yapması gerekip gerekmediğine karar vermesi daha uzun sürdü. Bir web aramasının gerekli olduğunu belirledikten ve tatmin edici bir yanıt bulduktan sonra, bilgiyi müşteriye/ön uca geri gönderdi.
Bu sefer, gerçekten de baş kahraman olarak Kazuma Kiryu'nun yer aldığı "Ejderha Gaiden Gibi: Adını Silinen Adam" başlığını geri getiriyor.
Büyüleyici, değil mi? Geniş Dil Modeli tarafından desteklenen aracı, mevcut kaynaklar (arama) göz önüne alındığında hangi eylemlerin gerekli olduğunu tahmin eder ve tatmin edici bir yanıt sağlar. LangChain modeli, istemleri (modele yönelik talimatlar) ve aracılar ve araçlar gibi diğer özellikleri bağlamayı ve "zincirlemeyi" kolaylaştırır.
Bu uygulamayı oluşturmaktan ve bu teknolojiler hakkında bilgi edinmekten keyif aldığınızı umuyoruz. Daha derine inmek isteyenler için, ön uç ve arka uç için tamamlanmış projeye erişebilirsiniz.
Ortaklarımızın gerçekleştirdiği en son teknolojilerle tasarım yapmak istiyorsanız bir sonraki yapay zeka mücadelesinde bize katılın!
*please see lablab.ai for all terms and conditions