Ana içeriğe geç

Google Workspace CLI: Drive Dosyalarınız Üzerinde Bir RAG Asistanı Oluşturun

Google’ın yeni yapay zekâ odaklı CLI’sini nasıl kuracağınızı, kimlik doğrulaması yapacağınızı ve kendi Drive dosyalarınız hakkında soruları yanıtlayan Gemini destekli bir RAG hattına nasıl bağlayacağınızı öğrenin.
· 12 dk. oku

Yapay Zeka ile Keşfedin

Google geliştiriciler için gerçekten ilginç bir şey yayınladı. Tüm Google Workspace’inize (Drive, Gmail, Takvim, Sheets, Docs, Chat ve daha fazlası) tek bir araçla yapılandırılmış, betiklenebilir erişim sağlayan bir Google Workspace komut satırı arayüzü .

Kod tabanı neredeyse tamamen Rust (%99,3), ancak yerel önceden derlenmiş ikili dosyalar olarak npm üzerinden dağıtılıyor; dolayısıyla Rust araç zincirine ihtiyacınız yok.

Bu eğitimde Google Workspace CLI’yi sıfırdan kuracak, kimlik doğrulaması yapacak ve Drive dosyalarınızı doğal dille sorgulamanıza olanak tanıyan Gemini destekli bir RAG asistanı oluşturacaksınız. Sonunda şu noktalara ulaşmış olacaksınız:

  • gws yüklü ve Drive’ınıza karşı kimlik doğrulanmış

  • ChromaDB, Sentence Transformers ve Gemini SDK içeren bir Python sanal ortamı

  • gws ile dosyaları alan, yerel bir modelle gömümler oluşturan ve yanıtları Gemini 2.5 Flash ile akış halinde veren çalışan bir yerel RAG hattı

Not: Bu resmi olarak desteklenen bir Google ürünü değildir.

Google Workspace CLI Nedir?

Google Workspace CLI (gws), tüm Google Workspace ekosistemi için yapay zekâ odaklı bir komut satırı aracıdır. Öne çıkan yönleri şunlardır:

  • Dinamik komut keşfi: Sabit kodlanmış bir komut ağacı göndermek yerine, gws çalışma zamanında Google’ın Discovery Service’ini okur. Google yeni API uç noktaları eklediğinde, CLI sürüm artışı olmadan bunları otomatik olarak alır.

  • Ajan-yerel tasarım: CLI, e-postaları özetleyen, Drive dosyalarını taşıyan, takvim etkinlikleri oluşturan ve daha fazlasını yapan yaygın iş akışları için 100+ önceden oluşturulmuş ajan becerisi ve 50 seçilmiş tarife ile gelir. Her çıktı yapılandırılmış JSON’dur, bu nedenle LLM’ler doğrudan tüketebilir.

  • Yerel MCP sunucu desteği: gws’yi yerel bir MCP sunucusu olarak çalıştırın ve tek bir API istemcisi yazmadan yapay zekâ ajanınıza tam Workspace araç erişimi verin.

  • Model Armor entegrasyonu: Kullanıcı kontrollü içeriği okuyan üretim ajanları için, API yanıtlarını LLM’iniz görmeden önce istem enjeksiyonuna karşı temizlemek üzere Google Cloud Model Armor’dan geçirebilirsiniz.

Tüm beceri kütüphanesine buradan göz atabilirsiniz: github.com/googleworkspace/cli/blob/main/docs/skills.md.

Eğitim: Google Workspace CLI ve Gemini ile Bir RAG Asistanı Oluşturun

Bu eğitimde, RAG asistanını adım adım oluşturacağız. Uygulamanın yüksek seviyede yaptığı işler şunlardır:

  • gws CLI’siyle Google Drive’ınıza karşı kimlik doğrulaması yapar ve en son değiştirilmiş Docs, Sheets ve metin dosyalarınızı alır

  • Her belgeyi parçalara böler ve ChromaDB aracılığıyla Sentence Transformers kullanarak yerelde gömüm oluşturur 

  • Vektör indeksini diske kalıcı olarak yazar; böylece sonraki çalıştırmalarda zaten içe alınan dosyalar atlanır ve doğrudan sohbete geçilir

  • Doğal dille bir soruyu kabul eder, ChromaDB’den en alakalı ilk 3 parçayı getirir ve temellendirilmiş bir bağlam istemi oluşturur

  • Terminalinizde, yalnızca bağlama dayalı ve kaynakça içeren bir yanıtı Gemini 2.5 Flash’tan jeton jeton akış halinde verir

