1. Giriş
Merhaba. Temsilciler fikrini sevdiniz. Parmaklarınızı bile kıpırdatmadan işlerinizi halledebilecek küçük yardımcılar, değil mi? Mükemmel! Ancak dürüst olalım, özellikle daha büyük ve karmaşık projelerle uğraşırken tek bir müşteri temsilcisi her zaman yeterli olmayacaktır. Muhtemelen bir ekipten yardım almanız gerekecek. İşte bu noktada çok ajanslı sistemler devreye girer.
Temsilciler, LLM'ler tarafından desteklendiğinde eski moda sabit kodlamaya kıyasla inanılmaz bir esneklik sağlar. Ancak, her şeyin bir olumsuz yönü vardır. Bu yöntemler de kendi zorluklarıyla birlikte gelir. Bu atölyede tam da bu konuyu ele alacağız.
Bu eğitimde şunları öğreneceksiniz:
LangGraph ile İlk Temsilcinizi Oluşturma: Popüler bir çerçeve olan LangGraph'ı kullanarak kendi temsilcinizi oluşturacağız. Temsilcinizi yalnızca LLM'lerle değil, mevcut hizmetlerle de etkileşime geçirebilmek için veritabanlarına bağlanan araçları nasıl oluşturacağınızı, internette arama yapmak için en son Gemini 2 API'yi nasıl kullanacağınızı ve istemleri ve yanıtları nasıl optimize edeceğinizi öğreneceksiniz. Ayrıca işlev çağırmanın nasıl işlediğini de göstereceğiz.
Size Özel Temsilci Koordinasyonu: Basit düz yollardan daha karmaşık çok senaryolara kadar temsilcilerinizi koordine etmenin farklı yollarını keşfedeceğiz. Bu işlemi, müşteri temsilcisi ekibinizin akışını yönetmek olarak düşünebilirsiniz.
Çoklu Temsilci Sistemleri: Etkinlik odaklı bir mimari sayesinde temsilcilerinizin birlikte çalışabileceği ve işleri birlikte halledebileceği bir sistemi nasıl oluşturacağınızı öğreneceksiniz.
LLM özgürlüğü: Görev için en iyisini kullanın: Yalnızca bir LLM'yi kullanmanıza gerek yok. Sorun çözme gücünü artırmak için birden fazla LLM'yi nasıl kullanacağınızı, onlara farklı roller atayarak nasıl havalı "düşünme modelleri" oluşturacağınızı öğreneceksiniz.
Dinamik İçerik? Sorun değil: Temsilcinizi gerçek zamanlı olarak her kullanıcıya özel dinamik içerikler oluştururken hayal edin. Bunu nasıl yapacağınızı göstereceğiz.
Google Cloud ile buluta taşıma: Not defterinde oynamayı unutun. Çok aracılı sisteminizi gerçek dünyaya hazır hâle getirmek için Google Cloud'da nasıl tasarlayacağınızı ve dağıtacağınızı göstereceğiz.
Bu proje, bahsettiğimiz tüm tekniklerin nasıl kullanılacağına dair iyi bir örnek olacaktır.
2. Mimari
Öğretmen olmak veya eğitim alanında çalışmak çok tatmin edici olabilir. Ancak iş yükü, özellikle de tüm hazırlık çalışmaları zorlayıcı olabilir. Ayrıca, genellikle yeterli personel bulunmaz ve özel ders almak pahalı olabilir. Bu nedenle, yapay zeka destekli bir öğretim asistanı öneriyoruz. Bu araç, eğitimcilerin yükünü hafifletebilir ve personel eksikliği ile uygun fiyatlı özel ders eksikliğinden kaynaklanan boşluğu doldurmaya yardımcı olabilir.
Yapay zeka destekli öğretim asistanımız ayrıntılı ders planları, eğlenceli testler, kolayca anlaşılabilen sesli özetler ve kişiselleştirilmiş ödevler hazırlayabilir. Bu sayede öğretmenler en iyi yaptıkları işe odaklanabilir: Öğrencilerle bağlantı kurma ve öğrenmeye aşık olmalarına yardımcı olma.
Sistemde iki site bulunur: Biri öğretmenlerin önümüzdeki haftalar için ders planları oluşturabileceği,
ve öğrencilerin testlere, sesli özetlere ve ödevlere erişebileceği bir kanal oluşturun.
Peki, eğitim asistanımız Aidemy'i destekleyen mimariyi inceleyelim. Gördüğünüz gibi, bu süreci birkaç temel bileşene ayırdık. Bu bileşenlerin tümü, bu hedefe ulaşmak için birlikte çalışır.
Temel Mimari Öğeleri ve Teknolojileri:
Google Cloud Platform (GCP): Sistemin merkezinde yer alır:
- Vertex AI: Google'ın Gemini LLM'lerine erişir.
- Cloud Run: Container'a alınmış aracıları ve işlevleri dağıtmak için kullanılan sunucusuz platform.
- Cloud SQL: Müfredat verileri için PostgreSQL veritabanı.
- Pub/Sub ve Eventarc: Bileşenler arasında eşzamansız iletişimi sağlayan, etkinlik odaklı mimarinin temeli.
- Cloud Storage: Ses özetlerini ve ödev dosyalarını depolar.
- Gizli Anahtar Yöneticisi: Veritabanı kimlik bilgilerini güvenli bir şekilde yönetir.
- Artifact Registry: Aracılar için Docker görüntülerini depolar.
- Compute Engine: Tedarikçi firma çözümlerine güvenmek yerine kendi kendine barındırılan LLM dağıtmak için
LLM'ler: Sistemin "beyni"dir:
- Google'ın Gemini modelleri: (Gemini 1.0 Pro, Gemini 2 Flash, Gemini 2 Flash Thinking, Gemini 1.5-pro) Ders planlama, içerik oluşturma, dinamik HTML oluşturma, test açıklama ve ödevleri birleştirme için kullanılır.
- DeepSeek: Kendi kendine çalışma ödevleri oluşturma gibi özel görevler için kullanılır.
LangChain ve LangGraph: LLM Uygulama Geliştirme Çerçeveleri
- Karmaşık çok aracılı iş akışlarının oluşturulmasını kolaylaştırır.
- Araçların (API çağrıları, veritabanı sorguları, web aramaları) akıllıca koordinasyonunu sağlar.
- Sistem ölçeklenebilirliği ve esnekliği için etkinlik odaklı mimari uygular.
Özünde mimarimiz, LLM'lerin gücünü, tümüyle Google Cloud'da çalışan yapılandırılmış veriler ve olaya dayalı iletişimle birleştirir. Bu sayede ölçeklenebilir, güvenilir ve etkili bir öğretim asistanı oluşturabiliyoruz.
3. Başlamadan önce
Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun. Cloud projenizde faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını nasıl kontrol edeceğinizi öğrenin.
👉Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i (Cloud Shell bölmesinin üst kısmındaki terminal şeklindeki simge) ve ardından "Düzenleyiciyi aç" düğmesini (kalemin bulunduğu açık bir klasöre benzer) tıklayın. Bu işlem, pencerede Cloud Shell Kod Düzenleyici'yi açar. Sol tarafta bir dosya gezgini görürsünüz.
👉Aşağıdaki durum çubuğunda gösterildiği gibi Cloud Code ile oturum açma düğmesini tıklayın. Eklentiyi talimatlara göre yetkilendirin. Durum çubuğunda Cloud Code - no project (Cloud Code - proje yok) ifadesini görürseniz önce bunu, ardından açılır menüden "Select a Google Cloud Project"i (Google Cloud projesi seçin) ve oluşturduğunuz projeler listesinden belirli bir Google Cloud projesini seçin.
👉Bulut IDE'de terminali açın,
👉Terminalde, aşağıdaki komutu kullanarak kimliğinizin doğrulandığını ve projenin proje kimliğinize ayarlandığını doğrulayın:
gcloud auth list
👉Ardından şu komutu çalıştırın:
gcloud config set project <YOUR_PROJECT_ID>
👉Gerekli Google Cloud API'lerini etkinleştirmek için aşağıdaki komutu çalıştırın:
gcloud services enable compute.googleapis.com \
storage.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com \
eventarc.googleapis.com \
sqladmin.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
cloudresourcemanager.googleapis.com \
cloudfunctions.googleapis.com
Bu işlem birkaç dakika sürebilir.
Cloud Shell IDE'de Gemini Code Assist'i etkinleştirme
Sol panelde gösterildiği gibi Code Assist (Kod Yardımı) düğmesini tıklayın ve doğru Google Cloud projesini son bir kez seçin. Cloud AI Companion API'yi etkinleştirmeniz istenirse lütfen bunu yapın ve devam edin. Google Cloud projenizi seçtikten sonra, durum çubuğundaki Cloud Code durum mesajında projenizi görebildiğinizden ve sağdaki durum çubuğunda da aşağıdaki gibi Code Assist'i etkinleştirdiğinizden emin olun:
İzin ayarlama
👉Hizmet hesabı iznini ayarlama
export PROJECT_ID=$(gcloud config get project)
export SERVICE_ACCOUNT_NAME=$(gcloud compute project-info describe --format="value(defaultServiceAccount)")
echo "Here's your SERVICE_ACCOUNT_NAME $SERVICE_ACCOUNT_NAME"
İzin ver 👉Cloud Storage (Okuma/Yazma):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/storage.objectAdmin"
👉Pub/Sub (Yayınla/Al):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/pubsub.publisher"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/pubsub.subscriber"
👉Cloud SQL (Okuma/Yazma):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/cloudsql.editor"
👉Eventarc (Etkinlik Alma):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/iam.serviceAccountTokenCreator"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/eventarc.eventReceiver"
👉Vertex AI (Kullanıcı):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/aiplatform.user"
👉Secret Manager (Okuma):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role="roles/secretmanager.secretAccessor"
👉Sonuçları IAM konsolunuzda doğrulayın
4. İlk aracı oluşturma
Karmaşık çok aracılı sistemlere girmeden önce temel bir yapı taşı oluşturmamız gerekir: tek bir işlevsel aracı. Bu bölümde, basit bir "kitap sağlayıcı" aracısı oluşturarak ilk adımlarımızı atacağız. Kitap sağlayıcı aracısı, giriş olarak bir kategori alır ve bu kategoride JSON temsili kitap oluşturmak için bir Gemini LLM kullanır. Ardından bu kitap önerilerini REST API uç noktası olarak sunar .
👉Başka bir tarayıcı sekmesinde, web tarayıcınızda Google Cloud Console'u açın, gezinme menüsünde (☰) "Cloud Run"a gidin. "+ ... FONKSİYON YAZ" düğmesini tıklayın.
👉Ardından, Cloud Run işlevinin temel ayarlarını yapılandıracağız:
- Hizmet adı:
book-provider
- Bölge:
us-central1
- Çalışma süresi:
Python 3.12
- Kimlik doğrulama:
Allow unauthenticated invocations
'ten Etkin'e.
👉Diğer ayarları varsayılan olarak bırakın ve Oluştur'u tıklayın. Bu işlem sizi kaynak kod düzenleyiciye yönlendirir.
Önceden doldurulmuş main.py
ve requirements.txt
dosyalarını görürsünüz.
main.py
, işlevin iş mantığını, requirements.txt
ise gerekli paketleri içerir.
👉Artık kod yazmaya hazırız. Ancak ayrıntılara girmeden önce Gemini Code Assist'in bize avantaj sağlayıp sağlayamayacağını görelim. Cloud Shell Düzenleyici'ye dönün, Gemini Code Assist simgesini tıklayın ve istem kutusuna aşağıdaki isteği yapıştırın:
Use the functions_framework library to be deployable as an HTTP function.
Accept a request with category and number_of_book parameters (either in JSON body or query string).
Use langchain and gemini to generate the data for book with fields bookname, author, publisher, publishing_date.
Use pydantic to define a Book model with the fields: bookname (string, description: "Name of the book"), author (string, description: "Name of the author"), publisher (string, description: "Name of the publisher"), and publishing_date (string, description: "Date of publishing").
Use langchain and gemini model to generate book data. the output should follow the format defined in Book model.
The logic should use JsonOutputParser from langchain to enforce output format defined in Book Model.
Have a function get_recommended_books(category) that internally uses langchain and gemini to return a single book object.
The main function, exposed as the Cloud Function, should call get_recommended_books() multiple times (based on number_of_book) and return a JSON list of the generated book objects.
Handle the case where category or number_of_book are missing by returning an error JSON response with a 400 status code.
return a JSON string representing the recommended books. use os library to retrieve GOOGLE_CLOUD_PROJECT env var. Use ChatVertexAI from langchain for the LLM call
Ardından Code Assist, hem kaynak kodu hem de requirements.txt bağımlılık dosyası sağlayarak olası bir çözüm oluşturur.
Code Assist'in oluşturduğu kodu, aşağıda verilen test edilmiş doğru çözümle karşılaştırmanızı öneririz. Bu sayede, aracın etkinliğini değerlendirebilir ve olası tutarsızlıkları tespit edebilirsiniz. LLM'lere hiçbir zaman körü körüne güvenilmemelidir. Ancak Code Assist, hızlı prototipleme ve ilk kod yapılarını oluşturmak için mükemmel bir araç olabilir ve iyi bir başlangıç yapmak için kullanılmalıdır.
Bu bir atölye olduğundan aşağıda sağlanan doğrulanmış kodu kullanacağız. Ancak, Code Assist tarafından oluşturulan kodun özelliklerini ve sınırlamalarını daha iyi anlamak için dilediğiniz zaman deneyebilirsiniz.
👉Cloud Run işlevinin kaynak kod düzenleyicisine (diğer tarayıcı sekmesinde) dönün. main.py
öğesinin mevcut içeriğini aşağıdaki kodla dikkatlice değiştirin:
import functions_framework
import json
from flask import Flask, jsonify, request
from langchain_google_vertexai import ChatVertexAI
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from pydantic import BaseModel, Field
import os
class Book(BaseModel):
bookname: str = Field(description="Name of the book")
author: str = Field(description="Name of the author")
publisher: str = Field(description="Name of the publisher")
publishing_date: str = Field(description="Date of publishing")
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
llm = ChatVertexAI(model_name="gemini-1.0-pro")
def get_recommended_books(category):
"""
A simple book recommendation function.
Args:
category (str): category
Returns:
str: A JSON string representing the recommended books.
"""
parser = JsonOutputParser(pydantic_object=Book)
question = f"Generate a random made up book on {category} with bookname, author and publisher and publishing_date"
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | llm | parser
response = chain.invoke({"query": question})
return json.dumps(response)
@functions_framework.http
def recommended(request):
request_json = request.get_json(silent=True) # Get JSON data
if request_json and 'category' in request_json and 'number_of_book' in request_json:
category = request_json['category']
number_of_book = int(request_json['number_of_book'])
elif request.args and 'category' in request.args and 'number_of_book' in request.args:
category = request.args.get('category')
number_of_book = int(request.args.get('number_of_book'))
else:
return jsonify({'error': 'Missing category or number_of_book parameters'}), 400
recommendations_list = []
for i in range(number_of_book):
book_dict = json.loads(get_recommended_books(category))
print(f"book_dict=======>{book_dict}")
recommendations_list.append(book_dict)
return jsonify(recommendations_list)
👉requirements.txt dosyasının içeriğini aşağıdakiyle değiştirin:
functions-framework==3.*
google-genai==1.0.0
flask==3.1.0
jsonify==0.5
langchain_google_vertexai==2.0.13
langchain_core==0.3.34
pydantic==2.10.5
👉İşlev giriş noktasını ayarlayacağız: recommended
👉İşlevi dağıtmak için KAYDET VE DAĞIT'ı tıklayın. Dağıtım sürecinin tamamlanmasını bekleyin. Cloud Console'da durum gösterilir. Bu işlem birkaç dakika sürebilir.
👉Dağıtım tamamlandıktan sonra Cloud Shell düzenleyiciye dönün ve terminalde şu komutu çalıştırın:
export PROJECT_ID=$(gcloud config get project)
export BOOK_PROVIDER_URL=$(gcloud run services describe book-provider --region=us-central1 --project=$PROJECT_ID --format="value(status.url)")
curl -X POST -H "Content-Type: application/json" -d '{"category": "Science Fiction", "number_of_book": 2}' $BOOK_PROVIDER_URL
JSON biçiminde bazı kitap verileri gösterilir.
[
{"author":"Anya Sharma","bookname":"Echoes of the Singularity","publisher":"NovaLight Publishing","publishing_date":"2077-03-15"},
{"author":"Anya Sharma","bookname":"Echoes of the Quantum Dawn","publisher":"Nova Genesis Publishing","publishing_date":"2077-03-15"}
]
Tebrikler! Cloud Run işlevini başarıyla dağıttınız. Bu, Aidemy temsilcimizi geliştirirken entegre edeceğimiz hizmetlerden biridir.
5. Yapım Araçları: Aracılar RESTFUL hizmetine ve Verilere Bağlanma
Bootstrap iskelet projesini indirelim. Cloud Shell Düzenleyici'de olduğunuzdan emin olun. Terminalde şu komutu çalıştırın:
git clone https://github.com/weimeilin79/aidemy-bootstrap.git
Bu komut çalıştırıldıktan sonra Cloud Shell ortamınızda aidemy-bootstrap
adlı yeni bir klasör oluşturulur.
Cloud Shell Düzenleyici'nin Gezgin bölmesinde (genellikle sol tarafta), aidemy-bootstrap
Git deposunu klonladığınızda oluşturulan klasörü görürsünüz. Gezgin'de projenizin kök klasörünü açın. İçinde planner
alt klasörü bulunur. Bu klasörü de açın.
Müşteri temsilcilerimizin gerçekten yardımcı olmak için kullanacağı araçları oluşturmaya başlayalım. Bildiğiniz gibi LLM'ler akıl yürütme ve metin oluşturma konusunda mükemmeldir ancak gerçek dünyadaki görevleri gerçekleştirmek ve doğru, güncel bilgiler sağlamak için harici kaynaklara erişmesi gerekir. Bu araçları, aracın dünyayla etkileşim kurmasını sağlayan "İsviçre çakısı" olarak düşünebilirsiniz.
Temsilci oluştururken bir sürü ayrıntıyı sabit kodlamaya düşmek kolaydır. Bu, esnek olmayan bir temsilci oluşturur. Bunun yerine, araç oluşturarak ve kullanarak harici mantıklara veya sistemlere erişebilir. Bu sayede hem LLM hem de geleneksel programlamanın avantajlarından yararlanabilir.
Bu bölümde, öğretmenlerin ders planları oluşturmak için kullanacağı planlayıcı aracısının temelini oluşturacağız. Planlayıcı, plan oluşturmaya başlamadan önce konu ve konu hakkında daha fazla bilgi sağlayarak sınırları belirlemek istiyoruz. Üç araç oluşturacağız:
- RESTful API Çağrısı: Veri almak için önceden var olan bir API ile etkileşim kurma.
- Veritabanı Sorgusu: Bir Cloud SQL veritabanından yapılandırılmış verileri getirme.
- Google Arama: Web'deki anlık bilgilere erişme.
API'den Kitap Önerileri Getirme
Öncelikle, önceki bölümde dağıttığımız book-provider API'sinden kitap önerileri alan bir araç oluşturalım. Bu örnekte, bir temsilcinin mevcut hizmetlerden nasıl yararlanabileceği gösterilmektedir.
Cloud Shell Düzenleyici'de, önceki bölümde klonladığınız aidemy-bootstrap
projesini açın. 👉planner
klasöründeki book.py
dosyasını düzenleyin ve aşağıdaki kodu yapıştırın:
def recommend_book(query: str):
"""
Get a list of recommended book from an API endpoint
Args:
query: User's request string
"""
region = get_next_region();
llm = VertexAI(model_name="gemini-1.5-pro", location=region)
query = f"""The user is trying to plan a education course, you are the teaching assistant. Help define the category of what the user requested to teach, respond the categroy with no more than two word.
user request: {query}
"""
print(f"-------->{query}")
response = llm.invoke(query)
print(f"CATEGORY RESPONSE------------>: {response}")
# call this using python and parse the json back to dict
category = response.strip()
headers = {"Content-Type": "application/json"}
data = {"category": category, "number_of_book": 2}
books = requests.post(BOOK_PROVIDER_URL, headers=headers, json=data)
return books.text
if __name__ == "__main__":
print(recommend_book("I'm doing a course for my 5th grade student on Math Geometry, I'll need to recommend few books come up with a teach plan, few quizes and also a homework assignment."))
Açıklama:
- recommend_book(query: str): Bu işlev, kullanıcının sorgusunu giriş olarak alır.
- LLM Etkileşimi: Sorgudan kategoriyi ayıklamak için LLM'yi kullanır. Bu örnekte, araçlar için parametreler oluşturmaya yardımcı olmak amacıyla LLM'yi nasıl kullanabileceğiniz gösterilmektedir.
- API Çağrısı: Kategoriyi ve istenen kitap sayısını ileterek kitap sağlayıcı API'sine bir POST isteği gönderir.
👉Bu yeni işlevi test etmek için ortam değişkenini ayarlayın, şunu çalıştırın :
cd ~/aidemy-bootstrap/planner/
export BOOK_PROVIDER_URL=$(gcloud run services describe book-provider --region=us-central1 --project=$PROJECT_ID --format="value(status.url)")
👉Bağımlılıkları yükleyin ve çalıştığından emin olmak için kodu çalıştırın:
cd ~/aidemy-bootstrap/planner/
python -m venv env
source env/bin/activate
export PROJECT_ID=$(gcloud config get project)
pip install -r requirements.txt
python book.py
Git uyarısı pop-up penceresini yoksayın.
Kitap sağlayıcı API'sinden alınan kitap önerilerini içeren bir JSON dizesi görürsünüz.
[{"author":"Anya Sharma","bookname":"Echoes of the Singularity","publisher":"NovaLight Publishing","publishing_date":"2077-03-15"},{"author":"Anya Sharma","bookname":"Echoes of the Quantum Dawn","publisher":"Nova Genesis Publishing","publishing_date":"2077-03-15"}]
Bu mesajı görüyorsanız ilk araç düzgün çalışıyor demektir.
Belirli parametrelerle açıkça bir RESTful API çağrısı oluşturmak yerine doğal dil ("Bir kurs yapıyorum...") kullanıyoruz. Ardından müşteri temsilcisi, doğal dil anlama özelliğini kullanarak gerekli parametreleri (ör. kategori) akıllıca ayıklayarak API ile etkileşime geçmek için doğal dil anlama özelliğinden nasıl yararlandığını vurgular.
👉book.py
dosyasından aşağıdaki test kodunu kaldırın.
if __name__ == "__main__":
print(recommend_book("I'm doing a course for my 5th grade student on Math Geometry, I'll need to recommend few books come up with a teach plan, few quizes and also a homework assignment."))
Bir veritabanından müfredat verileri alma
Ardından, Cloud SQL PostgreSQL veritabanından yapılandırılmış müfredat verilerini getiren bir araç oluşturacağız. Bu sayede müşteri temsilcisi, ders planlama için güvenilir bir bilgi kaynağına erişebilir.
👉aidemy adlı bir Cloud SQL örneği oluşturmak için terminalde aşağıdaki komutları çalıştırın . Bu işlem biraz zaman alabilir.
gcloud sql instances create aidemy \
--database-version=POSTGRES_14 \
--cpu=2 \
--memory=4GB \
--region=us-central1 \
--root-password=1234qwer \
--storage-size=10GB \
--storage-auto-increase
👉Ardından, yeni örnekte aidemy-db
adlı bir veritabanı oluşturun.
gcloud sql databases create aidemy-db \
--instance=aidemy
Google Cloud Console'da Cloud SQL'de örneği doğrulayalım. Listede aidemy
adlı bir Cloud SQL örneği göreceksiniz. Ayrıntılarını görüntülemek için örnek adını tıklayın. Cloud SQL örneği ayrıntıları sayfasında, sol gezinme menüsünde "SQL Studio"yu tıklayın. Bunu yaptığınızda yeni bir sekme açılır.
Veritabanına bağlanmak için tıklayın. SQL Studio'da oturum açma
Veritabanı olarak aidemy-db
'ü seçin. Kullanıcı olarak postgres
, şifre olarak 1234qwer
girin.
👉SQL Studio sorgu düzenleyicisine aşağıdaki SQL kodunu yapıştırın:
CREATE TABLE curriculums (
id SERIAL PRIMARY KEY,
year INT,
subject VARCHAR(255),
description TEXT
);
-- Inserting detailed curriculum data for different school years and subjects
INSERT INTO curriculums (year, subject, description) VALUES
-- Year 5
(5, 'Mathematics', 'Introduction to fractions, decimals, and percentages, along with foundational geometry and problem-solving techniques.'),
(5, 'English', 'Developing reading comprehension, creative writing, and basic grammar, with a focus on storytelling and poetry.'),
(5, 'Science', 'Exploring basic physics, chemistry, and biology concepts, including forces, materials, and ecosystems.'),
(5, 'Computer Science', 'Basic coding concepts using block-based programming and an introduction to digital literacy.'),
-- Year 6
(6, 'Mathematics', 'Expanding on fractions, ratios, algebraic thinking, and problem-solving strategies.'),
(6, 'English', 'Introduction to persuasive writing, character analysis, and deeper comprehension of literary texts.'),
(6, 'Science', 'Forces and motion, the human body, and introductory chemical reactions with hands-on experiments.'),
(6, 'Computer Science', 'Introduction to algorithms, logical reasoning, and basic text-based programming (Python, Scratch).'),
-- Year 7
(7, 'Mathematics', 'Algebraic expressions, geometry, and introduction to statistics and probability.'),
(7, 'English', 'Analytical reading of classic and modern literature, essay writing, and advanced grammar skills.'),
(7, 'Science', 'Introduction to cells and organisms, chemical reactions, and energy transfer in physics.'),
(7, 'Computer Science', 'Building on programming skills with Python, introduction to web development, and cyber safety.');
Bu SQL kodu, curriculums
adlı bir tablo oluşturur ve bazı örnek veriler ekler. SQL kodunu çalıştırmak için Çalıştır'ı tıklayın. Komutların başarıyla yürütüldüğünü belirten bir onay mesajı görürsünüz.
👉Keşif aracını genişletin, yeni oluşturulan tabloyu bulun ve sorgu'yu tıklayın. Sizin için oluşturulan SQL'in yer aldığı yeni bir düzenleyici sekmesi açılır.
SELECT * FROM
"public"."curriculums" LIMIT 1000;
👉Çalıştır'ı tıklayın.
Sonuçlar tablosunda, önceki adımda eklediğiniz veri satırları gösterilir. Bu, tablonun ve verilerin doğru şekilde oluşturulduğunu gösterir.
Doldurulmuş örnek müfredat verileriyle bir veritabanı başarıyla oluşturduğunuza göre, bu verileri alacak bir araç oluşturacağız.
👉Cloud Code Editor'da aidemy-bootstrap
klasöründeki curriculums.py
dosyasını düzenleyin ve aşağıdaki kodu yapıştırın:
def connect_with_connector() -> sqlalchemy.engine.base.Engine:
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
encoded_db_user = os.environ.get("DB_USER")
print(f"--------------------------->db_user: {db_user!r}")
print(f"--------------------------->db_pass: {db_pass!r}")
print(f"--------------------------->db_name: {db_name!r}")
ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC
connector = Connector()
def getconn() -> pg8000.dbapi.Connection:
conn: pg8000.dbapi.Connection = connector.connect(
instance_connection_name,
"pg8000",
user=db_user,
password=db_pass,
db=db_name,
ip_type=ip_type,
)
return conn
pool = sqlalchemy.create_engine(
"postgresql+pg8000://",
creator=getconn,
pool_size=2,
max_overflow=2,
pool_timeout=30, # 30 seconds
pool_recycle=1800, # 30 minutes
)
return pool
def init_connection_pool() -> sqlalchemy.engine.base.Engine:
return (
connect_with_connector()
)
raise ValueError(
"Missing database connection type. Please define one of INSTANCE_HOST, INSTANCE_UNIX_SOCKET, or INSTANCE_CONNECTION_NAME"
)
def get_curriculum(year: int, subject: str):
"""
Get school curriculum
Args:
subject: User's request subject string
year: User's request year int
"""
try:
stmt = sqlalchemy.text(
"SELECT description FROM curriculums WHERE year = :year AND subject = :subject"
)
with db.connect() as conn:
result = conn.execute(stmt, parameters={"year": year, "subject": subject})
row = result.fetchone()
if row:
return row[0]
else:
return None
except Exception as e:
print(e)
return None
db = init_connection_pool()
Açıklama:
- Ortam Değişkenleri: Kod, veritabanı kimlik bilgilerini ve bağlantı bilgilerini ortam değişkenlerinden alır (bu konu hakkında daha fazla bilgiyi aşağıda bulabilirsiniz).
- connect_with_connector(): Bu işlev, veritabanıyla güvenli bir bağlantı kurmak için Cloud SQL bağlayıcısını kullanır.
- get_curriculum(yıl: int, konu: str): Bu işlev, yıl ve konuyu giriş olarak alır, müfredatlar tablosunu sorgular ve ilgili müfredat açıklamasını döndürür.
👉Kodu çalıştırmadan önce bazı ortam değişkenleri ayarlamamız gerekir. Terminalde şunları çalıştırın:
export PROJECT_ID=$(gcloud config get project)
export INSTANCE_NAME="aidemy"
export REGION="us-central1"
export DB_USER="postgres"
export DB_PASS="1234qwer"
export DB_NAME="aidemy-db"
👉Test etmek için curriculums.py
dosyasının sonuna aşağıdaki kodu ekleyin:
if __name__ == "__main__":
print(get_curriculum(6, "Mathematics"))
👉Kodu çalıştırın:
cd ~/aidemy-bootstrap/planner/
source env/bin/activate
python curriculums.py
6. sınıf Matematik müfredatının açıklamasını konsolda görürsünüz.
Expanding on fractions, ratios, algebraic thinking, and problem-solving strategies.
Müfredat açıklamasını görüyorsanız veritabanı aracı düzgün çalışıyor demektir. Ctrl+C
tuşuna basarak komut dosyasını durdurun.
👉curriculums.py
dosyasından aşağıdaki test kodunu kaldırın.
if __name__ == "__main__":
print(get_curriculum(6, "Mathematics"))
👉Sanal ortamdan çıkın, terminalde şunu çalıştırın:
deactivate
6. Yapım Araçları: Web'den anlık bilgilere erişme
Son olarak, web'deki anlık bilgilere erişmek için Gemini 2 ve Google Arama entegrasyonunu kullanan bir araç oluşturacağız. Bu, temsilcinin güncel kalmasına ve alakalı sonuçlar sunmasına yardımcı olur.
Gemini 2'nin Google Search API ile entegrasyonu, daha doğru ve bağlamla alakalı arama sonuçları sağlayarak müşteri temsilcisi özelliklerini geliştirir. Bu sayede temsilciler güncel bilgilere erişebilir ve yanıtlarını gerçek verilere dayandırarak halüsinasyonları en aza indirebilir. İyileştirilmiş API entegrasyonu, daha doğal dil sorguları yapılmasını da kolaylaştırarak temsilcilerin karmaşık ve ayrıntılı arama istekleri oluşturmasını sağlar.
Bu işlev, giriş olarak bir arama sorgusu, müfredat, konu ve yıl alır ve internetten alakalı bilgileri almak için Gemini API'yi ve Google Arama aracını kullanır. Yakından bakarsanız başka bir çerçeve kullanmadan işlev çağrısı yapmak için Google Üretken Yapay Zeka SDK'sını kullandığını görebilirsiniz.
👉aidemy-bootstrap
klasöründeki search.py
dosyasını düzenleyin ve aşağıdaki kodu yapıştırın:
model_id = "gemini-2.0-flash-001"
google_search_tool = Tool(
google_search = GoogleSearch()
)
def search_latest_resource(search_text: str, curriculum: str, subject: str, year: int):
"""
Get latest information from the internet
Args:
search_text: User's request category string
subject: "User's request subject" string
year: "User's request year" integer
"""
search_text = "%s in the context of year %d and subject %s with following curriculum detail %s " % (search_text, year, subject, curriculum)
region = get_next_region()
client = genai.Client(vertexai=True, project=PROJECT_ID, location=region)
print(f"search_latest_resource text-----> {search_text}")
response = client.models.generate_content(
model=model_id,
contents=search_text,
config=GenerateContentConfig(
tools=[google_search_tool],
response_modalities=["TEXT"],
)
)
print(f"search_latest_resource response-----> {response}")
return response
if __name__ == "__main__":
response = search_latest_resource("What are the syllabus for Year 6 Mathematics?", "Expanding on fractions, ratios, algebraic thinking, and problem-solving strategies.", "Mathematics", 6)
for each in response.candidates[0].content.parts:
print(each.text)
Açıklama:
- Araç tanımlama - google_search_tool: GoogleSearch nesnesini bir Araç içine sarmalama
- search_latest_resource(search_text: str, subject: str, year: int): Bu işlev, giriş olarak bir arama sorgusu, konu ve yıl alır ve Google araması yapmak için Gemini API'yi kullanır. Gemini modeli
- GenerateContentConfig: GoogleSearch aracına erişimi olduğunu tanımlayın
Gemini modeli, search_text parametresini dahili olarak analiz eder ve soruyu doğrudan yanıtlayıp yanıtlayamayacağını veya GoogleSearch aracını kullanıp kullanamayacağını belirler. Bu, LLM'nin akıl yürütme sürecinde gerçekleşen kritik bir adımdır. Model, harici araçların gerekli olduğu durumları tanıyacak şekilde eğitilmiştir. Model Google Arama aracını kullanmaya karar verirse gerçek çağrıyı Google Üretken Yapay Zeka SDK'sı yapar. SDK, modelin kararını ve oluşturduğu parametreleri alır ve Google Arama API'sine gönderir. Bu bölüm, kodda kullanıcıdan gizlenir.
Gemini modeli daha sonra arama sonuçlarını yanıtına entegre eder. Bu bilgiler, kullanıcının sorusunu yanıtlamak, özet oluşturmak veya başka bir görevi gerçekleştirmek için kullanılabilir.
👉Test etmek için kodu çalıştırın:
cd ~/aidemy-bootstrap/planner/
export PROJECT_ID=$(gcloud config get project)
source env/bin/activate
python search.py
"5. Sınıf Matematik Müfredatı" ile ilgili arama sonuçlarını içeren Gemini Search API yanıtını görürsünüz. Tam çıkış, arama sonuçlarına bağlıdır ancak aramayla ilgili bilgiler içeren bir JSON nesnesi olacaktır.
Arama sonuçları görüyorsanız Google Arama aracı düzgün çalışıyor demektir. Ctrl+C
tuşuna basarak komut dosyasını durdurun.
👉Ardından, koddaki son kısmı kaldırın.
if __name__ == "__main__":
response = search_latest_resource("What are the syllabus for Year 6 Mathematics?", "Expanding on fractions, ratios, algebraic thinking, and problem-solving strategies.", "Mathematics", 6)
for each in response.candidates[0].content.parts:
print(each.text)
👉Sanal ortamdan çıkın, terminalde şunu çalıştırın:
deactivate
Tebrikler! Planlama aracınız için üç güçlü araç oluşturdunuz: API bağlayıcı, veritabanı bağlayıcı ve Google Arama aracı. Bu araçlar, temsilcinin etkili öğretim planları oluşturmak için ihtiyaç duyduğu bilgilere ve özelliklere erişmesini sağlar.
7. LangGraph ile düzenleme
Artık ayrı ayrı araçlarımızı oluşturduğumuza göre LangGraph'ı kullanarak bunları koordine etme zamanı geldi. Bu sayede, kullanıcının isteğine göre hangi araçların ne zaman kullanılacağına akıllıca karar verebilecek daha gelişmiş bir "planlayıcı" aracısı oluşturabiliriz.
LangGraph, büyük dil modellerini (LLM'ler) kullanarak durum bilgisine sahip, çok aktörlü uygulamalar oluşturmayı kolaylaştırmak için tasarlanmış bir Python kitaplığıdır. Bunu, LLM'ler, araçlar ve diğer temsilcileri içeren karmaşık sohbetleri ve iş akışlarını koordine etmek için bir çerçeve olarak düşünebilirsiniz.
Temel Kavramlar:
- Grafik Yapısı: LangGraph, uygulamanızın mantığını yönlendirilmiş bir grafik olarak temsil eder. Grafikteki her düğüm, işlemdeki bir adımı (ör. bir LLM çağrısı, araç çağrısı, koşullu kontrol) temsil eder. Kenarlar, düğümler arasındaki yürütme akışını tanımlar.
- Durum: LangGraph, grafikte ilerlerken uygulamanızın durumunu yönetir. Bu durum, kullanıcının girişi, araç çağrılarının sonuçları, LLM'lerden gelen ara çıkışlar ve adımlar arasında korunması gereken diğer tüm bilgiler gibi değişkenleri içerebilir.
- Düğümler: Her düğüm bir hesaplamayı veya etkileşimi temsil eder. Bu kullanıcılar:
- Araç Düğümleri: Bir araç kullanın (ör. web araması yapma, veritabanı sorgulama)
- İşlev Düğümleri: Python işlevi yürütür.
- Kenar: Düğümleri bağlayarak yürütme akışını tanımlar. Bu kullanıcılar:
- Doğrudan Kenarlar: Bir düğümden diğerine basit ve koşulsuz bir akış.
- Koşullu Kenarlar: Akış, koşullu bir düğümün sonucuna bağlıdır.
Düzenlemeyi uygulamak için LangGraph'ı kullanacağız. LangGraph mantığımızı tanımlamak için aidemy-bootstrap
klasöründeki aidemy.py
dosyasını düzenleyelim. 👉Aşağıdaki kodu aidemy.py
'ün sonuna ekleyin:
tools = [get_curriculum, search_latest_resource, recommend_book]
def determine_tool(state: MessagesState):
llm = ChatVertexAI(model_name="gemini-2.0-flash-001", location=get_next_region())
sys_msg = SystemMessage(
content=(
f"""You are a helpful teaching assistant that helps gather all needed information.
Your ultimate goal is to create a detailed 3-week teaching plan.
You have access to tools that help you gather information.
Based on the user request, decide which tool(s) are needed.
"""
)
)
llm_with_tools = llm.bind_tools(tools)
return {"messages": llm_with_tools.invoke([sys_msg] + state["messages"])}
Bu işlev, sohbetin mevcut durumunu almak, LLM'ye bir sistem mesajı sağlamak ve ardından LLM'den yanıt oluşturmasını istemekten sorumludur. LLM, kullanıcıya doğrudan yanıt verebilir veya mevcut araçlardan birini kullanmayı seçebilir.
tools : Bu liste, temsilcinin kullanabileceği araç grubunu temsil eder. Önceki adımlarda tanımladığımız üç araç işlevi içerir: get_curriculum
, search_latest_resource
ve recommend_book
. llm.bind_tools(tools): Araçlar listesini llm nesnesine "bağlar". Araçları bağlamak, LLM'ye bu araçların kullanılabilir olduğunu bildirir ve LLM'ye bunların nasıl kullanılacağıyla ilgili bilgiler (ör. araçların adları, kabul ettikleri parametreler ve işlevleri) sağlar.
Düzenlemeyi uygulamak için LangGraph'ı kullanacağız. 👉aidemy.py
dosyasının sonuna aşağıdaki kodu ekleyin:
def prep_class(prep_needs):
builder = StateGraph(MessagesState)
builder.add_node("determine_tool", determine_tool)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "determine_tool")
builder.add_conditional_edges("determine_tool",tools_condition)
builder.add_edge("tools", "determine_tool")
memory = MemorySaver()
graph = builder.compile(checkpointer=memory)
config = {"configurable": {"thread_id": "1"}}
messages = graph.invoke({"messages": prep_needs},config)
print(messages)
for m in messages['messages']:
m.pretty_print()
teaching_plan_result = messages["messages"][-1].content
return teaching_plan_result
if __name__ == "__main__":
prep_class("I'm doing a course for year 5 on subject Mathematics in Geometry, , get school curriculum, and come up with few books recommendation plus search latest resources on the internet base on the curriculum outcome. And come up with a 3 week teaching plan")
Açıklama:
StateGraph(MessagesState)
:StateGraph
nesnesi oluşturur.StateGraph
, LangGraph'ta temel bir kavramdır. Temsilcinizin iş akışını bir grafik olarak gösterir. Grafikteki her düğüm, süreçteki bir adımı temsil eder. Bunu, temsilcinin nasıl akıl yürüteceğini ve hareket edeceğini gösteren bir plan olarak düşünün.- Koşullu Kenar:
"determine_tool"
düğümünden gelentools_condition
bağımsız değişkeni, büyük olasılıkladetermine_tool
işlevinin çıkışına göre hangi kenarın izleneceğini belirleyen bir işlevdir. Koşullu kenarlar, LLM'nin hangi aracı kullanacağına (veya kullanıcıya doğrudan yanıt verip vermeyeceğine) karar vermesine bağlı olarak grafiğin dallanmasına olanak tanır. Bu noktada temsilcinin "zekası" devreye girer. Temsilci, davranışını duruma göre dinamik olarak uyarlayabilir. - Döngü: Grafiğe,
"tools"
düğümünü"determine_tool"
düğümüne bağlayan bir kenar ekler. Bu, grafikte bir döngü oluşturur ve müşteri temsilcisinin görevi tamamlayacak ve tatmin edici bir yanıt verecek kadar bilgi toplayana kadar araçları tekrar tekrar kullanmasına olanak tanır. Bu döngü, birden fazla akıl yürütme ve bilgi toplama adımı gerektiren karmaşık görevler için çok önemlidir.
Şimdi, farklı araçları nasıl koordine ettiğini görmek için planlayıcı aracımızı test edelim.
Bu kod, prep_class işlevini belirli bir kullanıcı girişiyle çalıştırarak müfredat, kitap önerileri ve en son internet kaynaklarını kullanarak 5. sınıf Geometri dersi için bir öğretim planı oluşturma isteğini simüle eder.
Terminalinizi kapattıysanız veya ortam değişkenleri artık ayarlanmamışsa aşağıdaki komutları yeniden çalıştırın.
export BOOK_PROVIDER_URL=$(gcloud run services describe book-provider --region=us-central1 --project=$PROJECT_ID --format="value(status.url)")
export PROJECT_ID=$(gcloud config get project)
export INSTANCE_NAME="aidemy"
export REGION="us-central1"
export DB_USER="postgres"
export DB_PASS="1234qwer"
export DB_NAME="aidemy-db"
👉Kodu çalıştırın:
cd ~/aidemy-bootstrap/planner/
source env/bin/activate
pip install -r requirements.txt
python aidemy.py
Terminalde günlüğü izleyin. Temsilcinin nihai öğretim planını sunmadan önce üç aracı da (okul müfredatını alma, kitap önerileri alma ve en yeni kaynakları arama) kullandığına dair kanıt görebilirsiniz. Bu, LangGraph orkestrasyonunun düzgün çalıştığını ve temsilcinin kullanıcının isteğini yerine getirmek için mevcut tüm araçları akıllıca kullandığını gösterir.
================================ Human Message =================================
I'm doing a course for year 5 on subject Mathematics in Geometry, , get school curriculum, and come up with few books recommendation plus search latest resources on the internet base on the curriculum outcome. And come up with a 3 week teaching plan
================================== Ai Message ==================================
Tool Calls:
get_curriculum (xxx)
Call ID: xxx
Args:
year: 5.0
subject: Mathematics
================================= Tool Message =================================
Name: get_curriculum
Introduction to fractions, decimals, and percentages, along with foundational geometry and problem-solving techniques.
================================== Ai Message ==================================
Tool Calls:
search_latest_resource (xxxx)
Call ID: xxxx
Args:
year: 5.0
search_text: Geometry
curriculum: {"content": "Introduction to fractions, decimals, and percentages, along with foundational geometry and problem-solving techniques."}
subject: Mathematics
================================= Tool Message =================================
Name: search_latest_resource
candidates=[Candidate(content=Content(parts=[Part(.....) automatic_function_calling_history=[] parsed=None
================================== Ai Message ==================================
Tool Calls:
recommend_book (93b48189-4d69-4c09-a3bd-4e60cdc5f1c6)
Call ID: 93b48189-4d69-4c09-a3bd-4e60cdc5f1c6
Args:
query: Mathematics Geometry Year 5
================================= Tool Message =================================
Name: recommend_book
[{.....}]
================================== Ai Message ==================================
Based on the curriculum outcome, here is a 3-week teaching plan for year 5 Mathematics Geometry:
**Week 1: Introduction to Shapes and Properties**
.........
Ctrl+C
tuşlarına basarak komut dosyasını durdurun.
👉Ardından, test kodunu farklı bir istemle değiştirin. Bu istem, farklı araçların çağrılmasını gerektirir.
if __name__ == "__main__":
prep_class("I'm doing a course for year 5 on subject Mathematics in Geometry, search latest resources on the internet base on the subject. And come up with a 3 week teaching plan")
Terminalinizi kapattıysanız veya ortam değişkenleri artık ayarlanmamışsa aşağıdaki komutları yeniden çalıştırın.
export BOOK_PROVIDER_URL=$(gcloud run services describe book-provider --region=us-central1 --project=$PROJECT_ID --format="value(status.url)")
export PROJECT_ID=$(gcloud config get project)
export INSTANCE_NAME="aidemy"
export REGION="us-central1"
export DB_USER="postgres"
export DB_PASS="1234qwer"
export DB_NAME="aidemy-db"
👉Kodu tekrar çalıştırın:
cd ~/aidemy-bootstrap/planner/
source env/bin/activate
python aidemy.py
Bu sefer ne fark ettiniz? Temsilci hangi araçları çağırdı? Temsilcinin bu sefer yalnızca search_latest_resource aracını çağırdığını görürsünüz. Bunun nedeni, istemde diğer iki araca ihtiyaç duyulduğunu belirtmemesi ve LLM'mizin diğer araçları çağırmayacak kadar akıllı olmasıdır.
================================ Human Message =================================
I'm doing a course for year 5 on subject Mathematics in Geometry, search latest resources on the internet base on the subject. And come up with a 3 week teaching plan
================================== Ai Message ==================================
Tool Calls:
get_curriculum (xxx)
Call ID: xxx
Args:
year: 5.0
subject: Mathematics
================================= Tool Message =================================
Name: get_curriculum
Introduction to fractions, decimals, and percentages, along with foundational geometry and problem-solving techniques.
================================== Ai Message ==================================
Tool Calls:
search_latest_resource (xxx)
Call ID: xxxx
Args:
year: 5.0
subject: Mathematics
curriculum: {"content": "Introduction to fractions, decimals, and percentages, along with foundational geometry and problem-solving techniques."}
search_text: Geometry
================================= Tool Message =================================
Name: search_latest_resource
candidates=[Candidate(content=Content(parts=[Part(.......token_count=40, total_token_count=772) automatic_function_calling_history=[] parsed=None
================================== Ai Message ==================================
Based on the information provided, a 3-week teaching plan for Year 5 Mathematics focusing on Geometry could look like this:
**Week 1: Introducing 2D Shapes**
........
* Use visuals, manipulatives, and real-world examples to make the learning experience engaging and relevant.
Ctrl+C
tuşlarına basarak komut dosyasını durdurun. aidemy.py dosyanızı temiz tutmak için test kodunu kaldırın:
if __name__ == "__main__":
prep_class("I'm doing a course for year 5 on subject Mathematics in Geometry, search latest resources on the internet base on the subject. And come up with a 3 week teaching plan")
Temsilci mantığımızı tanımladığımıza göre Flask web uygulamasını başlatalım. Bu sayede öğretmenler, müşteri temsilcisiyle etkileşime geçmek için form tabanlı bir arayüze yönlendirilir. LLM'lerde sohbet robotu etkileşimleri yaygın olsa da birçok eğitimci için daha sezgisel olabileceğinden geleneksel bir form gönderme kullanıcı arayüzü tercih ediyoruz.
Terminalinizi kapattıysanız veya ortam değişkenleri artık ayarlanmamışsa aşağıdaki komutları yeniden çalıştırın.
export BOOK_PROVIDER_URL=$(gcloud run services describe book-provider --region=us-central1 --project=$PROJECT_ID --format="value(status.url)")
export PROJECT_ID=$(gcloud config get project)
export INSTANCE_NAME="aidemy"
export REGION="us-central1"
export DB_USER="postgres"
export DB_PASS="1234qwer"
export DB_NAME="aidemy-db"
👉Ardından web kullanıcı arayüzünü başlatın.
cd ~/aidemy-bootstrap/planner/
source env/bin/activate
python app.py
Cloud Shell terminal çıkışında başlangıç mesajlarını arayın. Flask genellikle çalıştığı ve hangi bağlantı noktasında olduğunu belirten mesajlar yazdırır.
Running on http://127.0.0.1:8080
Running on http://127.0.0.1:8080
The application needs to keep running to serve requests.
👉"Web önizlemesi" menüsünden 8080 bağlantı noktasında önizle'yi seçin. Cloud Shell, uygulamanızın web önizlemesini içeren yeni bir tarayıcı sekmesi veya penceresi açar.
Başvuru arayüzünde Yıl için 5
, konu için Mathematics
'ü seçin ve Eklenti İsteği'ne Geometry
yazın
Yanıtı beklerken boş boş bakmak yerine Cloud Editor'ın terminaline geçin. İşlemcinin terminalinde, ilerleme durumunu ve işleviniz tarafından oluşturulan çıkış veya hata mesajlarını gözlemleyebilirsiniz. 😁
👉Terminalde Ctrl+C
tuşuna basarak komut dosyasını durdurun.
👉Sanal ortamdan çıkma:
deactivate
8. Planlayıcı aracısını buluta dağıtma
Görüntüyü oluşturup kayıt otoritesine aktarma
👉Bu modeli buluta dağıtma zamanı. Terminalde, derleyeceğimiz Docker görüntüsünü depolamak için bir yapı arşivi oluşturun.
gcloud artifacts repositories create agent-repository \
--repository-format=docker \
--location=us-central1 \
--description="My agent repository"
Oluşturulan depo [agent-repository] ifadesini görürsünüz.
👉Docker görüntüsünü oluşturmak için aşağıdaki komutu çalıştırın.
cd ~/aidemy-bootstrap/planner/
export PROJECT_ID=$(gcloud config get project)
docker build -t gcr.io/${PROJECT_ID}/aidemy-planner .
👉Resmi, GCR yerine Artifact Registry'de barındırılacak şekilde yeniden etiketlememiz ve etiketlenen resmi Artifact Registry'ye göndermemiz gerekiyor:
export PROJECT_ID=$(gcloud config get project)
docker tag gcr.io/${PROJECT_ID}/aidemy-planner us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-planner
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-planner
Yükleme tamamlandıktan sonra resmin Artifact Registry'de başarıyla depolandığını doğrulayabilirsiniz. Google Cloud Console'da Artifact Registry'ye gidin. aidemy-planner
resmini agent-repository
deposunda bulabilirsiniz.
Secret Manager ile veritabanı kimlik bilgilerinin güvenliğini sağlama
Veritabanı kimlik bilgilerini güvenli bir şekilde yönetmek ve bunlara erişmek için Google Cloud Secret Manager'ı kullanırız. Bu sayede, hassas bilgiler uygulama kodumuza sabit kod olarak eklenmez ve güvenlik artırılır.
👉Veritabanı kullanıcı adı, şifresi ve veritabanı adı için ayrı ayrı gizli anahtarlar oluşturacağız. Bu yaklaşım, her kimlik bilgisini bağımsız olarak yönetmemize olanak tanır. Terminalde şu komutu çalıştırın:
gcloud secrets create db-user
printf "postgres" | gcloud secrets versions add db-user --data-file=-
gcloud secrets create db-pass
printf "1234qwer" | gcloud secrets versions add db-pass --data-file=-
gcloud secrets create db-name
printf "aidemy-db" | gcloud secrets versions add db-name --data-file=-
Secret Manager'ı kullanmak, uygulamanızın güvenliğini sağlama ve hassas kimlik bilgilerinin yanlışlıkla açığa çıkmasını önleme konusunda önemli bir adımdır. Bulut dağıtımları için en iyi güvenlik uygulamalarını takip eder.
Cloud Run'a dağıt
Cloud Run, container mimarisine alınmış uygulamaları hızlı ve kolay bir şekilde dağıtmanıza olanak tanıyan, tümüyle yönetilen bir sunucusuz platformdur. Altyapı yönetimini soyutlayarak kodunuzu yazmaya ve dağıtmaya odaklanmanıza olanak tanır. Planlayıcımızı Cloud Run hizmeti olarak dağıtacağız.
👉Google Cloud Console'da "Cloud Run"a gidin. DEPLOY CONTAINER'ı (KAPSAYICIYI YAYINLA) tıklayın ve SERVICE'i (HİZMET) seçin. Cloud Run hizmetinizi yapılandırın:
- Kapsayıcı resmi: URL alanında "Seç"i tıklayın. Artifact Registry'ye yayınladığınız resim URL'sini bulun (ör. us-central1-docker.pkg.dev/PROJECT_ID/agent-repository/agent-planner/IMG_ADINIZ).
- Hizmet adı:
aidemy-planner
- Bölge:
us-central1
bölgesini seçin. - Kimlik doğrulama: Bu atölye çalışması için "Kimliği doğrulanmayan çağrılara izin ver" seçeneğine izin verebilirsiniz. Üretim için erişimi kısıtlamanız muhtemeldir.
- Kapsayıcılar sekmesi (Kapsayıcılar, Ağ'ı genişletin):
- Ayar sekmesi:
- Kaynak
- bellek : 2 GB
- Kaynak
- Değişkenler ve Gizli Anahtarlar sekmesi:
- Ortam değişkenleri:
- Ad:
GOOGLE_CLOUD_PROJECT
ve değer: <PROJE_KİMLİK_BİLGİNİZ> ekleyin. - Ad:
BOOK_PROVIDER_URL
ve değer: <YOUR_BOOK_PROVIDER_FUNCTION_URL> ekleyin.
- Ad:
- Ortam değişkeni olarak sunulan gizli anahtarlar:
- Ad ekleyin:
DB_USER
, gizli anahtar:db-user
'ü seçin ve sürüm:latest
- Ad ekleyin:
DB_PASS
, gizli anahtar:db-pass
'ü seçin ve sürüm:latest
- Ad ekleyin:
DB_NAME
, gizli anahtar:db-name
'ü seçin ve sürüm:latest
- Ad ekleyin:
- Ortam değişkenleri:
- Ayar sekmesi:
YOUR_BOOK_PROVIDER_FUNCTION_URL değerinizi almanız gerekiyorsa terminalde aşağıdaki komutu çalıştırın:
gcloud run services describe book-provider --region=us-central1 --project=$PROJECT_ID --format="value(status.url)"
Diğeri varsayılan olarak bırakın.
👉OLUŞTUR'u tıklayın.
Cloud Run, hizmetinizi dağıtır.
Dağıtıldıktan sonra hizmeti tıklayarak ayrıntılar sayfasına gidin. Dağıtılan URL'yi en üstte bulabilirsiniz.
Başvuru arayüzünde Yıl için 7
, konu olarak Mathematics
'yi seçin ve Eklenti İsteği alanına Algebra
yazın. Bu, temsilciye özel bir ders planı oluşturmak için gerekli bağlamı sağlar.
Tebrikler! Güçlü yapay zeka aracımızı kullanarak başarılı bir şekilde bir öğretim planı oluşturdunuz. Bu, temsilcilerin iş yükünü önemli ölçüde azaltma ve görevleri kolaylaştırma potansiyelini gösterir. Bu da verimliliği artırıp eğitimcilerin hayatını kolaylaştırır.
9. Çoklu ajans sistemleri
Öğretim planı oluşturma aracını başarıyla uyguladığımıza göre şimdi öğrenci portalını oluşturmaya odaklanalım. Bu portal, öğrencilere kurslarıyla ilgili testlere, sesli özetlere ve ödevlere erişim sağlar. Bu işlevin kapsamı göz önüne alındığında, modüler ve ölçeklenebilir bir çözüm oluşturmak için çok aracılı sistemlerin gücünden yararlanacağız.
Daha önce de belirttiğimiz gibi, her şeyi tek bir aracıya bırakmak yerine çok aracılı sistem, iş yükünü her biri özel bir aracı tarafından yönetilen daha küçük ve özel görevlere ayırmamıza olanak tanır. Bu yaklaşımın birkaç önemli avantajı vardır:
Modülerlik ve sürdürülebilirlik: Her şeyi yapan tek bir aracı oluşturmak yerine, sorumlulukları iyi tanımlanmış daha küçük, özelleştirilmiş aracılar oluşturun. Bu modülerlik, sistemin anlaşılmasını, korunmasını ve hata ayıklama işlemini kolaylaştırır. Bir sorun oluştuğunda, büyük bir kod tabanını incelemek zorunda kalmak yerine sorunu belirli bir temsilciye ayırabilirsiniz.
Ölçeklenebilirlik: Tek ve karmaşık bir temsilciyi ölçeklendirmek darboğaz olabilir. Çok temsilcili bir sistemle, temsilcileri belirli ihtiyaçlarına göre ölçeklendirebilirsiniz. Örneğin, bir temsilci çok sayıda isteği ele alıyorsa sistemin geri kalanını etkilemeden kolayca bu temsilcinin daha fazla örneğini oluşturabilirsiniz.
Ekip uzmanlığı: Bunu şöyle düşünün: Bir mühendisten uygulamanın tamamını sıfırdan oluşturmasını istemezsiniz. Bunun yerine, her biri belirli bir alanda uzman olan bir uzman ekibi oluşturursunuz. Benzer şekilde, çok aracılı sistem, farklı LLM'lerin ve araçların güçlü yönlerinden yararlanmanıza olanak tanır. Bu sayede, bunları belirli görevlere en uygun temsilcilere atayabilirsiniz.
Paralel Geliştirme: Farklı ekipler aynı anda farklı temsilciler üzerinde çalışarak geliştirme sürecini hızlandırabilir. Temsilciler bağımsız olduğundan, bir temsilcide yapılan değişikliklerin diğer temsilcileri etkileme olasılığı düşüktür.
Etkinlik Odaklı Mimari
Bu temsilciler arasında etkili iletişim ve koordinasyon sağlamak için olaya dayalı bir mimari kullanacağız. Bu, temsilcilerin sistemde gerçekleşen "etkinliklere" tepki vereceği anlamına gelir.
Temsilciler belirli etkinlik türlerine (ör. "Öğretim planı oluşturuldu", "Ödev oluşturuldu"). Bir etkinlik gerçekleştiğinde ilgili temsilciler bilgilendirilir ve buna göre tepki verebilir. Bu ayrım, esnekliği, ölçeklenebilirliği ve anlık yanıt vermeyi destekler.
Başlamak için bu etkinlikleri yayınlayabileceğimiz bir yönteme ihtiyacımız var. Bunun için bir Pub/Sub konusu oluşturacağız. Plan adlı bir konu oluşturarak başlayalım.
👉Google Cloud Console pub/sub'a gidin ve "Konu Oluştur" düğmesini tıklayın.
👉Konuyu plan
kimliği/adı ile yapılandırın ve Add a default subscription
seçeneğinin işaretini kaldırın, geri kalanı varsayılan olarak bırakın ve Oluştur'u tıklayın.
Pub/Sub sayfası yenilenir ve yeni oluşturduğunuz konu tabloda listelenir.
Şimdi Pub/Sub etkinlik yayınlama işlevini planlayıcı aracımıza entegre edelim. Az önce oluşturduğumuz Pub/Sub konusuna "plan" etkinliği gönderen yeni bir araç ekleyeceğiz. Bu etkinlik, sistemdeki diğer temsilcilere (ör. öğrenci portalındaki temsilciler) yeni bir öğretim planının kullanıma sunulduğunu bildirir.
👉Cloud Code Düzenleyici'ye geri dönün ve planner
klasöründeki app.py
dosyasını açın. Etkinliği yayınlayan bir işlev ekleyeceğiz. Değiştir:
##ADD SEND PLAN EVENT FUNCTION HERE
ile
def send_plan_event(teaching_plan:str):
"""
Send the teaching event to the topic called plan
Args:
teaching_plan: teaching plan
"""
publisher = pubsub_v1.PublisherClient()
print(f"-------------> Sending event to topic plan: {teaching_plan}")
topic_path = publisher.topic_path(PROJECT_ID, "plan")
message_data = {"teaching_plan": teaching_plan}
data = json.dumps(message_data).encode("utf-8")
future = publisher.publish(topic_path, data)
return f"Published message ID: {future.result()}"
- send_plan_event: Bu işlev, oluşturulan öğretim planını giriş olarak alır, bir Pub/Sub yayıncı istemcisi oluşturur, konu yolunu oluşturur , öğretim planını JSON dize dönüştürür ve mesajı konuya yayınlar.
- tools List:
send_plan_event
işlevi, müşteri temsilcisinin kullanabileceği şekilde araç listesine eklenir.
Aynı klasörün altındaki app.py
dosyasında 👉Temsilciye, öğretim planını oluşturduktan sonra öğretim planı etkinliğini Pub/Sub konusuna göndermesini talimat verecek şekilde istemi güncelleyin. Değiştir
### ADD send_plan_event CALL
aşağıdakilerle:
send_plan_event(teaching_plan)
send_plan_event aracını ekleyerek ve istemi değiştirerek planlayıcı aracımızın Pub/Sub'da etkinlik yayınlamasını sağladık. Böylece, sistemimizin diğer bileşenlerinin yeni öğretim planlarının oluşturulmasına tepki vermesine olanak tanıdık. Artık aşağıdaki bölümlerde işlevsel bir çok aracılı sistemimiz olacak.
10. İsteğe bağlı testlerle öğrencilere güç verme
Öğrencilerin, belirli öğrenme planlarına göre hazırlanmış sonsuz sayıda teste erişebildiği bir öğrenme ortamı düşünün. Bu testler, yanıtlar ve açıklamalar da dahil olmak üzere anında geri bildirim sağlayarak materyalin daha iyi anlaşılmasını sağlar. Yapay zeka destekli test portalımızla bu potansiyeli ortaya çıkarmayı amaçlıyoruz.
Bu vizyonu hayata geçirmek için öğretim planının içeriğine göre çoktan seçmeli sorular oluşturabilecek bir test oluşturma bileşeni geliştireceğiz.
👉Cloud Code Editor'ın Gezgin bölmesinde portal
klasörüne gidin. quiz.py
dosyasını açın, aşağıdaki kodu kopyalayıp dosyanın sonuna yapıştırın.
def generate_quiz_question(file_name: str, difficulty: str, region:str ):
"""Generates a single multiple-choice quiz question using the LLM.
```json
{
"question": "The question itself",
"options": ["Option A", "Option B", "Option C", "Option D"],
"answer": "The correct answer letter (A, B, C, or D)"
}
```
"""
print(f"region: {region}")
# Connect to resourse needed from Google Cloud
llm = VertexAI(model_name="gemini-1.5-pro", location=region)
plan=None
#load the file using file_name and read content into string call plan
with open(file_name, 'r') as f:
plan = f.read()
parser = JsonOutputParser(pydantic_object=QuizQuestion)
instruction = f"You'll provide one question with difficulty level of {difficulty}, 4 options as multiple choices and provide the anwsers, the quiz needs to be related to the teaching plan {plan}"
prompt = PromptTemplate(
template="Generates a single multiple-choice quiz question\n {format_instructions}\n {instruction}\n",
input_variables=["instruction"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | llm | parser
response = chain.invoke({"instruction": instruction})
print(f"{response}")
return response
Temsilcide, LLM'nin çıkışını anlamak ve yapılandırmak için özel olarak tasarlanmış bir JSON çıkış ayrıştırıcı oluşturur. Ayrıştırılan çıktının doğru biçime (soru, seçenekler ve yanıt) uygun olmasını sağlamak için daha önce tanımladığımız QuizQuestion
modelini kullanır.
👉Sanal ortam oluşturmak, bağımlılıkları yüklemek ve aracıyı başlatmak için terminalde aşağıdaki komutları çalıştırın:
cd ~/aidemy-bootstrap/portal/
python -m venv env
source env/bin/activate
pip install -r requirements.txt
python app.py
Çalışan uygulamaya erişmek için Cloud Shell'in web önizleme özelliğini kullanın. Üst gezinme çubuğundan veya dizin sayfasındaki karttan "Testler" bağlantısını tıklayın. Öğrenci için rastgele oluşturulmuş üç test gösterilir. Bu testler, öğretim planına dayanır ve yapay zeka destekli test oluşturma sistemimizin gücünü gösterir.
Yerel olarak çalışan işlemi durdurmak için terminalde Ctrl+C
tuşuna basın.
Gemini 2 Thinking for Explanations
Tamam, testler var. Bu iyi bir başlangıç. Peki öğrenciler bir konuda yanlış yaparsa ne olur? Gerçek öğrenme burada gerçekleşir, değil mi? Yanıtlarının neden yanlış olduğunu ve doğru yanıta nasıl ulaşacaklarını açıklayabilirsek doğru yanıtı hatırlama olasılıkları çok daha yüksektir. Ayrıca, kafa karışıklığını gidermeye ve güvenlerini artırmaya yardımcı olur.
Bu nedenle, Gemini 2'nin "düşünen" modelini devreye alıyoruz. Bu durumu, yapay zekaya açıklama yapmadan önce konuyu düşünmesi için biraz daha zaman tanıdığınız gibi düşünebilirsiniz. Bu sayede daha ayrıntılı ve daha iyi geri bildirim verebilir.
Öğrencilere yardımcı olarak, soruları yanıtlayarak ve ayrıntılı açıklamalar yaparak yardımcı olup olamayacağını görmek istiyoruz. Bunu test etmek için, herkesin bildiği gibi zor bir konu olan diferansiyel hesaptan başlayacağız.
👉Öncelikle Cloud Code Editor'a gidin, portal
klasörünün içindeki answer.py
dosyasında
def answer_thinking(question, options, user_response, answer, region):
return ""
aşağıdaki kod snippet'iyle:
def answer_thinking(question, options, user_response, answer, region):
try:
llm = VertexAI(model_name="gemini-2.0-flash-001",location=region)
input_msg = HumanMessage(content=[f"Here the question{question}, here are the available options {options}, this student's answer {user_response}, whereas the correct answer is {answer}"])
prompt_template = ChatPromptTemplate.from_messages(
[
SystemMessage(
content=(
"You are a helpful teacher trying to teach the student on question, you were given the question and a set of multiple choices "
"what's the correct answer. use friendly tone"
)
),
input_msg,
]
)
prompt = prompt_template.format()
response = llm.invoke(prompt)
print(f"response: {response}")
return response
except Exception as e:
print(f"Error sending message to chatbot: {e}") # Log this error too!
return f"Unable to process your request at this time. Due to the following reason: {str(e)}"
if __name__ == "__main__":
question = "Evaluate the limit: lim (x→0) [(sin(5x) - 5x) / x^3]"
options = ["A) -125/6", "B) -5/3 ", "C) -25/3", "D) -5/6"]
user_response = "B"
answer = "A"
region = "us-central1"
result = answer_thinking(question, options, user_response, answer, region)
Bu, Gemini 2 Flash modelini başlatan ve ona faydalı bir öğretmen gibi davranıp açıklama yapması gerektiğini söyleyen çok basit bir dil zinciri uygulamasıdır.
👉Terminalde aşağıdaki komutu çalıştırın:
cd ~/aidemy-bootstrap/portal/
python answer.py
Orijinal talimatlarda verilen örneğe benzer bir çıkış görürsünüz. Mevcut model, bu konuda ayrıntılı bir açıklama sunmayabilir.
Okay, I see the question and the choices. The question is to evaluate the limit:
lim (x→0) [(sin(5x) - 5x) / x^3]
You chose option B, which is -5/3, but the correct answer is A, which is -125/6.
It looks like you might have missed a step or made a small error in your calculations. This type of limit often involves using L'Hôpital's Rule or Taylor series expansion. Since we have the form 0/0, L'Hôpital's Rule is a good way to go! You need to apply it multiple times. Alternatively, you can use the Taylor series expansion of sin(x) which is:
sin(x) = x - x^3/3! + x^5/5! - ...
So, sin(5x) = 5x - (5x)^3/3! + (5x)^5/5! - ...
Then, (sin(5x) - 5x) = - (5x)^3/3! + (5x)^5/5! - ...
Finally, (sin(5x) - 5x) / x^3 = - 5^3/3! + (5^5 * x^2)/5! - ...
Taking the limit as x approaches 0, we get -125/6.
Keep practicing, you'll get there!
answer.py dosyasında, answer_thinking işlevindeki model_name değerini gemini-2.0-flash-001
yerine gemini-2.0-flash-thinking-exp-01-21
ile değiştirin.
Bu, daha fazla nedensellik ilişkisi kurabilen LLM'yi değiştirir ve daha iyi açıklamalar oluşturmasına yardımcı olur. Ve tekrar çalıştırın.
👉Yeni düşünme modelini test etmek için çalıştırın:
cd ~/aidemy-bootstrap/portal/
source env/bin/activate
python answer.py
Aşağıda, düşünme modelinden gelen ve çok daha ayrıntılı olan bir yanıt örneği verilmiştir. Bu yanıtta, diferansiyel denklemin nasıl çözüleceğine dair adım adım açıklama sunulmaktadır. Bu, "düşünen" modellerin yüksek kaliteli açıklamalar üretmedeki gücünü gösterir. Aşağıdakine benzer bir çıkış görürsünüz:
Hey there! Let's take a look at this limit problem together. You were asked to evaluate:
lim (x→0) [(sin(5x) - 5x) / x^3]
and you picked option B, -5/3, but the correct answer is actually A, -125/6. Let's figure out why!
It's a tricky one because if we directly substitute x=0, we get (sin(0) - 0) / 0^3 = (0 - 0) / 0 = 0/0, which is an indeterminate form. This tells us we need to use a more advanced technique like L'Hopital's Rule or Taylor series expansion.
Let's use the Taylor series expansion for sin(y) around y=0. Do you remember it? It looks like this:
sin(y) = y - y^3/3! + y^5/5! - ...
where 3! (3 factorial) is 3 × 2 × 1 = 6, 5! is 5 × 4 × 3 × 2 × 1 = 120, and so on.
In our problem, we have sin(5x), so we can substitute y = 5x into the Taylor series:
sin(5x) = (5x) - (5x)^3/3! + (5x)^5/5! - ...
sin(5x) = 5x - (125x^3)/6 + (3125x^5)/120 - ...
Now let's plug this back into our limit expression:
[(sin(5x) - 5x) / x^3] = [ (5x - (125x^3)/6 + (3125x^5)/120 - ...) - 5x ] / x^3
Notice that the '5x' and '-5x' cancel out! So we are left with:
= [ - (125x^3)/6 + (3125x^5)/120 - ... ] / x^3
Now, we can divide every term in the numerator by x^3:
= -125/6 + (3125x^2)/120 - ...
Finally, let's take the limit as x approaches 0. As x gets closer and closer to zero, terms with x^2 and higher powers will become very, very small and approach zero. So, we are left with:
lim (x→0) [ -125/6 + (3125x^2)/120 - ... ] = -125/6
Therefore, the correct answer is indeed **A) -125/6**.
It seems like your answer B, -5/3, might have come from perhaps missing a factor somewhere during calculation or maybe using an incorrect simplification. Double-check your steps when you were trying to solve it!
Don't worry, these limit problems can be a bit tricky sometimes! Keep practicing and you'll get the hang of it. Let me know if you want to go through another similar example or if you have any more questions! 😊
Now that we have confirmed it works, let's use the portal.
👉answer.py
'den aşağıdaki test kodunu KALDIRIN:
if __name__ == "__main__":
question = "Evaluate the limit: lim (x→0) [(sin(5x) - 5x) / x^3]"
options = ["A) -125/6", "B) -5/3 ", "C) -25/3", "D) -5/6"]
user_response = "B"
answer = "A"
region = "us-central1"
result = answer_thinking(question, options, user_response, answer, region)
👉Sanal ortam oluşturmak, bağımlılıkları yüklemek ve aracıyı başlatmak için terminalde aşağıdaki komutları çalıştırın:
cd ~/aidemy-bootstrap/portal/
source env/bin/activate
python app.py
👉Çalışmakta olan uygulamaya erişmek için Cloud Shell'in web önizleme özelliğini kullanın. "Testler" bağlantısını tıklayın, tüm testleri yanıtlayın ve en az bir yanıtı yanlış verdiğinizden emin olun, ardından gönder'i tıklayın.
Yanıtı beklerken boş boş bakmak yerine Cloud Editor'ın terminaline geçin. İşlemcinin terminalinde, ilerleme durumunu ve işleviniz tarafından oluşturulan çıkış veya hata mesajlarını gözlemleyebilirsiniz. 😁
Yerel olarak çalışan işlemi durdurmak için terminalde Ctrl+C
tuşuna basın.
11. Temsilcileri Eventarc ile düzenleme
Şimdiye kadar öğrenci portalı, varsayılan bir öğretim planı grubuna göre testler oluşturuyordu. Bu yararlı bir özellik olsa da planlayıcı aracımız ile portalın test aracının aslında birbirleriyle iletişime geçmediği anlamına geliyor. Planlayıcı aracısının yeni oluşturulan eğitim planlarını bir Pub/Sub konusuna yayınladığı özelliği nasıl eklediğimizi hatırlıyor musunuz? Artık bu bilgileri portal müşteri temsilcimize bağlama zamanı geldi.
Portalın, yeni bir öğretim planı oluşturulduğunda test içeriğini otomatik olarak güncellemesini istiyoruz. Bunun için portalda bu yeni planları alabilecek bir uç nokta oluşturacağız.
👉Cloud Code Editor'ın Gezgin bölmesinde portal
klasörüne gidin. Düzenlemek için app.py
dosyasını açın. ## Kodunuzu buraya ekleyin arasına aşağıdaki kodu ekleyin:
## Add your code here
@app.route('/new_teaching_plan', methods=['POST'])
def new_teaching_plan():
try:
# Get data from Pub/Sub message delivered via Eventarc
envelope = request.get_json()
if not envelope:
return jsonify({'error': 'No Pub/Sub message received'}), 400
if not isinstance(envelope, dict) or 'message' not in envelope:
return jsonify({'error': 'Invalid Pub/Sub message format'}), 400
pubsub_message = envelope['message']
print(f"data: {pubsub_message['data']}")
data = pubsub_message['data']
data_str = base64.b64decode(data).decode('utf-8')
data = json.loads(data_str)
teaching_plan = data['teaching_plan']
print(f"File content: {teaching_plan}")
with open("teaching_plan.txt", "w") as f:
f.write(teaching_plan)
print(f"Teaching plan saved to local file: teaching_plan.txt")
return jsonify({'message': 'File processed successfully'})
except Exception as e:
print(f"Error processing file: {e}")
return jsonify({'error': 'Error processing file'}), 500
## Add your code here
Yeniden derleme ve Cloud Run'a dağıtma
Tamam. Hem planlayıcımızı hem de portal temsilcilerimizi Cloud Run'da güncelleyip yeniden dağıtmanız gerekiyor. Bu sayede, en son koda sahip olurlar ve etkinlikler aracılığıyla iletişim kuracak şekilde yapılandırılırlar.
👉Ardından, terminalde tekrar çalıştırarak planlayıcı aracısı görüntüsünü yeniden oluşturup göndereceğiz:
cd ~/aidemy-bootstrap/planner/
export PROJECT_ID=$(gcloud config get project)
docker build -t gcr.io/${PROJECT_ID}/aidemy-planner .
export PROJECT_ID=$(gcloud config get project)
docker tag gcr.io/${PROJECT_ID}/aidemy-planner us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-planner
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-planner
👉Aynı işlemi yapıp portal aracısı görüntüsünü derleyip göndereceğiz:
cd ~/aidemy-bootstrap/portal/
export PROJECT_ID=$(gcloud config get project)
docker build -t gcr.io/${PROJECT_ID}/aidemy-portal .
export PROJECT_ID=$(gcloud config get project)
docker tag gcr.io/${PROJECT_ID}/aidemy-portal us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-portal
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-portal
Artifact Registry'de hem aidemy-planner
hem de aidemy-portal
kapsayıcı görüntülerinin listelendiğini göreceksiniz.
👉Terminale geri dönüp planlayıcı aracısı için Cloud Run görüntüsünü güncellemek üzere şu komutu çalıştırın:
export PROJECT_ID=$(gcloud config get project)
gcloud run services update aidemy-planner \
--region=us-central1 \
--image=us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-planner:latest
Aşağıdakine benzer bir çıkış görürsünüz:
OK Deploying... Done.
OK Creating Revision...
OK Routing traffic...
Done.
Service [aidemy-planner] revision [aidemy-planner-xxxxx] has been deployed and is serving 100 percent of traffic.
Service URL: https://aidemy-planner-xxx.us-central1.run.app
Hizmet URL'sini not edin. Bu, dağıtılan planlama aracınızın bağlantısıdır.
👉Portal aracısı için Cloud Run örneğini oluşturmak üzere bunu çalıştırın
export PROJECT_ID=$(gcloud config get project)
gcloud run deploy aidemy-portal \
--image=us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-portal:latest \
--region=us-central1 \
--platform=managed \
--allow-unauthenticated \
--memory=2Gi \
--cpu=2 \
--set-env-vars=GOOGLE_CLOUD_PROJECT=${PROJECT_ID}
Aşağıdakine benzer bir çıkış görürsünüz:
Deploying container to Cloud Run service [aidemy-portal] in project [xxxx] region [us-central1]
OK Deploying new service... Done.
OK Creating Revision...
OK Routing traffic...
OK Setting IAM Policy...
Done.
Service [aidemy-portal] revision [aidemy-portal-xxxx] has been deployed and is serving 100 percent of traffic.
Service URL: https://aidemy-portal-xxxx.us-central1.run.app
Hizmet URL'sini not edin. Bu, dağıtılan öğrenci portalınızın bağlantısıdır.
Eventarc tetikleyicisini oluşturma
Ancak asıl soru şudur: Pub/Sub konusunda yeni bir plan beklerken bu uç nokta nasıl bilgilendirilir? İşte bu noktada Eventarc devreye girerek günü kurtarır.
Eventarc, belirli etkinlikleri (ör. Pub/Sub konumuza gelen yeni bir mesaj) dinleyen ve buna yanıt olarak işlemleri otomatik olarak tetikleyen bir köprü görevi görür. Bizim durumumuzda, yeni bir öğretim planı yayınlandığında bunu algılar ve portalımızın uç noktasına güncelleme zamanı olduğunu bildiren bir sinyal gönderir.
Etkinlik odaklı iletişimi Eventarc'ın yönetmesi sayesinde planlayıcı temsilcimizi ve portal temsilcimizi sorunsuz bir şekilde bağlayabilir, gerçekten dinamik ve duyarlı bir öğrenme sistemi oluşturabiliriz. Bu, en son ders planlarını otomatik olarak doğru yere teslim eden akıllı bir haberci gibidir.
👉Konsolda Eventarc'a gidin.
👉 "+ Tetikleyici OLUŞTUR" düğmesini tıklayın.
Tetikleyiciyi yapılandırma (Temel):
- Tetikleyici adı:
plan-topic-trigger
- Tetikleyici türleri: Google kaynakları.
- Etkinlik sağlayıcı: Cloud Pub/Sub
- Etkinlik Türü:
google.cloud.pubsub.topic.v1.messagePublished
- Bölge:
us-central1
. - Cloud Pub/Sub Konusu :
plan
'ü seçin - Hizmet hesabına
roles/iam.serviceAccountTokenCreator
rolü verin - Etkinlik Hedefi: Cloud Run
- Cloud Run Hizmeti: aidemy-portal
- Hizmet URL'si yolu:
/new_teaching_plan
- İletiyi yoksay ("locations/me-central2" konumunda izin reddedildi (veya konum mevcut olmayabilir).)
"Oluştur"u tıklayın.
Eventarc Tetikleyiciler sayfası yenilenir ve yeni oluşturduğunuz tetikleyici tabloda listelenir.
👉Ardından planlayıcıya erişin ve yeni bir öğretim planı isteyin. Bu kez 5
yılı, science
konusu ve atoms
ekleme isteğiyle deneyin.
Planlayıcı temsilcinizin konumunu unutursanız bunu terminalde çalıştırın
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner
Ardından bir veya iki dakika bekleyin. Bu gecikme, bu laboratuvarın faturalandırma sınırlaması nedeniyle tekrar uygulanmıştır. Normal şartlarda gecikme olmamalıdır.
Son olarak öğrenci portalına erişin. Testlerin güncellendiğini ve oluşturduğunuz yeni öğretim planıyla uyumlu hale geldiğini göreceksiniz. Bu, Eventarc'ın Aidemy sistemine başarıyla entegre edildiğini gösterir.
Portal aracınızın konumunu unutursanız bunu terminalde çalıştırın
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep portal
Tebrikler! Daha fazla ölçeklenebilirlik ve esneklik için etkinlik odaklı mimariden yararlanarak Google Cloud'da çok aracılı bir sistem oluşturdunuz. Sağlam bir temel oluşturdunuz ancak keşfedilecek daha çok şey var. Bu mimarinin gerçek avantajlarını daha ayrıntılı incelemek, Gemini 2'nin çok formatlı Live API'sinin gücünü keşfetmek ve LangGraph ile tek orkestrasyonun nasıl uygulanacağını öğrenmek için sonraki iki bölüme göz atabilirsiniz.
12. İSTEĞE BAĞLI: Gemini ile Ses Özetleri
Gemini; metin, resim ve hatta ses gibi çeşitli kaynaklardan gelen bilgileri anlayıp işleyebilir. Böylece öğrenme ve içerik oluşturma için yepyeni bir olasılıklar yelpazesi sunar. Gemini'nin "görme", "duyma" ve "okuma" özelliği, gerçekten yaratıcı ve ilgi çekici kullanıcı deneyimleri sunar.
Öğrenme sürecinde görsel veya metin oluşturmanın yanı sıra etkili özetleme ve özetleme de önemli bir adımdır. Bir düşünün: Ne sıklıkla akılda kalıcı bir şarkının sözlerini, ders kitabında okuduğunuz bir bilgiye kıyasla daha kolay hatırlarsınız? Sesler son derece akılda kalıcı olabilir. Bu nedenle, öğretim planlarımızın sesli özetlerini oluşturmak için Gemini'nin çoklu duyusal özelliklerinden yararlanacağız. Bu sayede, öğrencilere materyalleri incelemek için kullanışlı ve ilgi çekici bir yöntem sunacağız. Böylece, işitsel öğrenmenin gücüyle bilginin akılda kalıcılığını ve anlaşılırlığını artırabiliriz.
Oluşturulan ses dosyalarını depolayabileceğimiz bir yere ihtiyacımız var. Cloud Storage, ölçeklenebilir ve güvenilir bir çözüm sunar.
👉Konsoldaki Depolama'ya gidin. Soldaki menüde "Kapsamlar"ı tıklayın. Üstteki "+ OLUŞTUR" düğmesini tıklayın.
👉Paketinizi yapılandırın:
- paket adı: aidemy-recap-<UNIQUE_NAME> ÖNEMLİ: "aidemy-recap-" ile başlayan benzersiz bir paket adı tanımladığınızdan emin olun. Bu benzersiz ad, Cloud Storage paketinizi oluştururken adlandırma çakışmalarını önlemek için çok önemlidir.
- region:
us-central1
. - Depolama sınıfı: "Standart". Standart, sık erişilen veriler için uygundur.
- Erişim denetimi: Varsayılan "Tek tip erişim denetimi"ni seçili bırakın. Bu sayede paket düzeyinde tutarlı bir erişim denetimi sağlanır.
- Gelişmiş seçenekler: Bu atölye için genellikle varsayılan ayarlar yeterlidir. Paketinizi oluşturmak için OLUŞTUR düğmesini tıklayın.
Herkese açık erişimi önleme hakkında bir pop-up görebilirsiniz. Kutuyu işaretli bırakın ve Confirm
simgesini tıklayın.
Artık yeni oluşturduğunuz paketi Paketler listesinde görürsünüz. Paketinizin adını unutmayın. Daha sonra bu ada ihtiyacınız olacak.
👉Cloud Code Editor'ın terminalinde, hizmet hesabına pakete erişim izni vermek için aşağıdaki komutları çalıştırın:
export COURSE_BUCKET_NAME=$(gcloud storage buckets list --format="value(name)" | grep aidemy-recap)
export SERVICE_ACCOUNT_NAME=$(gcloud compute project-info describe --format="value(defaultServiceAccount)")
gcloud storage buckets add-iam-policy-binding gs://$COURSE_BUCKET_NAME \
--member "serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role "roles/storage.objectViewer"
gcloud storage buckets add-iam-policy-binding gs://$COURSE_BUCKET_NAME \
--member "serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role "roles/storage.objectCreator"
👉Cloud Code Düzenleyici'de, course
klasörünün içindeki audio.py
dosyasını açın. Aşağıdaki kodu dosyanın sonuna yapıştırın:
config = LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=SpeechConfig(
voice_config=VoiceConfig(
prebuilt_voice_config=PrebuiltVoiceConfig(
voice_name="Charon",
)
)
),
)
async def process_weeks(teaching_plan: str):
region = "us-west1" #To workaround onRamp qouta limits
client = genai.Client(vertexai=True, project=PROJECT_ID, location=region)
clientAudio = genai.Client(vertexai=True, project=PROJECT_ID, location="us-central1")
async with clientAudio.aio.live.connect(
model=MODEL_ID,
config=config,
) as session:
for week in range(1, 4):
response = client.models.generate_content(
model="gemini-1.0-pro",
contents=f"Given the following teaching plan: {teaching_plan}, Extrace content plan for week {week}. And return just the plan, nothingh else " # Clarified prompt
)
prompt = f"""
Assume you are the instructor.
Prepare a concise and engaging recap of the key concepts and topics covered.
This recap should be suitable for generating a short audio summary for students.
Focus on the most important learnings and takeaways, and frame it as a direct address to the students.
Avoid overly formal language and aim for a conversational tone, tell a few jokes.
Teaching plan: {response.text} """
print(f"prompt --->{prompt}")
await session.send(input=prompt, end_of_turn=True)
with open(f"temp_audio_week_{week}.raw", "wb") as temp_file:
async for message in session.receive():
if message.server_content.model_turn:
for part in message.server_content.model_turn.parts:
if part.inline_data:
temp_file.write(part.inline_data.data)
data, samplerate = sf.read(f"temp_audio_week_{week}.raw", channels=1, samplerate=24000, subtype='PCM_16', format='RAW')
sf.write(f"course-week-{week}.wav", data, samplerate)
storage_client = storage.Client()
bucket = storage_client.bucket(BUCKET_NAME)
blob = bucket.blob(f"course-week-{week}.wav") # Or give it a more descriptive name
blob.upload_from_filename(f"course-week-{week}.wav")
print(f"Audio saved to GCS: gs://{BUCKET_NAME}/course-week-{week}.wav")
await session.close()
def breakup_sessions(teaching_plan: str):
asyncio.run(process_weeks(teaching_plan))
- Akış Bağlantısı: Öncelikle Live API uç noktasıyla kalıcı bir bağlantı kurulur. Bir istek gönderip yanıt aldığınız standart API çağrısının aksine bu bağlantı, sürekli veri alışverişi için açık kalır.
- Çoklu Modlu Yapılandırma: Ne tür bir çıkış istediğinizi (bu durumda ses) belirtmek için yapılandırmayı kullanın. Hatta kullanmak istediğiniz parametreleri (ör. ses seçimi, ses kodlaması) de belirtebilirsiniz.
- Eşzamansız İşleme: Bu API, eşzamansız olarak çalışır. Yani ses oluşturma işleminin tamamlanmasını beklerken ana iş parçacığını engellemez. Verileri gerçek zamanlı olarak işleyerek ve çıktıyı parçalar halinde göndererek neredeyse anında bir deneyim sunar.
Şimdi, asıl soru şu: Bu ses oluşturma işlemi ne zaman çalıştırılmalıdır? İdeal olarak, sesli özetlerin yeni bir eğitim planı oluşturulduktan hemen sonra kullanılabilmesini isteriz. Eğitim planını bir Pub/Sub konusuna yayınlayarak olay odaklı bir mimari uyguladığımızdan, bu konuya abone olabiliriz.
Ancak yeni öğretim planları sık sık oluşturulmaz. Sürekli çalışan ve yeni planlar bekleyen bir temsilcinin olması verimli olmaz. Bu nedenle, bu ses oluşturma mantığını bir Cloud Run işlevi olarak dağıtmak son derece mantıklı bir seçimdir.
İşlev olarak dağıtıldığında, Pub/Sub konusuna yeni bir mesaj yayınlanana kadar etkin durumda kalmaz. Bu durumda işlev otomatik olarak tetiklenir. İşlev, ses özetlerini oluşturur ve paketimizde saklar.
👉main.py
dosyasındaki course
klasöründe bulunan bu dosya, yeni bir öğretim planı mevcut olduğunda tetiklenecek Cloud Run işlevini tanımlar. Planı alır ve ses özeti oluşturma işlemini başlatır. Dosyanın sonuna aşağıdaki kod snippet'ini ekleyin.
@functions_framework.cloud_event
def process_teaching_plan(cloud_event):
print(f"CloudEvent received: {cloud_event.data}")
time.sleep(60)
try:
if isinstance(cloud_event.data.get('message', {}).get('data'), str): # Check for base64 encoding
data = json.loads(base64.b64decode(cloud_event.data['message']['data']).decode('utf-8'))
teaching_plan = data.get('teaching_plan') # Get the teaching plan
elif 'teaching_plan' in cloud_event.data: # No base64
teaching_plan = cloud_event.data["teaching_plan"]
else:
raise KeyError("teaching_plan not found") # Handle error explicitly
#Load the teaching_plan as string and from cloud event, call audio breakup_sessions
breakup_sessions(teaching_plan)
return "Teaching plan processed successfully", 200
except (json.JSONDecodeError, AttributeError, KeyError) as e:
print(f"Error decoding CloudEvent data: {e} - Data: {cloud_event.data}")
return "Error processing event", 500
except Exception as e:
print(f"Error processing teaching plan: {e}")
return "Error processing teaching plan", 500
@functions_framework.cloud_event: Bu süsleyici, işlevi CloudEvents tarafından tetiklenecek bir Cloud Run işlevi olarak işaretler.
Yerel olarak test etme
👉Bu kodu sanal bir ortamda çalıştırıp Cloud Run işlevi için gerekli Python kitaplıklarını yükleyeceğiz.
cd ~/aidemy-bootstrap/courses
export COURSE_BUCKET_NAME=$(gcloud storage buckets list --format="value(name)" | grep aidemy-recap)
python -m venv env
source env/bin/activate
pip install -r requirements.txt
👉Cloud Run işlev emülatörü, işlevimizi Google Cloud'a dağıtmadan önce yerel olarak test etmemizi sağlar. Aşağıdaki komutu çalıştırarak yerel bir emülatör başlatın:
functions-framework --target process_teaching_plan --signature-type=cloudevent --source main.py
👉Emülatör çalışırken, yeni bir öğretim planının yayınlanmasını simüle etmek için emülatöre test CloudEvents gönderebilirsiniz. Yeni bir terminalde:
👉Çalıştır:
curl -X POST \
http://localhost:8080/ \
-H "Content-Type: application/json" \
-H "ce-id: event-id-01" \
-H "ce-source: planner-agent" \
-H "ce-specversion: 1.0" \
-H "ce-type: google.cloud.pubsub.topic.v1.messagePublished" \
-d '{
"message": {
"data": "eyJ0ZWFjaGluZ19wbGFuIjogIldlZWsgMTogMkQgU2hhcGVzIGFuZCBBbmdsZXMgLSBEYXkgMTogUmV2aWV3IG9mIGJhc2ljIDJEIHNoYXBlcyAoc3F1YXJlcywgcmVjdGFuZ2xlcywgdHJpYW5nbGVzLCBjaXJjbGVzKS4gRGF5IDI6IEV4cGxvcmluZyBkaWZmZXJlbnQgdHlwZXMgb2YgdHJpYW5nbGVzIChlcXVpbGF0ZXJhbCwgaXNvc2NlbGVzLCBzY2FsZW5lLCByaWdodC1hbmdsZWQpLiBEYXkgMzogRXhwbG9yaW5nIHF1YWRyaWxhdGVyYWxzIChzcXVhcmUsIHJlY3RhbmdsZSwgcGFyYWxsZWxvZ3JhbSwgcmhvbWJ1cywgdHJhcGV6aXVtKS4gRGF5IDQ6IEludHJvZHVjdGlvbiB0byBhbmdsZXM6IHJpZ2h0IGFuZ2xlcywgYWN1dGUgYW5nbGVzLCBhbmQgb2J0dXNlIGFuZ2xlcy4gRGF5IDU6IE1lYXN1cmluZyBhbmdsZXMgdXNpbmcgYSBwcm90cmFjdG9yLiBXZWVrIDI6IDNEIFNoYXBlcyBhbmQgU3ltbWV0cnkgLSBEYXkgNjogSW50cm9kdWN0aW9uIHRvIDNEIHNoYXBlczogY3ViZXMsIGN1Ym9pZHMsIHNwaGVyZXMsIGN5bGluZGVycywgY29uZXMsIGFuZCBweXJhbWlkcy4gRGF5IDc6IERlc2NyaWJpbmcgM0Qgc2hhcGVzIHVzaW5nIGZhY2VzLCBlZGdlcywgYW5kIHZlcnRpY2VzLiBEYXkgODogUmVsYXRpbmcgMkQgc2hhcGVzIHRvIDNEIHNoYXBlcy4gRGF5IDk6IElkZW50aWZ5aW5nIGxpbmVzIG9mIHN5bW1ldHJ5IGluIDJEIHNoYXBlcy4gRGF5IDEwOiBDb21wbGV0aW5nIHN5bW1ldHJpY2FsIGZpZ3VyZXMuIFdlZWsgMzogUG9zaXRpb24sIERpcmVjdGlvbiwgYW5kIFByb2JsZW0gU29sdmluZyAtIERheSAxMTogRGVzY3JpYmluZyBwb3NpdGlvbiB1c2luZyBjb29yZGluYXRlcyBpbiB0aGUgZmlyc3QgcXVhZHJhbnQuIERheSAxMjogUGxvdHRpbmcgY29vcmRpbmF0ZXMgdG8gZHJhdyBzaGFwZXMuIERheSAxMzogVW5kZXJzdGFuZGluZyB0cmFuc2xhdGlvbiAoc2xpZGluZyBhIHNoYXBlKS4gRGF5IDE0OiBVbmRlcnN0YW5kaW5nIHJlZmxlY3Rpb24gKGZsaXBwaW5nIGEgc2hhcGUpLiBEYXkgMTU6IFByb2JsZW0tc29sdmluZyBhY3Rpdml0aWVzIGludm9sdmluZyBwZXJpbWV0ZXIsIGFyZWEsIGFuZCBtaXNzaW5nIGFuZ2xlcy4ifQ=="
}
}'
Yanıtı beklerken ekrana boş boş bakmak yerine diğer Cloud Shell terminaline geçin. İşlemcinin terminalinde, ilerleme durumunu ve işleviniz tarafından oluşturulan çıkış veya hata mesajlarını gözlemleyebilirsiniz. 😁
2. terminale döndüğünüzde OK
değerini göreceksiniz.
👉Paketteki verileri doğrularsınız. Cloud Storage'a gidip "Paket" sekmesini, ardından aidemy-recap-xxx
👉Emülatörü çalıştıran terminalde çıkmak için ctrl+c
yazın. İkinci terminali kapatın. İkinci terminali kapatın ve sanal ortamdan çıkmak için devre dışı bırakma komutunu çalıştırın.
deactivate
Google Cloud'a dağıtma
👉Yerel olarak test ettikten sonra kurs aracısını Google Cloud'a dağıtma zamanı gelmiştir. Terminalde şu komutları çalıştırın:
cd ~/aidemy-bootstrap/courses
export COURSE_BUCKET_NAME=$(gcloud storage buckets list --format="value(name)" | grep aidemy-recap)
gcloud functions deploy courses-agent \
--region=us-central1 \
--gen2 \
--source=. \
--runtime=python312 \
--trigger-topic=plan \
--entry-point=process_teaching_plan \
--set-env-vars=GOOGLE_CLOUD_PROJECT=${PROJECT_ID},COURSE_BUCKET_NAME=$COURSE_BUCKET_NAME
Google Cloud Console'da Cloud Run'a giderek dağıtımı doğrulayın.Listelenen courses-agent adlı yeni bir hizmet görürsünüz.
Tetikleyici yapılandırmasını kontrol etmek için courses-agent hizmetini tıklayarak ayrıntılarını görüntüleyin. "Tetikleyiciler" sekmesine gidin.
Plan konusunda yayınlanan mesajları dinleyecek şekilde yapılandırılmış bir tetikleyici görürsünüz.
Son olarak, uçtan uca çalıştırmayı görelim.
👉Ardından, portal aracısını, oluşturulan ses dosyalarını nerede bulacağını bilecek şekilde yapılandırmamız gerekir. Terminalde şu komutu çalıştırın:
export COURSE_BUCKET_NAME=$(gcloud storage buckets list --format="value(name)" | grep aidemy-recap)
export PROJECT_ID=$(gcloud config get project)
gcloud run services update aidemy-portal \
--region=us-central1 \
--set-env-vars=GOOGLE_CLOUD_PROJECT=${PROJECT_ID},COURSE_BUCKET_NAME=$COURSE_BUCKET_NAME
👉Planlayıcı temsilcisi sayfasında yeni bir öğretim planı oluşturmayı deneyin. Başlaması birkaç dakika sürebilir. Endişelenmeyin, bu sunucusuz bir hizmettir. Planlayıcı temsilcinizin URL'sini alın (Yanında yoksa bunu terminalde çalıştırın):
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner
Yeni planı oluşturduktan sonra sesin oluşturulması için 2-3 dakika bekleyin. Bu işlem, bu laboratuvar hesabındaki faturalandırma sınırlaması nedeniyle birkaç dakika daha sürebilir.
courses-agent
işlevinin öğretim planını alıp almadığını, işlevin "Tetikleyiciler" sekmesini kontrol ederek izleyebilirsiniz. Sayfayı düzenli olarak yenileyin. İşlevin çağrıldığını göreceksiniz. İşlev 2 dakikadan uzun bir süre sonra çağrılmadıysa öğretim planını tekrar oluşturmayı deneyebilirsiniz. Ancak oluşturulan her plan, temsilci tarafından sırayla tüketilip işleneceğinden, arka arkaya hızlı bir şekilde tekrar tekrar plan oluşturmaktan kaçının. Bu, iş yükü oluşturabilir.
👉Portalı ziyaret edin ve "Kurslar"ı tıklayın. Her biri ses özetini gösteren üç kart görürsünüz. Portal temsilcinizin URL'sini bulmak için:
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep portal
Ses özetlerinin, yeni oluşturduğunuz öğretim planıyla uyumlu olduğundan emin olmak için her bir kursta "oynat"ı tıklayın.
Sanal ortamdan çıkın.
deactivate
13. İSTEĞE BAĞLI: Gemini ve DeepSeek ile rol tabanlı ortak çalışma
Özellikle ilgi çekici ve anlamlı ödevler hazırlarken birden fazla bakış açısına sahip olmak çok değerlidir. Şimdi, ödev oluşturmak için farklı rollere sahip iki farklı modelden yararlanan çok aracılı bir sistem oluşturacağız: Biri işbirliğini, diğeri ise kendi kendine çalışmayı teşvik ediyor. İş akışının sabit bir rota izlediğini varsaydığımız "tek atış" mimarisini kullanacağız.
Gemini Ödev Oluşturucu
Gemini işlevini, ortak çalışmaya vurgu yapan ödevler oluşturacak şekilde ayarlayarak başlayacağız.
assignment
klasöründeki gemini.py
dosyasını düzenleyin.
👉Aşağıdaki kodu gemini.py
dosyasının sonuna yapıştırın:
def gen_assignment_gemini(state):
region=get_next_region()
client = genai.Client(vertexai=True, project=PROJECT_ID, location=region)
print(f"---------------gen_assignment_gemini")
response = client.models.generate_content(
model=MODEL_ID, contents=f"""
You are an instructor
Develop engaging and practical assignments for each week, ensuring they align with the teaching plan's objectives and progressively build upon each other.
For each week, provide the following:
* **Week [Number]:** A descriptive title for the assignment (e.g., "Data Exploration Project," "Model Building Exercise").
* **Learning Objectives Assessed:** List the specific learning objectives from the teaching plan that this assignment assesses.
* **Description:** A detailed description of the task, including any specific requirements or constraints. Provide examples or scenarios if applicable.
* **Deliverables:** Specify what students need to submit (e.g., code, report, presentation).
* **Estimated Time Commitment:** The approximate time students should dedicate to completing the assignment.
* **Assessment Criteria:** Briefly outline how the assignment will be graded (e.g., correctness, completeness, clarity, creativity).
The assignments should be a mix of individual and collaborative work where appropriate. Consider different learning styles and provide opportunities for students to apply their knowledge creatively.
Based on this teaching plan: {state["teaching_plan"]}
"""
)
print(f"---------------gen_assignment_gemini answer {response.text}")
state["model_one_assignment"] = response.text
return state
import unittest
class TestGenAssignmentGemini(unittest.TestCase):
def test_gen_assignment_gemini(self):
test_teaching_plan = "Week 1: 2D Shapes and Angles - Day 1: Review of basic 2D shapes (squares, rectangles, triangles, circles). Day 2: Exploring different types of triangles (equilateral, isosceles, scalene, right-angled). Day 3: Exploring quadrilaterals (square, rectangle, parallelogram, rhombus, trapezium). Day 4: Introduction to angles: right angles, acute angles, and obtuse angles. Day 5: Measuring angles using a protractor. Week 2: 3D Shapes and Symmetry - Day 6: Introduction to 3D shapes: cubes, cuboids, spheres, cylinders, cones, and pyramids. Day 7: Describing 3D shapes using faces, edges, and vertices. Day 8: Relating 2D shapes to 3D shapes. Day 9: Identifying lines of symmetry in 2D shapes. Day 10: Completing symmetrical figures. Week 3: Position, Direction, and Problem Solving - Day 11: Describing position using coordinates in the first quadrant. Day 12: Plotting coordinates to draw shapes. Day 13: Understanding translation (sliding a shape). Day 14: Understanding reflection (flipping a shape). Day 15: Problem-solving activities involving perimeter, area, and missing angles."
initial_state = {"teaching_plan": test_teaching_plan, "model_one_assignment": "", "model_two_assigmodel_one_assignmentnment": "", "final_assignment": ""}
updated_state = gen_assignment_gemini(initial_state)
self.assertIn("model_one_assignment", updated_state)
self.assertIsNotNone(updated_state["model_one_assignment"])
self.assertIsInstance(updated_state["model_one_assignment"], str)
self.assertGreater(len(updated_state["model_one_assignment"]), 0)
print(updated_state["model_one_assignment"])
if __name__ == '__main__':
unittest.main()
Ödev oluşturmak için Gemini modelini kullanır.
Gemini aracısını test etmeye hazırız.
👉Ortamı ayarlamak için terminalde aşağıdaki komutları çalıştırın:
cd ~/aidemy-bootstrap/assignment
export PROJECT_ID=$(gcloud config get project)
python -m venv env
source env/bin/activate
pip install -r requirements.txt
👉Test etmek için şunları çalıştırabilirsiniz:
python gemini.py
Sonuçta daha fazla grup çalışması içeren bir ödev görürsünüz. Sonundaki assert testi de sonuçları döndürür.
Here are some engaging and practical assignments for each week, designed to build progressively upon the teaching plan's objectives:
**Week 1: Exploring the World of 2D Shapes**
* **Learning Objectives Assessed:**
* Identify and name basic 2D shapes (squares, rectangles, triangles, circles).
* .....
* **Description:**
* **Shape Scavenger Hunt:** Students will go on a scavenger hunt in their homes or neighborhoods, taking pictures of objects that represent different 2D shapes. They will then create a presentation or poster showcasing their findings, classifying each shape and labeling its properties (e.g., number of sides, angles, etc.).
* **Triangle Trivia:** Students will research and create a short quiz or presentation about different types of triangles, focusing on their properties and real-world examples.
* **Angle Exploration:** Students will use a protractor to measure various angles in their surroundings, such as corners of furniture, windows, or doors. They will record their measurements and create a chart categorizing the angles as right, acute, or obtuse.
....
**Week 2: Delving into the World of 3D Shapes and Symmetry**
* **Learning Objectives Assessed:**
* Identify and name basic 3D shapes.
* ....
* **Description:**
* **3D Shape Construction:** Students will work in groups to build 3D shapes using construction paper, cardboard, or other materials. They will then create a presentation showcasing their creations, describing the number of faces, edges, and vertices for each shape.
* **Symmetry Exploration:** Students will investigate the concept of symmetry by creating a visual representation of various symmetrical objects (e.g., butterflies, leaves, snowflakes) using drawing or digital tools. They will identify the lines of symmetry and explain their findings.
* **Symmetry Puzzles:** Students will be given a half-image of a symmetrical figure and will be asked to complete the other half, demonstrating their understanding of symmetry. This can be done through drawing, cut-out activities, or digital tools.
**Week 3: Navigating Position, Direction, and Problem Solving**
* **Learning Objectives Assessed:**
* Describe position using coordinates in the first quadrant.
* ....
* **Description:**
* **Coordinate Maze:** Students will create a maze using coordinates on a grid paper. They will then provide directions for navigating the maze using a combination of coordinate movements and translation/reflection instructions.
* **Shape Transformations:** Students will draw shapes on a grid paper and then apply transformations such as translation and reflection, recording the new coordinates of the transformed shapes.
* **Geometry Challenge:** Students will solve real-world problems involving perimeter, area, and angles. For example, they could be asked to calculate the perimeter of a room, the area of a garden, or the missing angle in a triangle.
....
ctl+c
ile durun ve test kodunu temizleyin. Aşağıdaki kodu gemini.py
'den KALDIRIN.
import unittest
class TestGenAssignmentGemini(unittest.TestCase):
def test_gen_assignment_gemini(self):
test_teaching_plan = "Week 1: 2D Shapes and Angles - Day 1: Review of basic 2D shapes (squares, rectangles, triangles, circles). Day 2: Exploring different types of triangles (equilateral, isosceles, scalene, right-angled). Day 3: Exploring quadrilaterals (square, rectangle, parallelogram, rhombus, trapezium). Day 4: Introduction to angles: right angles, acute angles, and obtuse angles. Day 5: Measuring angles using a protractor. Week 2: 3D Shapes and Symmetry - Day 6: Introduction to 3D shapes: cubes, cuboids, spheres, cylinders, cones, and pyramids. Day 7: Describing 3D shapes using faces, edges, and vertices. Day 8: Relating 2D shapes to 3D shapes. Day 9: Identifying lines of symmetry in 2D shapes. Day 10: Completing symmetrical figures. Week 3: Position, Direction, and Problem Solving - Day 11: Describing position using coordinates in the first quadrant. Day 12: Plotting coordinates to draw shapes. Day 13: Understanding translation (sliding a shape). Day 14: Understanding reflection (flipping a shape). Day 15: Problem-solving activities involving perimeter, area, and missing angles."
initial_state = {"teaching_plan": test_teaching_plan, "model_one_assignment": "", "model_two_assigmodel_one_assignmentnment": "", "final_assignment": ""}
updated_state = gen_assignment_gemini(initial_state)
self.assertIn("model_one_assignment", updated_state)
self.assertIsNotNone(updated_state["model_one_assignment"])
self.assertIsInstance(updated_state["model_one_assignment"], str)
self.assertGreater(len(updated_state["model_one_assignment"]), 0)
print(updated_state["model_one_assignment"])
if __name__ == '__main__':
unittest.main()
DeepSeek Ödev Oluşturucusunu yapılandırma
Bulut tabanlı yapay zeka platformları kullanışlı olsa da kendi kendine barındırılan LLM'ler, veri gizliliğini korumak ve veri egemenliğini sağlamak için çok önemli olabilir. En küçük DeepSeek modelini (1,5 milyar parametre) bir Cloud Compute Engine örneğine dağıtacağız. Google'ın Vertex AI platformunda veya GKE örneğinizde barındırma gibi başka yöntemler de vardır ancak bu yalnızca yapay zeka aracıları konulu bir atölye olduğu ve sizi burada sonsuza kadar bekletmek istemediğim için en basit yöntemi kullanalım. Ancak ilgileniyorsanız ve diğer seçenekleri incelemek istiyorsanız ödev klasöründeki deepseek-vertexai.py
dosyasına göz atın. Bu dosyada, VertexAI'da dağıtılan modellerle nasıl etkileşim kurulacağına dair örnek bir kod sağlanır.
👉Ollama'yı kendi kendine barındırılan bir LLM platformu olarak oluşturmak için terminalde şu komutu çalıştırın:
cd ~/aidemy-bootstrap/assignment
gcloud compute instances create ollama-instance \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--machine-type=e2-standard-4 \
--zone=us-central1-a \
--metadata-from-file startup-script=startup.sh \
--boot-disk-size=50GB \
--tags=ollama \
--scopes=https://www.googleapis.com/auth/cloud-platform
Compute Engine örneğinin çalıştığını doğrulamak için:
Google Cloud Console'da Compute Engine > "Sanal makine örnekleri"ne gidin. ollama-instance
, yeşil onay işaretiyle birlikte çalışır durumda olarak listelenir. Bu seçeneği görmüyorsanız alt bölgenin us-central1 olduğundan emin olun. Aksi takdirde, ürünü aramanız gerekebilir.
👉En küçük DeepSeek modelini yükleyip test edeceğiz. Cloud Shell Düzenleyici'ye dönüp Yeni bir terminalde GCE örneğine SSH erişimi için aşağıdaki komutu çalıştırın.
gcloud compute ssh ollama-instance --zone=us-central1-a
SSH bağlantısı kurulduktan sonra sizden aşağıdakiler istenebilir:
"Devam etmek istiyor musunuz (Y/n)?"
Devam etmek için Y
(büyük/küçük harf duyarlı değildir) yazıp Enter tuşuna basmanız yeterlidir.
Ardından, SSH anahtarı için bir şifre ifadesi oluşturmanız istenebilir. Parola kullanmamayı tercih ediyorsanız varsayılan değeri (şifre yok) kabul etmek için Enter tuşuna iki kez basmanız yeterlidir.
👉Şimdi sanal makinedesiniz. En küçük DeepSeek R1 modelini çekin ve çalışıp çalışmadığını test edin.
ollama pull deepseek-r1:1.5b
ollama run deepseek-r1:1.5b "who are you?"
👉GCE örneğinden çıkın ve ssh terminaline aşağıdakileri girin:
exit
Yeni terminali kapatın ve orijinal terminale dönün.
👉Ayrıca, diğer hizmetlerin LLM'ye erişebilmesi için ağ politikasını ayarlamayı unutmayın. Bunu üretim için yapmak istiyorsanız lütfen örneğin erişimini sınırlayın, hizmet için güvenlik girişi uygulayın veya IP erişimini kısıtlayın. Çalıştırın:
gcloud compute firewall-rules create allow-ollama-11434 \
--allow=tcp:11434 \
--target-tags=ollama \
--description="Allow access to Ollama on port 11434"
👉Güvenlik duvarı politikanızın düzgün çalışıp çalışmadığını doğrulamak için şunları çalıştırmayı deneyin:
export OLLAMA_HOST=http://$(gcloud compute instances describe ollama-instance --zone=us-central1-a --format='value(networkInterfaces[0].accessConfigs[0].natIP)'):11434
curl -X POST "${OLLAMA_HOST}/api/generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Hello, what are you?",
"model": "deepseek-r1:1.5b",
"stream": false
}'
Ardından, ödev aracındaki Deepseek işlevi üzerinde çalışarak bireysel çalışmalara vurgu yapan ödevler oluşturacağız.
👉assignment
klasörünün altında deepseek.py
dosyasını düzenleyin ve sonuna aşağıdaki snippet'i ekleyin
def gen_assignment_deepseek(state):
print(f"---------------gen_assignment_deepseek")
template = """
You are an instructor who favor student to focus on individual work.
Develop engaging and practical assignments for each week, ensuring they align with the teaching plan's objectives and progressively build upon each other.
For each week, provide the following:
* **Week [Number]:** A descriptive title for the assignment (e.g., "Data Exploration Project," "Model Building Exercise").
* **Learning Objectives Assessed:** List the specific learning objectives from the teaching plan that this assignment assesses.
* **Description:** A detailed description of the task, including any specific requirements or constraints. Provide examples or scenarios if applicable.
* **Deliverables:** Specify what students need to submit (e.g., code, report, presentation).
* **Estimated Time Commitment:** The approximate time students should dedicate to completing the assignment.
* **Assessment Criteria:** Briefly outline how the assignment will be graded (e.g., correctness, completeness, clarity, creativity).
The assignments should be a mix of individual and collaborative work where appropriate. Consider different learning styles and provide opportunities for students to apply their knowledge creatively.
Based on this teaching plan: {teaching_plan}
"""
prompt = ChatPromptTemplate.from_template(template)
model = OllamaLLM(model="deepseek-r1:1.5b",
base_url=OLLAMA_HOST)
chain = prompt | model
response = chain.invoke({"teaching_plan":state["teaching_plan"]})
state["model_two_assignment"] = response
return state
import unittest
class TestGenAssignmentDeepseek(unittest.TestCase):
def test_gen_assignment_deepseek(self):
test_teaching_plan = "Week 1: 2D Shapes and Angles - Day 1: Review of basic 2D shapes (squares, rectangles, triangles, circles). Day 2: Exploring different types of triangles (equilateral, isosceles, scalene, right-angled). Day 3: Exploring quadrilaterals (square, rectangle, parallelogram, rhombus, trapezium). Day 4: Introduction to angles: right angles, acute angles, and obtuse angles. Day 5: Measuring angles using a protractor. Week 2: 3D Shapes and Symmetry - Day 6: Introduction to 3D shapes: cubes, cuboids, spheres, cylinders, cones, and pyramids. Day 7: Describing 3D shapes using faces, edges, and vertices. Day 8: Relating 2D shapes to 3D shapes. Day 9: Identifying lines of symmetry in 2D shapes. Day 10: Completing symmetrical figures. Week 3: Position, Direction, and Problem Solving - Day 11: Describing position using coordinates in the first quadrant. Day 12: Plotting coordinates to draw shapes. Day 13: Understanding translation (sliding a shape). Day 14: Understanding reflection (flipping a shape). Day 15: Problem-solving activities involving perimeter, area, and missing angles."
initial_state = {"teaching_plan": test_teaching_plan, "model_one_assignment": "", "model_two_assignment": "", "final_assignment": ""}
updated_state = gen_assignment_deepseek(initial_state)
self.assertIn("model_two_assignment", updated_state)
self.assertIsNotNone(updated_state["model_two_assignment"])
self.assertIsInstance(updated_state["model_two_assignment"], str)
self.assertGreater(len(updated_state["model_two_assignment"]), 0)
print(updated_state["model_two_assignment"])
if __name__ == '__main__':
unittest.main()
👉Şimdi çalıştırarak test edelim:
cd ~/aidemy-bootstrap/assignment
source env/bin/activate
export PROJECT_ID=$(gcloud config get project)
export OLLAMA_HOST=http://$(gcloud compute instances describe ollama-instance --zone=us-central1-a --format='value(networkInterfaces[0].accessConfigs[0].natIP)'):11434
python deepseek.py
Daha fazla kendi kendine çalışma içeren bir ödev görürsünüz.
**Assignment Plan for Each Week**
---
### **Week 1: 2D Shapes and Angles**
- **Week Title:** "Exploring 2D Shapes"
Assign students to research and present on various 2D shapes. Include a project where they create models using straws and tape for triangles, draw quadrilaterals with specific measurements, and compare their properties.
### **Week 2: 3D Shapes and Symmetry**
Assign students to create models or nets for cubes and cuboids. They will also predict how folding these nets form the 3D shapes. Include a project where they identify symmetrical properties using mirrors or folding techniques.
### **Week 3: Position, Direction, and Problem Solving**
Assign students to use mirrors or folding techniques for reflections. Include activities where they measure angles, use a protractor, solve problems involving perimeter/area, and create symmetrical designs.
....
👉ctl+c
'yi durdurun ve test kodunu temizleyin. Aşağıdaki kodu deepseek.py
'den KALDIRIN.
import unittest
class TestGenAssignmentDeepseek(unittest.TestCase):
def test_gen_assignment_deepseek(self):
test_teaching_plan = "Week 1: 2D Shapes and Angles - Day 1: Review of basic 2D shapes (squares, rectangles, triangles, circles). Day 2: Exploring different types of triangles (equilateral, isosceles, scalene, right-angled). Day 3: Exploring quadrilaterals (square, rectangle, parallelogram, rhombus, trapezium). Day 4: Introduction to angles: right angles, acute angles, and obtuse angles. Day 5: Measuring angles using a protractor. Week 2: 3D Shapes and Symmetry - Day 6: Introduction to 3D shapes: cubes, cuboids, spheres, cylinders, cones, and pyramids. Day 7: Describing 3D shapes using faces, edges, and vertices. Day 8: Relating 2D shapes to 3D shapes. Day 9: Identifying lines of symmetry in 2D shapes. Day 10: Completing symmetrical figures. Week 3: Position, Direction, and Problem Solving - Day 11: Describing position using coordinates in the first quadrant. Day 12: Plotting coordinates to draw shapes. Day 13: Understanding translation (sliding a shape). Day 14: Understanding reflection (flipping a shape). Day 15: Problem-solving activities involving perimeter, area, and missing angles."
initial_state = {"teaching_plan": test_teaching_plan, "model_one_assignment": "", "model_two_assignment": "", "final_assignment": ""}
updated_state = gen_assignment_deepseek(initial_state)
self.assertIn("model_two_assignment", updated_state)
self.assertIsNotNone(updated_state["model_two_assignment"])
self.assertIsInstance(updated_state["model_two_assignment"], str)
self.assertGreater(len(updated_state["model_two_assignment"]), 0)
print(updated_state["model_two_assignment"])
if __name__ == '__main__':
unittest.main()
Şimdi, her iki atamayı da yeni bir atamada birleştirmek için aynı Gemini modelini kullanacağız. assignment
klasöründeki gemini.py
dosyasını düzenleyin.
👉Aşağıdaki kodu gemini.py
dosyasının sonuna yapıştırın:
def combine_assignments(state):
print(f"---------------combine_assignments ")
region=get_next_region()
client = genai.Client(vertexai=True, project=PROJECT_ID, location=region)
response = client.models.generate_content(
model=MODEL_ID, contents=f"""
Look at all the proposed assignment so far {state["model_one_assignment"]} and {state["model_two_assignment"]}, combine them and come up with a final assignment for student.
"""
)
state["final_assignment"] = response.text
return state
Her iki modelin güçlü yönlerini birleştirmek için LangGraph'ı kullanarak tanımlanmış bir iş akışı düzenleyeceğiz. Bu iş akışı üç adımdan oluşur: İlk olarak Gemini modeli, ortak çalışmaya odaklanan bir ödev oluşturur; ikinci olarak DeepSeek modeli, bireysel çalışmayı vurgulayan bir ödev oluşturur; son olarak Gemini bu iki ödevi tek bir kapsamlı ödevde birleştirir. LLM karar verme süreci olmadan adım sırasını önceden tanımladığımız için bu, tek, kullanıcı tanımlı bir orkestrasyon oluşturur.
👉assignment
klasöründeki main.py
dosyasının sonuna aşağıdaki kodu yapıştırın:
def create_assignment(teaching_plan: str):
print(f"create_assignment---->{teaching_plan}")
builder = StateGraph(State)
builder.add_node("gen_assignment_gemini", gen_assignment_gemini)
builder.add_node("gen_assignment_deepseek", gen_assignment_deepseek)
builder.add_node("combine_assignments", combine_assignments)
builder.add_edge(START, "gen_assignment_gemini")
builder.add_edge("gen_assignment_gemini", "gen_assignment_deepseek")
builder.add_edge("gen_assignment_deepseek", "combine_assignments")
builder.add_edge("combine_assignments", END)
graph = builder.compile()
state = graph.invoke({"teaching_plan": teaching_plan})
return state["final_assignment"]
import unittest
class TestCreatAssignment(unittest.TestCase):
def test_create_assignment(self):
test_teaching_plan = "Week 1: 2D Shapes and Angles - Day 1: Review of basic 2D shapes (squares, rectangles, triangles, circles). Day 2: Exploring different types of triangles (equilateral, isosceles, scalene, right-angled). Day 3: Exploring quadrilaterals (square, rectangle, parallelogram, rhombus, trapezium). Day 4: Introduction to angles: right angles, acute angles, and obtuse angles. Day 5: Measuring angles using a protractor. Week 2: 3D Shapes and Symmetry - Day 6: Introduction to 3D shapes: cubes, cuboids, spheres, cylinders, cones, and pyramids. Day 7: Describing 3D shapes using faces, edges, and vertices. Day 8: Relating 2D shapes to 3D shapes. Day 9: Identifying lines of symmetry in 2D shapes. Day 10: Completing symmetrical figures. Week 3: Position, Direction, and Problem Solving - Day 11: Describing position using coordinates in the first quadrant. Day 12: Plotting coordinates to draw shapes. Day 13: Understanding translation (sliding a shape). Day 14: Understanding reflection (flipping a shape). Day 15: Problem-solving activities involving perimeter, area, and missing angles."
initial_state = {"teaching_plan": test_teaching_plan, "model_one_assignment": "", "model_two_assignment": "", "final_assignment": ""}
updated_state = create_assignment(initial_state)
print(updated_state)
if __name__ == '__main__':
unittest.main()
👉create_assignment
işlevini ilk kez test etmek ve Gemini ile DeepSeek'i birleştiren iş akışının işlevsel olduğunu onaylamak için aşağıdaki komutu çalıştırın:
cd ~/aidemy-bootstrap/assignment
source env/bin/activate
pip install -r requirements.txt
python main.py
Hem öğrenci çalışmaları hem de öğrenci grup çalışmaları için her iki modeli de kendi bakış açılarıyla birleştiren bir şey görürsünüz.
**Tasks:**
1. **Clue Collection:** Gather all the clues left by the thieves. These clues will include:
* Descriptions of shapes and their properties (angles, sides, etc.)
* Coordinate grids with hidden messages
* Geometric puzzles requiring transformation (translation, reflection, rotation)
* Challenges involving area, perimeter, and angle calculations
2. **Clue Analysis:** Decipher each clue using your geometric knowledge. This will involve:
* Identifying the shape and its properties
* Plotting coordinates and interpreting patterns on the grid
* Solving geometric puzzles by applying transformations
* Calculating area, perimeter, and missing angles
3. **Case Report:** Create a comprehensive case report outlining your findings. This report should include:
* A detailed explanation of each clue and its solution
* Sketches and diagrams to support your explanations
* A step-by-step account of how you followed the clues to locate the artifact
* A final conclusion about the thieves and their motives
👉ctl+c
'yi durdurun ve test kodunu temizleyin. Aşağıdaki kodu main.py
'den KALDIRIN.
import unittest
class TestCreatAssignment(unittest.TestCase):
def test_create_assignment(self):
test_teaching_plan = "Week 1: 2D Shapes and Angles - Day 1: Review of basic 2D shapes (squares, rectangles, triangles, circles). Day 2: Exploring different types of triangles (equilateral, isosceles, scalene, right-angled). Day 3: Exploring quadrilaterals (square, rectangle, parallelogram, rhombus, trapezium). Day 4: Introduction to angles: right angles, acute angles, and obtuse angles. Day 5: Measuring angles using a protractor. Week 2: 3D Shapes and Symmetry - Day 6: Introduction to 3D shapes: cubes, cuboids, spheres, cylinders, cones, and pyramids. Day 7: Describing 3D shapes using faces, edges, and vertices. Day 8: Relating 2D shapes to 3D shapes. Day 9: Identifying lines of symmetry in 2D shapes. Day 10: Completing symmetrical figures. Week 3: Position, Direction, and Problem Solving - Day 11: Describing position using coordinates in the first quadrant. Day 12: Plotting coordinates to draw shapes. Day 13: Understanding translation (sliding a shape). Day 14: Understanding reflection (flipping a shape). Day 15: Problem-solving activities involving perimeter, area, and missing angles."
initial_state = {"teaching_plan": test_teaching_plan, "model_one_assignment": "", "model_two_assignment": "", "final_assignment": ""}
updated_state = create_assignment(initial_state)
print(updated_state)
if __name__ == '__main__':
unittest.main()
Ödev oluşturma sürecini otomatik hale getirmek ve yeni öğretim planlarına uyum sağlamak için mevcut olaya dayalı mimariden yararlanacağız. Aşağıdaki kod, "plan" Pub/Sub konusuna yeni bir eğitim planı her yayınlandığında tetiklenecek bir Cloud Run işlevi (generate_assignment) tanımlar.
👉main.py
dosyasının sonuna aşağıdaki kodu ekleyin:
@functions_framework.cloud_event
def generate_assignment(cloud_event):
print(f"CloudEvent received: {cloud_event.data}")
try:
if isinstance(cloud_event.data.get('message', {}).get('data'), str):
data = json.loads(base64.b64decode(cloud_event.data['message']['data']).decode('utf-8'))
teaching_plan = data.get('teaching_plan')
elif 'teaching_plan' in cloud_event.data:
teaching_plan = cloud_event.data["teaching_plan"]
else:
raise KeyError("teaching_plan not found")
assignment = create_assignment(teaching_plan)
print(f"Assignment---->{assignment}")
#Store the return assignment into bucket as a text file
storage_client = storage.Client()
bucket = storage_client.bucket(ASSIGNMENT_BUCKET)
file_name = f"assignment-{random.randint(1, 1000)}.txt"
blob = bucket.blob(file_name)
blob.upload_from_string(assignment)
return f"Assignment generated and stored in {ASSIGNMENT_BUCKET}/{file_name}", 200
except (json.JSONDecodeError, AttributeError, KeyError) as e:
print(f"Error decoding CloudEvent data: {e} - Data: {cloud_event.data}")
return "Error processing event", 500
except Exception as e:
print(f"Error generate assignment: {e}")
return "Error generate assignment", 500
Yerel olarak test etme
Google Cloud'a dağıtmadan önce Cloud Run işlevini yerel olarak test etmek iyi bir uygulamadır. Bu sayede iterasyon daha hızlı olur ve hata ayıklama işlemi kolaylaşır.
Öncelikle, oluşturulan ödev dosyalarını depolamak için bir Cloud Storage paketi oluşturun ve hizmet hesabına pakete erişim izni verin. Terminalde aşağıdaki komutları çalıştırın:
👉ÖNEMLİ: "aidemy-assignment-" ile başlayan benzersiz bir ASSIGNMENT_BUCKET adı tanımladığınızdan emin olun. Bu benzersiz ad, Cloud Storage paketinizi oluştururken adlandırma çakışmalarını önlemek için çok önemlidir. (<YOUR_NAME> yerine rastgele bir kelime girin)
export ASSIGNMENT_BUCKET=aidemy-assignment-<YOUR_NAME> #Name must be unqiue
👉Ardından şu komutu çalıştırın:
export PROJECT_ID=$(gcloud config get project)
export SERVICE_ACCOUNT_NAME=$(gcloud compute project-info describe --format="value(defaultServiceAccount)")
gsutil mb -p $PROJECT_ID -l us-central1 gs://$ASSIGNMENT_BUCKET
gcloud storage buckets add-iam-policy-binding gs://$ASSIGNMENT_BUCKET \
--member "serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role "roles/storage.objectViewer"
gcloud storage buckets add-iam-policy-binding gs://$ASSIGNMENT_BUCKET \
--member "serviceAccount:$SERVICE_ACCOUNT_NAME" \
--role "roles/storage.objectCreator"
👉Ardından Cloud Run işlev emülatörünü başlatın:
cd ~/aidemy-bootstrap/assignment
functions-framework --target generate_assignment --signature-type=cloudevent --source main.py
👉Emülatör bir terminalde çalışırken Cloud Shell'de ikinci bir terminal açın. Bu ikinci terminalde, yeni bir öğretim planının yayınlanmasını simüle etmek için emülatöre bir test CloudEvent'i gönderin:
curl -X POST \
http://localhost:8080/ \
-H "Content-Type: application/json" \
-H "ce-id: event-id-01" \
-H "ce-source: planner-agent" \
-H "ce-specversion: 1.0" \
-H "ce-type: google.cloud.pubsub.topic.v1.messagePublished" \
-d '{
"message": {
"data": "eyJ0ZWFjaGluZ19wbGFuIjogIldlZWsgMTogMkQgU2hhcGVzIGFuZCBBbmdsZXMgLSBEYXkgMTogUmV2aWV3IG9mIGJhc2ljIDJEIHNoYXBlcyAoc3F1YXJlcywgcmVjdGFuZ2xlcywgdHJpYW5nbGVzLCBjaXJjbGVzKS4gRGF5IDI6IEV4cGxvcmluZyBkaWZmZXJlbnQgdHlwZXMgb2YgdHJpYW5nbGVzIChlcXVpbGF0ZXJhbCwgaXNvc2NlbGVzLCBzY2FsZW5lLCByaWdodC1hbmdsZWQpLiBEYXkgMzogRXhwbG9yaW5nIHF1YWRyaWxhdGVyYWxzIChzcXVhcmUsIHJlY3RhbmdsZSwgcGFyYWxsZWxvZ3JhbSwgcmhvbWJ1cywgdHJhcGV6aXVtKS4gRGF5IDQ6IEludHJvZHVjdGlvbiB0byBhbmdsZXM6IHJpZ2h0IGFuZ2xlcywgYWN1dGUgYW5nbGVzLCBhbmQgb2J0dXNlIGFuZ2xlcy4gRGF5IDU6IE1lYXN1cmluZyBhbmdsZXMgdXNpbmcgYSBwcm90cmFjdG9yLiBXZWVrIDI6IDNEIFNoYXBlcyBhbmQgU3ltbWV0cnkgLSBEYXkgNjogSW50cm9kdWN0aW9uIHRvIDNEIHNoYXBlczogY3ViZXMsIGN1Ym9pZHMsIHNwaGVyZXMsIGN5bGluZGVycywgY29uZXMsIGFuZCBweXJhbWlkcy4gRGF5IDc6IERlc2NyaWJpbmcgM0Qgc2hhcGVzIHVzaW5nIGZhY2VzLCBlZGdlcywgYW5kIHZlcnRpY2VzLiBEYXkgODogUmVsYXRpbmcgMkQgc2hhcGVzIHRvIDNEIHNoYXBlcy4gRGF5IDk6IElkZW50aWZ5aW5nIGxpbmVzIG9mIHN5bW1ldHJ5IGluIDJEIHNoYXBlcy4gRGF5IDEwOiBDb21wbGV0aW5nIHN5bW1ldHJpY2FsIGZpZ3VyZXMuIFdlZWsgMzogUG9zaXRpb24sIERpcmVjdGlvbiwgYW5kIFByb2JsZW0gU29sdmluZyAtIERheSAxMTogRGVzY3JpYmluZyBwb3NpdGlvbiB1c2luZyBjb29yZGluYXRlcyBpbiB0aGUgZmlyc3QgcXVhZHJhbnQuIERheSAxMjogUGxvdHRpbmcgY29vcmRpbmF0ZXMgdG8gZHJhdyBzaGFwZXMuIERheSAxMzogVW5kZXJzdGFuZGluZyB0cmFuc2xhdGlvbiAoc2xpZGluZyBhIHNoYXBlKS4gRGF5IDE0OiBVbmRlcnN0YW5kaW5nIHJlZmxlY3Rpb24gKGZsaXBwaW5nIGEgc2hhcGUpLiBEYXkgMTU6IFByb2JsZW0tc29sdmluZyBhY3Rpdml0aWVzIGludm9sdmluZyBwZXJpbWV0ZXIsIGFyZWEsIGFuZCBtaXNzaW5nIGFuZ2xlcy4ifQ=="
}
}'
Yanıtı beklerken ekrana boş boş bakmak yerine diğer Cloud Shell terminaline geçin. İşlemcinin terminalinde, ilerleme durumunu ve işleviniz tarafından oluşturulan çıkış veya hata mesajlarını gözlemleyebilirsiniz. 😁
OK (Tamam) yanıtı döndürülür.
Ödevin başarıyla oluşturulup depolandığını onaylamak için Google Cloud Console'a gidip Depolama > "Cloud Storage"a gidin. Oluşturduğunuz aidemy-assignment
paketini seçin. Pakette assignment-{random number}.txt
adlı bir metin dosyası görürsünüz. Dosyayı indirip içeriğini doğrulamak için tıklayın. Bu işlem, yeni bir dosyanın yeni oluşturulan yeni atamayı içerdiğini doğrular.
👉Emülatörü çalıştıran terminalde çıkmak için ctrl+c
yazın. İkinci terminali kapatın. 👉Ayrıca, emülatörü çalıştıran terminalde sanal ortamdan çıkın.
deactivate
👉Ardından, atama aracısını buluta dağıtacağız
cd ~/aidemy-bootstrap/assignment
export ASSIGNMENT_BUCKET=$(gcloud storage buckets list --format="value(name)" | grep aidemy-assignment)
export OLLAMA_HOST=http://$(gcloud compute instances describe ollama-instance --zone=us-central1-a --format='value(networkInterfaces[0].accessConfigs[0].natIP)'):11434
export PROJECT_ID=$(gcloud config get project)
gcloud functions deploy assignment-agent \
--gen2 \
--timeout=540 \
--memory=2Gi \
--cpu=1 \
--set-env-vars="ASSIGNMENT_BUCKET=${ASSIGNMENT_BUCKET}" \
--set-env-vars=GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT} \
--set-env-vars=OLLAMA_HOST=${OLLAMA_HOST} \
--region=us-central1 \
--runtime=python312 \
--source=. \
--entry-point=generate_assignment \
--trigger-topic=plan
Google Cloud Console'a gidip Cloud Run'a giderek dağıtımı doğrulayın.Listelenen courses-agent adlı yeni bir hizmet görürsünüz.
Ödev oluşturma iş akışı uygulanıp test edilip kullanıma sunulduğuna göre bir sonraki adıma geçebiliriz: Bu ödevleri öğrenci portalında erişilebilir hale getirmek.
14. İSTEĞE BAĞLI: Gemini ve DeepSeek ile rol tabanlı ortak çalışma - Devam.
Dinamik web sitesi oluşturma
Öğrenci portalını geliştirmek ve daha ilgi çekici hale getirmek için ödev sayfaları için dinamik HTML oluşturma özelliğini uygulayacağız. Amaç, yeni bir ödev oluşturulduğunda portalı yeni ve görsel açıdan ilgi çekici bir tasarımla otomatik olarak güncellemektir. Bu sayede, daha dinamik ve ilgi çekici bir kullanıcı deneyimi oluşturmak için LLM'nin kodlama özelliklerinden yararlanılır.
👉Cloud Shell Düzenleyici'de, portal
klasöründeki render.py
dosyasını düzenleyin,
def render_assignment_page():
return ""
aşağıdaki kod snippet'iyle:
def render_assignment_page(assignment: str):
try:
region=get_next_region()
llm = VertexAI(model_name="gemini-2.0-flash-001", location=region)
input_msg = HumanMessage(content=[f"Here the assignment {assignment}"])
prompt_template = ChatPromptTemplate.from_messages(
[
SystemMessage(
content=(
"""
As a frontend developer, create HTML to display a student assignment with a creative look and feel. Include the following navigation bar at the top:
```
<nav>
<a href="/">Home</a>
<a href="/quiz">Quizzes</a>
<a href="/courses">Courses</a>
<a href="/assignment">Assignments</a>
</nav>
```
Also include these links in the <head> section:
```
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
```
Do not apply inline styles to the navigation bar.
The HTML should display the full assignment content. In its CSS, be creative with the rainbow colors and aesthetic.
Make it creative and pretty
The assignment content should be well-structured and easy to read.
respond with JUST the html file
"""
)
),
input_msg,
]
)
prompt = prompt_template.format()
response = llm.invoke(prompt)
response = response.replace("```html", "")
response = response.replace("```", "")
with open("templates/assignment.html", "w") as f:
f.write(response)
print(f"response: {response}")
return response
except Exception as e:
print(f"Error sending message to chatbot: {e}") # Log this error too!
return f"Unable to process your request at this time. Due to the following reason: {str(e)}"
Ödev için HTML'yi dinamik olarak oluşturmak üzere Gemini modelini kullanır. Ödev içeriğini giriş olarak alır ve Gemini'ye, yaratıcı bir tarza sahip görsel açıdan ilgi çekici bir HTML sayfası oluşturması için talimat vermek üzere bir istem kullanır.
Ardından, ödev grubuna yeni bir doküman eklendiğinde tetiklenecek bir uç nokta oluşturacağız:
👉Portal klasöründe app.py
dosyasını düzenleyin ve ## Add your code here" comments
işlevinin SONRASINA, new_teaching_plan
işlevinin İÇERİSİNE aşağıdaki kodu ekleyin:
## Add your code here
@app.route('/render_assignment', methods=['POST'])
def render_assignment():
try:
data = request.get_json()
file_name = data.get('name')
bucket_name = data.get('bucket')
if not file_name or not bucket_name:
return jsonify({'error': 'Missing file name or bucket name'}), 400
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(file_name)
content = blob.download_as_text()
print(f"File content: {content}")
render_assignment_page(content)
return jsonify({'message': 'Assignment rendered successfully'})
except Exception as e:
print(f"Error processing file: {e}")
return jsonify({'error': 'Error processing file'}), 500
## Add your code here
Tetiklendiğinde, istek verilerinden dosya adını ve paket adını alır, ödev içeriğini Cloud Storage'dan indirir ve HTML oluşturmak için render_assignment_page
işlevini çağırır.
👉Şimdi kodu yerel olarak çalıştıracağız:
cd ~/aidemy-bootstrap/portal
source env/bin/activate
python app.py
👉Cloud Shell penceresinin üst kısmındaki "Web önizlemesi" menüsünden "8080 bağlantı noktasında önizle"yi seçin. Bu işlem, uygulamanızı yeni bir tarayıcı sekmesinde açar. Gezinme çubuğundaki Atama bağlantısına gidin. Bu noktada boş bir sayfa görürsünüz. İçeriği dinamik olarak doldurmak için henüz atama aracısı ile portal arasında iletişim köprüsü oluşturmadığımızdan bu beklenen bir davranıştır.
👉Bu değişiklikleri dahil etmek ve güncellenmiş kodu dağıtmak için portal aracısı resmini yeniden oluşturup yayınlayın:
cd ~/aidemy-bootstrap/portal/
export PROJECT_ID=$(gcloud config get project)
docker build -t gcr.io/${PROJECT_ID}/aidemy-portal .
export PROJECT_ID=$(gcloud config get project)
docker tag gcr.io/${PROJECT_ID}/aidemy-portal us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-portal
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/agent-repository/aidemy-portal
👉Yeni görüntüyü gönderdikten sonra Cloud Run hizmetini yeniden dağıtın. Cloud Run güncellemesini zorunlu kılmak için aşağıdaki komut dosyasını çalıştırın:
export PROJECT_ID=$(gcloud config get project)
export COURSE_BUCKET_NAME=$(gcloud storage buckets list --format="value(name)" | grep aidemy-recap)
gcloud run services update aidemy-portal \
--region=us-central1 \
--set-env-vars=GOOGLE_CLOUD_PROJECT=${PROJECT_ID},COURSE_BUCKET_NAME=$COURSE_BUCKET_NAME
👉Şimdi, atama paketinde oluşturulan (tamamlanan) tüm yeni nesneleri dinleyen bir Eventarc tetikleyici dağıtacağız. Bu tetikleyici, yeni bir ödev dosyası oluşturulduğunda portal hizmetinde /render_assignment uç noktasını otomatik olarak çağırır.
export PROJECT_ID=$(gcloud config get project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$(gcloud storage service-agent --project $PROJECT_ID)" \
--role="roles/pubsub.publisher"
export SERVICE_ACCOUNT_NAME=$(gcloud compute project-info describe --format="value(defaultServiceAccount)")
gcloud eventarc triggers create portal-assignment-trigger \
--location=us-central1 \
--service-account=$SERVICE_ACCOUNT_NAME \
--destination-run-service=aidemy-portal \
--destination-run-region=us-central1 \
--destination-run-path="/render_assignment" \
--event-filters="bucket=$ASSIGNMENT_BUCKET" \
--event-filters="type=google.cloud.storage.object.v1.finalized"
Tetikleyicinin başarıyla oluşturulduğunu doğrulamak için Google Cloud Console'daki Eventarc Tetikleyicileri sayfasına gidin. Tabloda portal-assignment-trigger
değerini göreceksiniz. Ayrıntılarını görüntülemek için tetikleyicinin adını tıklayın.
Yeni tetikleyicinin etkinleşmesi 2-3 dakika sürebilir.
Dinamik atama oluşturma işlemini çalışırken görmek için planlayıcı temsilcinizin URL'sini bulmak üzere aşağıdaki komutu çalıştırın (elinizde yoksa):
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep planner
Portal temsilcinizin URL'sini bulun:
gcloud run services list --platform=managed --region=us-central1 --format='value(URL)' | grep portal
Planlayıcı aracısında yeni bir öğretim planı oluşturun.
Birkaç dakika sonra (ses oluşturma, ödev oluşturma ve HTML oluşturma işlemlerinin tamamlanması için) öğrenci portalına gidin.
👉Gezinme çubuğundaki "Ödev" bağlantısını tıklayın. Dinamik olarak oluşturulmuş bir HTML içeren yeni oluşturulmuş bir ödev görürsünüz. Her öğretim planı oluşturulduğunda dinamik bir ödev olmalıdır.
Aidemy çoklu ajans sistemini tamamladığınız için tebrikler. Aşağıdaki konularda pratik deneyim ve değerli bilgiler edindiniz:
- Modülerlik, ölçeklenebilirlik, uzmanlaşma ve basitleştirilmiş bakım dahil olmak üzere çok aracılı sistemlerin avantajları.
- Duyarlı ve gevşek bağlı uygulamalar oluşturmak için etkinlik odaklı mimarilerin önemi.
- LLM'lerin stratejik kullanımı, doğru modeli görevle eşleştirme ve gerçek dünyadaki etki için araçlarla entegrasyon.
- Ölçeklenebilir ve güvenilir çözümler oluşturmak için Google Cloud hizmetlerini kullanan bulutta yerel geliştirme uygulamaları.
- Sağlayıcı çözümlerine alternatif olarak veri gizliliği ve kendi kendine barındırma modellerini değerlendirmenin önemi.
Artık Google Cloud'da yapay zeka destekli karmaşık uygulamalar oluşturmak için sağlam bir temele sahipsiniz.
15. Zorluklar ve Sonraki Adımlar
Aidemy çoklu ajans sistemini oluşturduğunuz için tebrikler. Yapay zeka destekli eğitim için güçlü bir temel oluşturdunuz. Şimdi, bu özelliğin yeteneklerini daha da genişletmek ve gerçek dünyadaki ihtiyaçları karşılamak için bazı zorluklardan ve gelecekte yapılabilecek olası iyileştirmelerden bahsedelim:
Canlı soru-cevap ile etkileşimli öğrenme:
- Zorluk: Öğrenciler için gerçek zamanlı bir soru-cevap özelliği oluşturmak üzere Gemini 2'nin Live API'sinden yararlanabilir misiniz? Öğrencilerin soru sorabileceği ve anında yapay zeka destekli yanıtlar alabileceği bir sanal sınıf düşünün.
Otomatik Ödev Gönderme ve Notlandırma:
- Zorluk: Öğrencilerin ödevlerini dijital olarak göndermesine ve ödevlerin yapay zeka tarafından otomatik olarak notlandırılmasına olanak tanıyan, intihali tespit edip önleyen bir mekanizma içeren bir sistem tasarlayın ve uygulayın. Bu yarışma, notlandırma ve intihal tespiti süreçlerinin doğruluğunu ve güvenilirliğini artırmak için Almayla Artırılmış Üretim (RAG)'i keşfetme konusunda mükemmel bir fırsat sunuyor.
16. Temizleme
Aidemy çoklu aracı sistemimizi oluşturup keşfettikten sonra Google Cloud ortamımızı temizlemenin zamanı geldi.
- Cloud Run hizmetlerini silme
gcloud run services delete aidemy-planner --region=us-central1 --quiet
gcloud run services delete aidemy-portal --region=us-central1 --quiet
gcloud run services delete courses-agent --region=us-central1 --quiet
gcloud run services delete book-provider --region=us-central1 --quiet
gcloud run services delete assignment-agent --region=us-central1 --quiet
- Eventarc tetikleyicisini silme
gcloud eventarc triggers delete portal-assignment-trigger --location=us --quiet
gcloud eventarc triggers delete plan-topic-trigger --location=us-central1 --quiet
gcloud eventarc triggers delete portal-assignment-trigger --location=us-central1 --quiet
ASSIGNMENT_AGENT_TRIGGER=$(gcloud eventarc triggers list --project="$PROJECT_ID" --location=us-central1 --filter="name:assignment-agent" --format="value(name)")
COURSES_AGENT_TRIGGER=$(gcloud eventarc triggers list --project="$PROJECT_ID" --location=us-central1 --filter="name:courses-agent" --format="value(name)")
gcloud eventarc triggers delete $ASSIGNMENT_AGENT_TRIGGER --location=us-central1 --quiet
gcloud eventarc triggers delete $COURSES_AGENT_TRIGGER --location=us-central1 --quiet
- Pub/Sub konusu silin
gcloud pubsub topics delete plan --project="$PROJECT_ID" --quiet
- Cloud SQL örneğini silme
gcloud sql instances delete aidemy --quiet
- Artifact Registry deposunu silme
gcloud artifacts repositories delete agent-repository --location=us-central1 --quiet
- Secret Manager gizli anahtarlarını silme
gcloud secrets delete db-user --quiet
gcloud secrets delete db-pass --quiet
gcloud secrets delete db-name --quiet
- Compute Engine örneğini silin (Deepseek için oluşturulduysa)
gcloud compute instances delete ollama-instance --zone=us-central1-a --quiet
- Deepseek örneği için güvenlik duvarı kuralını silme
gcloud compute firewall-rules delete allow-ollama-11434 --quiet
- Cloud Storage paketlerini silme
export COURSE_BUCKET_NAME=$(gcloud storage buckets list --format="value(name)" | grep aidemy-recap)
export ASSIGNMENT_BUCKET=$(gcloud storage buckets list --format="value(name)" | grep aidemy-assignment)
gsutil rb gs://$COURSE_BUCKET_NAME
gsutil rb gs://$ASSIGNMENT_BUCKET