Hadi bunu adım adım oluşturalım.

Tam eğitim kodu: https://github.com/AashiDutt/Google-Workspace-CLI-Demo

Adım 1: CLI’yi yükleyin 

CLI, önceden derlenmiş Rust ikililerini saran bir npm paketi olarak dağıtılır. Rust araç zinciri gerekmez.

npm install -g @googleworkspace/cli

Kurulumu, aşağıdaki komutları tek tek çalıştırarak doğrulayın:

gws --version
which gws

Yüklemeden sonra gws bulunamazsa, npm global bin dizininizin PATH’inizde olduğundan emin olun.

Adım 2: Google Cloud’da bir proje oluşturun

CLI, bir GCP projesinin OAuth istemcisi üzerinden kimlik doğrular; bu nedenle giriş yapmadan önce bir projeye ihtiyacınız var. GCP’de bir proje oluşturmak veya seçmek için:

  • console.cloud.google.com adresine gidin
  • Proje açılır menüsüne tıklayın ve Yeni Proje’yi seçin
  • Bir ad verin ve bir sonraki adımda kullanacağımız otomatik oluşturulan Proje Kimliği’ni not edin

OAuth kimlik bilgilerini ayarlayın: 

  • API’ler ve Hizmetler’e gidin ve Kimlik Bilgileri’ni seçin

  • Kimlik Bilgileri Oluştur’a tıklayın ve OAuth 2.0 İstemci Kimliği’ne gidin

  • Uygulama türü olarak Masaüstü uygulaması’nı seçin

  • gws auth setup için kullanacağımız İstemci Kimliği ve İstemci Sırrı’nı not edin.

CLI, OAuth’u geçici bir localhost sunucusu başlatarak tamamlar. Masaüstü uygulaması istemcileri, rastgele localhost portlarını otomatik olarak işler. Web uygulaması istemcileri için ise her http://localhost:PORT değerini yetkili yönlendirme URI’leri listesine manuel olarak eklemeniz gerekir. 

Bir Web uygulaması istemcisi kullanıyorsanız ve "Erişim engellendi: Bu uygulamanın isteği geçersiz" hatasını alırsanız, Kimlik Bilgileri’ne gidin, ardından OAuth istemcisine ve Yetkili yönlendirme URI’lerine tıklayın ve hatada gösterilen tam http://localhost:PORT URL’sini ekleyin.

Adım 3: Kimlik doğrulama

gws’yi GCP projenize bağlamak için önce OAuth kimlik bilgilerinizi ortam değişkenleri olarak dışa aktarın; böylece kurulum sihirbazı bunları otomatik olarak algılayabilsin:

export GOOGLE_WORKSPACE_CLI_CLIENT_ID="CLIENT_ID"
export GOOGLE_WORKSPACE_CLI_CLIENT_SECRET="CLIENT_SECRET"

Ardından şunu çalıştırın:

gws auth setup --project YOUR_PROJECT_ID --login

Authenticate

Kurulum sihirbazı şunları yapacaktır:

  • Hangi Google hesabını kullanmak istediğinizi sorar
  • Standart Google OAuth onay akışı için bir tarayıcı açar
  • Hangi kapsamların (Drive, Gmail, Takvim vb.) yetkilendirileceğini sorar

Tamamlandığında şunu göreceksiniz: Kurulum tamamlandı!

gcloud CLI

Kimlik bilgileriniz ~/.config/gws/ konumunda saklanır. Her şeyin doğru şekilde bağlandığını doğrulamak için şunu çalıştırın:

gws auth status

Bu, kimliği doğrulanmış hesabı, bağlı GCP projesini ve etkin kapsamları yazdırır. Bir şey yanlış görünüyorsa, yapılandırma dosyalarını manuel olarak düzenlemeye çalışmak yerine doğru bayraklarla gws auth setup’ı yeniden çalıştırın.

Adım 4: Drive erişimini test edin

Herhangi bir Python kodu yazmadan önce, CLI’nin kimlik doğrulandığını ve Drive’ınızla konuşabildiğini doğrudan terminalden hızlıca kontrol etmeye değer. En son beş Drive dosyanızı listelemek için şu komutu hızla çalıştıralım:

gws drive files list --params '{"pageSize": 5}'

--params bayrağı, Drive API’nin sorgu parametrelerine doğrudan eşlenen bir JSON dizesi kabul eder. Burada pageSize: 5, yanıtı beş sonuçla sınırlar; bu da tüm Drive’ınızı dökmeden bağlantıyı doğrulamak için yeterlidir.

Kimlik doğrulama doğru çalışıyorsa, aşağıdaki gibi yapılandırılmış bir JSON yanıtı alırsınız:

{
  "files": [
    {
      "id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
      "name": "Q3 Strategy Doc",
      "mimeType": "application/vnd.google-apps.document"
    },
    ...
  ]
}

gws’den gelen her yanıt, ayrıştırma yok, kazıma yok, kırılgan metin çıktısı yok; yapılandırılmış bir JSON’dur. 

Bunun yerine serviceusage.services.use belirten bir “403 hatası” görürseniz, OAuth kimlik bilgileriniz faturalandırmanın etkin olduğu projeden farklı bir GCP projesine işaret ediyor demektir. Her şeyi yeniden bağlamak için doğru proje kimliğiyle kurulumu tekrar çalıştırın:

gws auth setup --project YOUR_PROJECT_ID --login

Drive erişimi doğrulandıysa, API’yi etkinleştirmeye ve hattın Python tarafını oluşturmaya hazırız.

Adım 5: Google Drive API’yi etkinleştirin

Bu noktada, gws GCP projenize karşı kimlik doğrulayabilir, ancak henüz Drive dosya içeriğini okuyamaz. GCP, kimlik doğrulamayı (kimsiniz) API etkinleştirmeden (projenizin hangi hizmetleri kullandığı) ayırır. Geçerli OAuth kimlik bilgileriyle bile, dosya içeriği alma girişimleri, Drive API proje üzerinde açıkça etkinleştirilene kadar 403 accessNotConfigured hatası döndürür.

Bunu etkinleştirmek için, bu URL’yi bir tarayıcıda açın, [PROJECT_ID] yerine gerçek proje kimliğinizi yazın ve Etkinleştir’e tıklayın:

https://console.developers.google.com/apis/api/drive.googleapis.com/overview?project=[PROJECT_ID]

Alternatif olarak, gcloud CLI yüklüyse, bunu doğrudan terminalden etkinleştirebilirsiniz:

gcloud services enable drive.googleapis.com --project YOUR_PROJECT_ID

Her iki yöntem de aynı şeyi yapar. Zaten etkinleştirilmiş bir API üzerinde çalıştırmak güvenlidir; işlem idempotenttir ve mevcut herhangi bir yapılandırmayı sıfırlamaz.

Google Drive API Enable

Etkinleştirildikten sonra, GCP değişikliği yaymak için birkaç saniye alabilir. Hemen gws drive files list çalıştırır ve hâlâ 403 görürseniz, 30 saniye bekleyin ve tekrar deneyin. 

Adım 6: Bağımlılıkları yükleyin

CLI tarafı tamamen yapılandırıldığında, şimdi gömme ve getirme mantığını yöneten Python ortamını kurabiliriz. RAG hattı, kasıtlı olarak dört paketle hafif tutulmuştur; GPU gerekmez ve tüm gömme işlemleri makinenizde yerel olarak gerçekleşir.

Aşağıdaki komutları tek tek çalıştırarak bir sanal ortam oluşturarak başlayın:

cd /path/to/your/project
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt

Ardından bağımlılıkları requirements.txt’ten yükleyin:

.txt
chromadb==1.5.5
google-genai==1.70.0
langchain-text-splitters==1.1.1
sentence-transformers==5.3.0

Her paketin hatta sağladıkları şunlardır:

  • chromadb: Bu, belge gömmelerini diskte ./chroma_db konumunda saklayan ve sonraki çalıştırmalarda yükleyen yerel vektör veritabanıdır; böylece uygulama daha önce işlediği dosyaları yeniden gömmek zorunda kalmaz.

  • google-genai: Bu, Gemini için resmi bir Python SDK’sıdır. Uygulama, getirilen bağlamı ve kullanıcı sorusunu Gemini 2.5 Flash’a göndermek ve yanıtı jeton jeton akışla almak için bunu kullanır.

  • langchain-text-splitters: Bu paket, gömme işleminden önce büyük belgeleri örtüşen parçalara bölen RecursiveCharacterTextSplitter’ı sağlar. Örtüşme, parça sınırlarındaki cümlelerin bağlamlarından kopmamasını sağlar.

  • sentence-transformers: Sentence Transformers, ChromaDB’nin DefaultEmbeddingFunction’ı aracılığıyla gömme modelini yerelde çalıştırır. Böylece her belge parçası, harici API çağrısı olmadan makinenizde gömülür.

Not: Gömme modeli (~90 MB) ilk kullanımda otomatik olarak indirilir ve yerelde önbelleğe alınır. 

Python ortamı hazır olduğunda, kod yazmadan önceki son parça Gemini API anahtarınızı almaktır.

Adım 7: Gemini API Anahtarını ayarlayın

RAG hattı, getirilen belge parçalarını ve kullanıcının sorusunu alıp temellendirilmiş bir yanıtı akış halinde döndürdüğü için yanıt üretim katmanı olarak Gemini’yı kullanır. Gemini’ya bağlanmak için Google AI Studio’dan bir API anahtarına ihtiyacınız var.

Google hesabınızla oturum açın ve API Anahtarı Al’a tıklayın, ardından API Anahtarı Oluştur’u seçin. İstendiğinde kota ve faturalandırma için GCP projenizi seçin. GCP panosunda Faturalandırma altında bir faturalandırma hesabı bağlayın, ardından Bir faturalandırma hesabı bağla’yı seçin. 

Anahtarınızı aldıktan sonra, onu bir ortam değişkeni olarak dışa aktarın:

API Billing

Anahtarı terminalinizde dışa aktarın:

export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"

Terminal oturumları arasında kalıcı kılmak için şunu çalıştırın:

echo 'export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"' >> ~/.zshrc
source ~/.zshrc

Uygulama bu anahtarı başlangıçta os.getenv("GEMINI_API_KEY") üzerinden okur. Değişken ayarlı değilse, anahtarı etkileşimli olarak yapıştırmanız istenir.

Model notu: Uygulama varsayılan olarak gemini-2.5-flash kullanır. Karmaşık belgelerde daha güçlü muhakeme için bunu GEMINI_MODEL="gemini-2.5-pro" dışa aktararak geçersiz kılabilirsiniz. gemini-2.0-flash yeni API anahtarları için kullanımdan kaldırılmıştır; burada kullanmayın.

Kimlik doğrulama, Drive API, bağımlılıklar ve Gemini anahtarıyla her şey hazır. Hattı oluşturalım.

Adım 8: RAG Hattını oluşturun

Şimdi her şeyi birbirine bağlayalım. Dört dosya ile çalışacağız: fetcher.py, vector_store.py, main.py ve requirements.txt. Her dosyanın tek bir sorumluluğu var: fetcher.py tüm CLI etkileşimini yönetir, vector_store.py gömme ve getirmeden sorumludur ve main.py içe aktarmadan akış sohbetine kadar tam döngüyü orkestre eder.

İlk çalıştırmada, gws Drive dosyalarınızı getirir, içerik parçalara bölünür ve yerelde gömülür, vektör indeksi diskte ./chroma_db konumuna yazılır. Sonraki çalıştırmalarda ChromaDB diskten yüklenir, yalnızca yeni dosyalar alınır ve gömülür ve sohbet döngüsü hiçbir şeyi yeniden işlemeye gerek kalmadan hemen başlar.

Her dosyayı adım adım inceleyelim.

Adım 8.1: fetcher.py — gws ile Drive erişimi

Bu modül, gws CLI ile Python arasında köprü görevi görür. Dosyaları listelemek, içerik dışa aktarmak ve kimlik doğrulamayı kontrol etmek gibi tüm Drive etkileşimleri gws’ye yapılan alt süreç çağrıları üzerinden yürür ve yapılandırılmış JSON çıktısı Python sözlüklerine ayrıştırılır. Sonuç olarak Python kodu OAuth belirteçleri, HTTP istemcileri veya API yanıt şemalarıyla doğrudan uğraşmak zorunda kalmaz; gws bunların hepsini halleder ve temiz JSON döndürür.

def _gws_json_stdout(stdout: str) -> str:
    if not stdout or "{" not in stdout:
        return stdout or ""
    return stdout[stdout.find("{"):]

_gws_json_stdout yardımcı işlevi, gws’nin bazen JSON yükünden önce anahtar zinciri veya günlük satırları yayması sorununu ele alır. Burada doğrudan json.loads(result.stdout) çağırmak başarısız olurdu; bu yardımcı işlev, ilk { karakterinden öncesini kırpar.

def check_auth() -> bool:
    cmd = ["gws", "drive", "about", "get", "--params", '{"fields": "user"}']
    result = subprocess.run(cmd, capture_output=True, text=True)
    payload = _gws_json_stdout(result.stdout)
    try:
        data = json.loads(payload) if payload.strip() else {}
    except json.JSONDecodeError:
        print("Error checking authentication status (could not parse gws output).")
        return False
    if "error" in data or result.returncode != 0:
        handle_error_output(result.stdout, result.stderr)
        return False
    return True

check_auth() işlevi, main.py içinde başlangıçta çağrılır; hafif bir Drive API çağrısı yapar ve yanıtı denetler. Kimlik doğrulama bozuksa veya kapsamlar eksikse, uygulama içe almaya kalkışmadan temiz şekilde çıkar.

Hata işleyici ayrıca belirli arıza durumlarını yakalar ve uygulanabilir iletiler yazdırır:

def handle_error_output(stdout, stderr):
    output = _gws_json_stdout(stdout or "") or (stderr or "")
    if "insufficientPermissions" in output or "unauthenticated" in output.lower():
        print("Please run: gws auth login -s drive")
    elif "serviceusage.services.use" in output or "serviceUsageConsumer" in output:
        print(
            "GCP quota project error: run gws auth setup --project YOUR_PROJECT_ID --login"
        )
    else:
        print(f"API Error: {output}")

Belge listeleyici yalnızca metin olarak dışa aktarılabilir MIME türlerini hedefler:

def fetch_document_list(limit=10) -> list[dict]:
    q = (
        "(mimeType='text/plain' or mimeType='application/vnd.google-apps.document' "
        "or mimeType='application/vnd.google-apps.spreadsheet') and trashed=false"
    )
    cmd = [
        "gws", "drive", "files", "list",
        "--params",
        json.dumps({"q": q, "pageSize": limit, "orderBy": "modifiedTime desc"}),
    ]

Sorgu, en son değiştirilene göre sıralanmış düz metin, Google Docs ve Google Sheets’i filtreler. Bu yaklaşım ile metin olarak temiz şekilde dışa aktarılamayan ikili dosyalar (PDF’ler, görseller) hariç tutulur.

Ancak indirme MIME türüne göre farklı şekilde ele alınır:

def download_document(file_id: str, mime_type: str) -> str:
    fd, out_path = tempfile.mkstemp(prefix="gws_", suffix=".bin")
    os.close(fd)
    try:
        if mime_type == "application/vnd.google-apps.document":
            cmd = ["gws", "drive", "files", "export",
                   "--params", json.dumps({"fileId": file_id, "mimeType": "text/plain"}),
                   "-o", out_path]
        elif mime_type == "application/vnd.google-apps.spreadsheet":
            cmd = ["gws", "drive", "files", "export",
                   "--params", json.dumps({"fileId": file_id, "mimeType": "text/csv"}),
                   "-o", out_path]
        else:
            cmd = ["gws", "drive", "files", "get",
                   "--params", json.dumps({"fileId": file_id, "alt": "media"}),
                   "-o", out_path]
        ...
        with open(out_path, "rb") as f:
            return f.read().decode("utf-8", errors="replace")
    finally:
        os.unlink(out_path)

gws, dışa aktarılan dosya baytlarını stdout’a değil -o ile diske yazar. Stdout JSON meta verilerini taşır. Kod, ikili çıktıyı yakalamak için geçici bir dosya kullanır, onu okur ve bir finally bloğunda temizler; böylece hata olsa bile geçici dosyalar her zaman kaldırılır.

Adım 8.2: vector_store.py — ChromaDB ile yerel gömmeler

Bu modül, gelen metni parçalara böler, Sentence Transformers kullanarak yerelde gömmeler üretir, bunları ChromaDB aracılığıyla diske kalıcı kılar ve sohbet döngüsünün her kullanıcı sorusunda çağırdığı basit bir query() yöntemi sunar.

class VectorStore:
    def __init__(self, persist_directory="./chroma_db"):
        self.client = chromadb.PersistentClient(path=persist_directory)
        self.collection = self.client.get_or_create_collection(
            name="drive_documents",
            embedding_function=embedding_functions.DefaultEmbeddingFunction()
        )
        self.text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=1000,
            chunk_overlap=200
        )

PersistentClient, vektör indeksini ./chroma_db konumuna yazar ve dizini silmediğiniz sürece sonraki çalıştırmalarda yeniden içe almaya gerek kalmadan yükler. DefaultEmbeddingFunction yerelde Sentence Transformers kullanır; gömmeler makinenizde hesaplanır ve marjinal maliyeti yoktur.

Bölücü, chunk_size=1000 ve chunk_overlap=200 kullanır; böylece örtüşme, sınırdaki cümlelerin bağlamının kaybolmamasını sağlar.

def add_document(self, file_id: str, filename: str, text: str):
    chunks = self.text_splitter.split_text(text)
    ids = [f"{file_id}_{i}" for i in range(len(chunks))]
    metadatas = [{"source": filename, "file_id": file_id} for _ in chunks]
    self.collection.upsert(documents=chunks, metadatas=metadatas, ids=ids)
    print(f"-> Added {len(chunks)} chunks for {filename}")

upsert, yukarıdaki kod parçasında, zaten içe alınmış bir dosyada hattı yeniden çalıştırmanın, yinelenen kimlik hatası atmak yerine parçaları güncellediği anlamına gelir.

def document_exists(self, file_id: str) -> bool:
    try:
        results = self.collection.get(where={"file_id": file_id}, limit=1)
        return len(results["ids"]) > 0
    except Exception:
        return False

Bu hızlı ön kontrol, main.py’nin içe aktarma döngüsünde, zaten gömdüğünüz dosyaları yeniden indirmeyi önler; böylece sonraki çalıştırmalar anında olur.

Adım 8.3: main.py — İçe alma, getirme ve akış sohbeti

main.py dosyası kimlik doğrulama kontrollerini çalıştırır, içe aktarma döngüsünü yönetir, Gemini istemcisini başlatır ve etkileşimli sohbet döngüsünü yürütür. Ağır işler bilerek fetcher.py ve vector_store.py’ye devredildiği için kasıtlı olarak incedir.

def setup_gemini():
    api_key = os.getenv("GEMINI_API_KEY")
    if not api_key:
        print("Please enter your GEMINI_API_KEY (get one from Google AI Studio).")
        api_key = input("Key: ").strip()
    return genai.Client(api_key=api_key)

Eğer GEMINI_API_KEY ayarlı değilse, uygulama çökmez; etkileşimli olarak sizi yönlendirir. Önceki adımda yaptığımız gibi GEMINI_API_KEY’inizi ayarlayabilirsiniz.

def ingest_documents(store, limit=10):
    files = fetch_document_list(limit)
    for file in files:
        file_id = file.get("id")
        if store.document_exists(file_id):
            print(f"Skipping {file.get('name')} (already in vector store)...")
            continue
        content = download_document(file_id, file.get("mimeType"))
        if content:
            store.add_document(file_id, file.get("name"), content)

document_exists kontrolü, artımlı içe alma mekanizmasıdır; her çalıştırmada sadece yeni dosyalar indirilir ve gömülür. Sohbet döngüsü, anlamsal olarak en benzer ilk 3 parçayı getirir ve her birini kaynak dosya adıyla etiketler:

def chat_loop(model, store):
    while True:
        query = input("\nYou: ")
        results = store.query(query, n_results=3)
        documents = results.get("documents", [[]])[0]
        metadatas = results.get("metadatas", [[]])[0]
        context_parts = []
        for doc, meta in zip(documents, metadatas):
            source = meta.get("source", "Unknown")
            context_parts.append(f"Source: {source}\nText:\n{doc}\n")
        full_context = "\n---\n".join(context_parts)
        prompt = f"""You are a helpful assistant. Answer the user's question based ONLY on the following context from their Google Drive. If you cannot answer from the context, say \"I don't know based on your documents.\"\nContext:\n{full_context}\nQuestion: {query}\n"""
        model_name = os.getenv("GEMINI_MODEL", "gemini-2.5-flash")
        response = model.models.generate_content_stream(model=model_name, contents=prompt)
        for chunk in response:
            if chunk.text:
                print(chunk.text, end="", flush=True)
        print()

Yukarıdaki istem, LLM’in yalnızca sağlanan bağlama dayanarak yanıt vermesini ve yanıt bağlamda yoksa "I don't know based on your documents." demesini açıkça şart koşar. Bu, Drive’ınızda olmayan bilgilerin hayal edilmesini önler. Yanıtlar generate_content_stream aracılığıyla jeton jeton akışla gelir; böylece çıktı anında görünür.

Adım 9: Uygulamayı çalıştırma

Dört dosyanın hepsi yerindeyken uygulamayı şu şekilde başlatın:

python main.py

İlk çalıştırmada uygulama kimlik doğrulamasını kontrol eder, ChromaDB’yi başlatır, gömme modeli önbellekte yoksa indirir, en fazla 10 Drive dosyası alır, bunları gömer ve saklar, ardından kullanıcıyı sohbet döngüsüne alır. Her dosya içe alınırken aşamalı ilerleme çıktısı görürsünüz:

Running the App

Sonraki çalıştırmalarda, ChromaDB kalıcı dizini diskten yükler, daha önce içe alınmış dosyalar atlanır ve neredeyse anında sohbet istemine ulaşırsınız.

Ancak, örneğin dahil etmek istediğiniz yeni Drive dosyaları ekledikten sonra her şeyi sıfırdan yeniden içe almak için ChromaDB dizinini silip yeniden çalıştırmanız gerekir:

rm -rf ./chroma_db
python main.py

Tüm hattı çalıştırmadan bağımsız olarak kimlik doğrulamayı doğrulamak için fetcher.py’yi doğrudan çalıştırın:

python fetcher.py

Bu, check_auth()’ı yürütür ve CLI, OAuth ve Drive API’nin tam bir içe alma çalıştırmasına başlamadan önce çalıştığını doğrulamak için Drive dosyalarınızın bir listesini yazdırır.

Sonuç

Google Workspace CLI ile oluşturduğumuz RAG asistanı kasıtlı olarak minimaldir: gws getirir, Sentence Transformers yerelde gömer, ChromaDB saklar, Gemini yanıtı akışla verir. Dört dosya, sıfır bulut gömme maliyeti, her çalıştırmada artımlı içe alma. Mimarî, Gmail ve Takvim’i ek içe alma kaynakları olarak eklemek, daha büyük bir Gemini modeline geçmek veya sohbet döngüsünü bir LangGraph ajanıyla değiştirmek istediğinizde de temiz şekilde ölçeklenir. Temel aynı kalır.

Aashi Dutt

Yazar

Aashi Dutt

ML (Üretken Yapay Zekâ) alanında Google Developers Uzmanıyım, Kaggle 3x Expert unvanına sahibim ve 3+ yıllık teknoloji deneyimiyle Women Techmakers Elçisiyim. 2020'de bir sağlık teknolojileri girişiminin kurucu ortağı oldum ve Georgia Tech'te makine öğrenmesi alanında uzmanlaşarak bilgisayar bilimleri yüksek lisansı yapıyorum.

Google Workspace CLI SSS

gws’i kurmak için bir Rust araç zincirine ihtiyacım var mı?

Hayır. CLI, her işletim sistemi ve mimari için önceden derlenmiş ikililerle bir npm paketi olarak gelir. npm install -g @googleworkspace/cli tüm süreçtir.

Neden bir GCP projesine ihtiyacım var?

Google API’lerine geliştirici erişimi için OAuth istemci kimlik bilgilerini tutmak ve API kotasını izlemek üzere bir GCP projesi gerekir. Yapılandırmayı halletmek için gws auth setup komutunu çalıştırın, ancak proje önce GCP Konsolu’nda var olmalıdır.

403 serviceusage.services.use hatası alıyorum.

OAuth kimlik bilgileriniz, faturalandırma ve API erişimi etkin olan projeden farklı bir GCP projesine işaret ediyor. gws auth setup --project YOUR_PROJECT_ID komutunu yeniden çalıştırın.

Gmail veya Takvim’i belge kaynağı olarak nasıl eklerim?

Yapılandırılmış bir JSON döndürmek için gws gmail messages list ve gws calendar events list komutlarını çalıştırın. Her hizmet için fetcher.py içine yeni alma işlevleri ekleyin ve ingest_documents()’tan çağırın. 

Bunu bir Google Workspace kuruluş hesabıyla kullanabilir miyim?

Evet, ancak Workspace yöneticinizin OAuth uygulamasını onaylaması gerekebilir. Kimlik doğrulama akışı "Kuruluşunuz tarafından erişim engellendi" döndürürse, OAuth istemcisinin izin listesine alınması hakkında yöneticinizle görüşün.

Konular

İlgili