Ana içeriğe geç

Jan-V1: Demo Projeyle Kılavuz

Jan-v1'in aracısal akıl yürütme yeteneklerini kullanarak, yerel dağıtım, Streamlit uygulama geliştirme ve daha fazlasını içeren Derin Araştırma Asistanı oluşturmayı öğrenin.
· 12 dk. oku

Yapay Zeka ile Keşfedin

Jan ekibi kısa süre önce Jan-v1 adlı, gelişmiş araç kullanımı ve çok adımlı problem çözme yoluyla sofistike araştırma otomasyonu yetenekleri sunan ileri düzey bir aracısal akıl yürütme modelini yayınladı.

Bu eğitimde odak noktam Jan-v1'in benzersiz aracısal akıl yürütme yetenekleri olacak; llama.cpp tarafından desteklenen ve yerel olarak dağıtılan bir Streamlit arayüzü üzerinden nasıl karmaşık bir araştırma iş akışı gibi davrandığını göstereceğim.

Bu eğitimde şunları nasıl yapacağımı açıklayacağım:

  • En iyi performans ve gizlilik için GGUF quantization ile Jan-v1'i yerel olarak dağıtma
  • Gerçek zamanlı ilerleme takibiyle otomatik araştırma için bir Streamlit uygulaması oluşturma
  • Dinamik sorgu oluşturma ile akıllı web arama entegrasyonu uygulama
  • Biçime özgü çıktı yapılandırmasıyla profesyonel bir rapor sentezi oluşturma
  • Temiz, iş dünyasına hazır dokümantasyon sağlamak için gelişmiş metin işleme uygulama

Sonunda, uygulamanız şöyle görünecek:

Derin Araştırma Asistanı Demosu

Jan-v1 Nedir?

Jan-v1; araç kullanımı, çok adımlı akıl yürütme ve otomatik araştırma gibi aracısal iş akışları için tasarlanmış, Lucy ve Qwen3-4B-thinking temeli üzerine inşa edilmiş 4B parametreli bir modeldir. Geleneksel LLM'lerin aksine, Jan-v1; yapılandırılmış iskelenme ve davranışla hizalanmış ödüller aracılığıyla araçlar, veri kaynakları ve akıl yürütme adımları arasında koordinasyonda ustadır.

İşte bu modelin birkaç kilit özelliği:

  • Ajan hazır mimari: Model, gelişmiş akıl yürütme ve araç API'lerini kullanarak web araması, sentez ve yapılandırılmış rapor üretimini gerçekleştiren gerçek dünya entegrasyonu için optimize edilmiştir.
  • Verimlilik: Küçük boyutuna rağmen, Jan-v1, odaklı ve hedefe yönelik çıktılara vurgu yapan hedeflenmiş RL eğitimi sayesinde genellikle çok daha büyük modellerde görülen performansı sunar.
  • Gizlilik odaklı dağıtım: Kompakt GGUF formatı, dizüstü bilgisayarlarda veya CPU'larda düşük gecikmeli, özel araştırma görevleri için ideal olan hızlı, yerel çıkarımı mümkün kılar.
  • Araştırmaya ayarlı eğitim: Jan-v1, bilgilendiricilik ile kısalığı dengeleyen yeni ödül fonksiyonları kullanır; bu da analiz ve raporlama gibi kritik görevler için önemlidir ve halüsinasyon ile gevezeliği en aza indirir.
  • Qwen3-4B-thinking üzerine kurulu: Model, Qwen3'ün thinking-mode füzyonundan sağlam zincirleme akıl yürütme ve araç kontrolünü devralır; bu da araştırma otomasyon hatları için özellikle etkilidir.

Jan-v1'i Yerelde Kurma

Bu proje için, en uygun performans ve kaynak verimliliği adına GGUF quantized sürümüyle Llama.cpp kullanarak Jan-v1'i yerelde dağıtacağız.

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

Önce, gerekli Python paketlerine sahip olduğunuzdan emin olun:

pip install llama-cpp-python==0.3.15
pip install streamlit aiohttp 

Bu komut, yapay zekâ modeli entegrasyonu, web arayüzü oluşturma ve eşzamansız web işlemleri için gereken tüm çekirdek bağımlılıkları kurar.

Adım 2: Jan-v1 GGUF sürümünü indirin

Modeli indirmeden önce, aşağıdaki komutu kullanarak models/ adlı yeni bir dizin oluşturun:

 mkdir -p models

Ardından, aşağıdaki komutla modeli indirin:

curl -L https://huggingface.co/janhq/Jan-v1-4B-GGUF/resolve/main/Jan-v1-4B-Q4_K_M.gguf -o Jan-v1-4B-Q4_K_M.gguf

Bu adımı tamamlayarak Jan-v1 4B modelini GGUF formatında başarıyla indirip models/ dizinine yerleştirdiniz. Bu quantized sürüm, performans ile bellek verimliliği arasında dengeli bir takas sunar ve CPU'larda veya Colab'de yerel çıkarım için idealdir.

Adım 3: Serper API anahtarını ayarlayın

Serper hesabınıza kaydolun veya giriş yapın: https://serper.dev/api-keys ve API Keys sekmesini seçin; ardından bu demo için varsayılan API anahtarını kopyalayın. Bu anahtarı aşağıdaki gibi bir ortam değişkeni olarak ayarlayalım:

export SERPER_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxx

Serper API Anahtarı

Artık araştırma asistanı hattınızda modeli yüklemeye ve onunla etkileşime geçmeye hazırsınız.

Demo: Jan-v1 ile Derin Araştırma Asistanı

Jan-v1'in gelişmiş araştırma yeteneklerini; akıllı sorgu oluşturma, otomatik web araması (Serper kullanarak) ve profesyonel rapor senteziyle sergileyen bir Streamlit uygulaması oluşturalım.

Adım 1: Kütüphaneleri içe aktarın

Araştırma asistanımız için gerekli tüm kütüphaneleri içe aktararak başlıyoruz. Bunlar, web arayüzü oluşturmadan eşzamansız web aramaya ve yerel yapay zekâ modeli entegrasyonuna kadar her şeyi destekler.

import streamlit as st
import json
import time
import re
from datetime import datetime
from typing import List, Dict, Optional
import asyncio
import aiohttp
from llama_cpp import Llama
import os
from dataclasses import dataclass

Uygulama boyunca kullanılan tüm çekirdek kütüphaneleri içe aktarıyoruz. Bunlara UI bileşenleri (Streamlit), eşzamanlılık araçları (asyncio, aiohttp) ve LLM arka ucu (llama_cpp) dahildir. Ayrıca ayrıştırma, türleme ve tarih işlemleri için yardımcı araçları da dâhil edeceğiz.

Adım 2: Yardımcı fonksiyonlar

Şimdi, rapor biçimlendirme ve içerik çıkarımıyla ilgilenen birkaç yardımcı fonksiyon uygulayacağız. Bu fonksiyonlar, üretilen raporlarımızın profesyonel kaliteyi ve tutarlı bir yapıyı korumasını sağlar.

def sections_for_format(fmt: str) -> list[str]:
    fmt = (fmt or "").strip().lower()
    if fmt == "executive":
        return ["EXECUTIVE SUMMARY"]
    if fmt == "detailed":
        return [
            "INTRODUCTION",
            "DETAILED ANALYSIS",
            "CURRENT TRENDS AND DEVELOPMENTS",
            "IMPLICATIONS AND RECOMMENDATIONS",
            "CONCLUSION",
        ]
    if fmt == "academic":
        return [
            "ABSTRACT",
            "INTRODUCTION",
            "METHODOLOGY",
            "FINDINGS",
            "DISCUSSION",
            "CONCLUSION",
        ]
    if fmt == "presentation":
        return [
            "OVERVIEW",
            "KEY INSIGHTS",
            "RECOMMENDATIONS",
            "NEXT STEPS",
            "CONCLUSION",
        ]
    return ["INTRODUCTION", "DETAILED ANALYSIS", "CONCLUSION"]
def extract_final_block(text: str) -> str:
    m = re.search(r"<final>([\s\S]*?)</final>", text, flags=re.IGNORECASE)
    if m:
        cleaned_text = m.group(1).strip()
    else:
        cleaned_text = text
    preamble_patterns = [
        r"^(?:note:|okay,|hmm,|internal|let me|i (?:will|’ll)|as an ai|thinking|plan:|here is your report|the following is|i have prepared|i am presenting|based on the provided information|below is the report|i hope this meets your requirements|this report outlines|this is the final report).*?$",
        r"^(?:Here is the report|I have compiled the report|The report is provided below|This is the requested report).*?$", # More specific preambles
        r"^(?:Please find the report below|Here's the report).*?$"
    ]
    for pattern in preamble_patterns:
        cleaned_text = re.sub(pattern, "", cleaned_text, flags=re.IGNORECASE | re.MULTILINE).strip()
    cleaned_text = re.sub(r"(?m)^\s*[-*•]\s+", "", cleaned_text)
    cleaned_text = re.sub(r"[#`*_]{1,3}", "", cleaned_text)
    headers = [
        "EXECUTIVE SUMMARY","INTRODUCTION","DETAILED ANALYSIS","CURRENT TRENDS AND DEVELOPMENTS",
        "IMPLICATIONS AND RECOMMENDATIONS","CONCLUSION","ABSTRACT","METHODOLOGY","FINDINGS",
        "DISCUSSION","OVERVIEW","KEY INSIGHTS","RECOMMENDATIONS","NEXT STEPS"
    ]
    sorted_headers = sorted(headers, key=len, reverse=True)
    first_pos = -1
    for h in sorted_headers:
        match = re.search(r'\b' + re.escape(h) + r'\b', cleaned_text, flags=re.IGNORECASE)
        if match:
            if first_pos == -1 or match.start() < first_pos:
                first_pos = match.start()
    if first_pos >= 0:
        cleaned_text = cleaned_text[first_pos:].strip()
    return cleaned_text

Her fonksiyonun akışa katkısı şöyle:

  • sections_for_format() fonksiyonu: Bu fonksiyon, seçilen rapor biçimine (ör. executive, detailed, academic) uyarlanmış bölüm başlıkları üretir. Böylece her rapor profesyonel standartlara uyar ve kullanıcı beklentilerini karşılar.
  • extract_final_block() fonksiyonu: Bu son işleme adımı, raporun özünü izole eder. <final> etiketleri arasındaki metni çıkarır ve önsözleri, dolgu ifadelerini ve markdown artifaktlarını temizler. Ayrıca en erken standart başlığı (ör. "INTRODUCTION", "SUMMARY") algılayarak ilgisiz giriş metnini kaldırır; böylece nihai çıktı temiz, yapılandırılmış ve kullanıma hazır olur.

Bu yardımcı fonksiyonlar, Jan-v1 gibi düşünen bir model için farklı rapor formatları ve araştırma senaryolarında tutarlı, yüksek kaliteli çıktı elde etmek açısından kritik öneme sahiptir.

Adım 3: Yapılandırmaları ayarlama

Model parametrelerini, API ayarlarını ve araştırma tercihlerini yöneten temel yapılandırma sistemini oluşturalım. Bu modüler yaklaşım, kolay özelleştirme ve en iyi performansı sağlar.

Adım 3.1: Araştırma yapılandırması

Bu adım, Jan-v1 modeliyle verimli yerel çıkarım için bir yapılandırma sistemi ve model yükleyiciyi tanımlar. Sistem, esneklik ve güvenliği korurken dizüstü bilgisayarlar veya Colab Pro gibi yalnızca CPU bulunan ortamlarda tekrarlanabilir araştırma görevlerini destekleyecek şekilde tasarlanmıştır.

@dataclass
class ResearchConfig:
    model_path: str = "models/Jan-v1-4B-Q4_K_M.gguf" #change as per your location
    max_tokens: int = 2048
    temperature: float = 0.6
    top_p: float = 0.95
    top_k: int = 20
    context_length: int = 4096
    search_api_key: str = os.getenv("SERPER_API_KEY", "")
    search_engine: str = "serper"  

Yukarıdaki kodun yapılandırma özeti:

  • Merkezileştirilmiş parametreler: ResearchConfig, farklı araştırma senaryoları için kolay ayar yapmaya olanak tanıyan tüm LLM ve arama motoru yapılandırmalarını merkezileştiren bir @dataclass'tır.
  • Çıkarım hiperparametreleri: temperature, top_p ve top_k gibi parametreler, araştırma odaklı çıktılar için önemli olan yaratıcılık ile olgusal temellilik arasında denge kuracak şekilde ayarlanmıştır.
  • Bellek ve bağlam: context_length 4096 token olarak ayarlanmıştır; bu, Jan-v1'in uzun biçimli akıl yürütme yetenekleri için optimize edilmiştir.
  • API entegrasyonu: search_api_key, Serper ile gerçek zamanlı web arama artırımı için entegrasyonu etkinleştirir.

Adım 3.2: Derin Araştırma asistanı 

Bu adımda, tüm araştırma görevleri için çekirdek denetleyici olarak görev yapan, düşük seviye model ve yapılandırma işlemlerini soyutlarken üretim, arama ve sentez için yüksek seviye arayüzler sunan bir Derin Araştırma asistanı sınıfı tanımlıyoruz.

class DeepResearchAssistant:
    def __init__(self, config: ResearchConfig):
        self.config = config
        self.llm = None
        self.demo_mode = False
    def load_model(self):
        try:
            if not os.path.exists(self.config.model_path):
                print(f"Model file not found: {self.config.model_path}")
                return False
            file_size_gb = os.path.getsize(self.config.model_path) / (1024**3)
            if file_size_gb < 1.0:
                print(f"Model file too small ({file_size_gb:.1f} GB).")
                return False
            self.llm = Llama(
                model_path=self.config.model_path,
                n_ctx=self.config.context_length,
                verbose=False,
                n_threads=max(1, min(4, os.cpu_count() // 2)),
                n_gpu_layers=0,
                use_mmap=True,
                use_mlock=False,
                n_batch=128,
                f16_kv=True,
            )
            test = self.llm("Hi", max_tokens=3, temperature=0.1, echo=False)
            ok = bool(test and 'choices' in test)
            print("Model loaded " if ok else "Model loaded but test generation failed ")
            return ok
        except Exception as e:
            print(f"Model loading failed: {e}")
            return False

DeepResearchAssistant sınıfı, model yüklemeyi ve yapılandırma doğrulamasını yöneten ve araştırma işlemleri için temiz bir arayüz sağlayan ana orkestratördür. Bu yapılandırma sistemi, hataların ele alınmasını ve doğrulamayı sağlar; modelin doğru şekilde yüklenip araştırma görevlerine hazır olmasını güvence altına alır. Sınıfın başlıca özellikleri şunlardır:

  • Modeli başlatma: load_model() yöntemi, yerel CPU çıkarımı için optimize edilmiş llama-cpp-python kullanarak Jan-v1 GGUF modelini güvenle başlatır.
  • Doğrulama kontrolleri: Önce, eksik veya bozuk dosyaları yakalamak için model yolunu ve minimum dosya boyutunu doğrularız.
  • Bellek eşleme: Ardından, tam RAM tüketmeden verimli disk destekli yüklemeyi etkinleştirmek için use_mmap=True kullanırız.
  • Optimize çıkarım: Ayrıca iş parçacıklarını, batch boyutunu yapılandırır ve bellek kullanımını azaltmak için f16_kv=True etkinleştiririz. n_gpu_layers=0 parametresi yalnızca CPU yürütümünü garanti eder.
  • Sağlamlık testi: Modelin doğru yanıt verdiğini doğrulamak için yükleme sonrası hafif bir istem gönderen bir sağlamlık testi yaparız.

Bu kurulum, GPU olmadan dizüstü bilgisayarlarda veya Colab'de Jan-v1'i çalıştırmak için ideal, hızlı ve hafif yerel çıkarım sağlar.

Adım 3.3: Bir yanıt üretme

Sırada, araştırma otomasyonumuzu güçlendiren web arama yetenekleriyle birlikte çekirdek yanıt üretim sistemini uygulayacağız. Bunun için, aşağıda gösterildiği gibi Serper API hizmetlerini kullanıyoruz:

def generate_response(self, prompt: str, max_tokens: int = None, extra_stops: Optional[List[str]] = None) -> str:
        if not self.llm:
            return "Model not loaded."
        stops = ["</s>", "<|im_end|>", "<|endoftext|>"]
        if extra_stops:
            stops.extend(extra_stops)
        mt = max_tokens or self.config.max_tokens
        try:
            resp = self.llm(
                prompt,
                max_tokens=mt,
                temperature=self.config.temperature,
                top_p=self.config.top_p,
                top_k=self.config.top_k,
                stop=stops,
                echo=False
            )
            return resp["choices"][0]["text"].strip()
        except Exception as e:
            return f"Error generating response: {str(e)}"
    async def search_web(self, query: str, num_results: int = 10) -> List[Dict]:
        if self.config.search_api_key:
            return await self.search_serper(query, num_results)
        return []
    async def search_serper(self, query: str, num_results: int) -> List[Dict]:
        url = "https://google.serper.dev/search"
        payload = {"q": query, "num": num_results}
        headers = {"X-API-KEY": self.config.search_api_key, "Content-Type": "application/json"}
        async with aiohttp.ClientSession() as session:
            async with session.post(url, json=payload, headers=headers) as response:
                data = await response.json()
                results = []
                for item in data.get('organic', []):
                    results.append({
                        'title': item.get('title', ''),
                        'url': item.get('link', ''),
                        'snippet': item.get('snippet', ''),
                        'source': 'web'
                    })
                return results
    def generate_search_queries(self, topic: str, focus_area: str, depth: str) -> List[str]:
        counts = {'surface': 5, 'moderate': 8, 'deep': 15, 'comprehensive': 25}
        n = counts.get(depth, 8)
        base = [
            f"{topic} overview",
            f"{topic} recent developments",
            f"{topic} academic studies",
            f"{topic} case studies",
            f"{topic} policy and regulation",
            f"{topic} technical approaches",
            f"{topic} market analysis",
            f"{topic} statistics and data",
        ]
        return base[:n]

Yukarıdaki kod, temel işlevselliği şu şekilde bölümlere ayırır:

  • generate_response() fonksiyonu: Bu fonksiyon, uygun hata yönetimi ve yapılandırılabilir durdurma dizileriyle tüm Jan-v1 model etkileşimlerini ele alır. Bu sayede araştırma sentezi için tutarlı ve yüksek kaliteli metin üretimi sağlanır.
  • search_web() ve search_serper() fonksiyonları: Bu fonksiyonlar, Serper API kullanarak eşzamansız web araması uygular ve birden fazla sorgu arasında hızlı, paralel arama sağlar. Async tasarım, araştırma işlemleri sırasında UI'nin kilitlenmesini önler.
  • generate_search_queries() fonksiyonu: Araştırma derinliği ve odak konusuna dayalı çeşitli arama sorguları oluşturmak için generate_search_queries() fonksiyonunu uygularız. Konuya genel bakışlardan teknik yaklaşımlara, vaka çalışmalarından düzenlemelere ve pazar analizine kadar araştırma konusunun kapsamlı bir şekilde ele alınmasını sağlar. Seçilen derinliğe (surface, moderate, deep veya comprehensive) bağlı olarak sorgu sayısını 5 ile 25 arasında ölçeklendirmenize olanak tanır.

Bu yanıt üretim sistemi, Jan-v1'in akıl yürütme yeteneklerini gerçek zamanlı web aramasıyla birleştirerek araştırma raporları oluşturmamızın çekirdeğini oluşturur.

Adım 3.4: Araştırmayı sentezleme

Sırada, ham arama sonuçlarını cilalı, profesyonel raporlara dönüştüren bir araştırma sentezi altyapısı uygulayacağız.

def synthesize_research(self, topic: str, search_results: List[Dict], focus_area: str, report_format: str) -> str:
        context_lines = []
        for i, result in enumerate(search_results[:20]):
            title = result.get("title", "")
            snippet = result.get("snippet", "")
            context_lines.append(f"Source {i+1} Title: {title}\nSource {i+1} Summary: {snippet}")
        context = "\n".join(context_lines)
        sections = sections_for_format(report_format)
        sections_text = "\n".join(sections)
        synthesis_prompt = f"""
You are an expert research analyst. Write the final, polished report on: "{topic}" for a professional, real-world audience.
***CRITICAL INSTRUCTIONS:***
- Your entire response MUST be the final report, wrapped **EXACTLY** inside <final> and </final> tags.
- DO NOT output any text, thoughts, or commentary BEFORE the <final> tag or AFTER the </final> tag.
- DO NOT include any conversational filler, internal thoughts, or commentary about the generation process (e.g., "As an AI...", "I will now summarize...", "Here is your report:").
- DO NOT use markdown formatting (e.g., #, ##, *, -).
- DO NOT use bullet points or lists.
- Maintain a formal, academic/professional tone throughout.
- Ensure the report is complete and self-contained.
- Include the following section headers, in this order, and no others:
{sections_text}
Guidance:
- Base your writing strictly on the Research Notes provided below. If the notes lack specific data, write a careful, methodology-forward analysis without inventing facts or numbers.
Research Notes:
{context}
Now produce ONLY the final report:
<final>
...your report here...
</final>
"""
        raw = self.generate_response(synthesis_prompt, max_tokens=1800, extra_stops=["</final>"])
        final_report = extract_final_block(raw)
        final_report = re.sub(r"(?m)^\s*[-*•]\s+", "", final_report)
        final_report = re.sub(r"[#`*_]{1,3}", "", final_report)
        first = next((h for h in sections if h in final_report), None)
        if first:
            final_report = final_report[final_report.find(first):].strip()
        return final_report

Yukarıdaki kod, Jan-v1'in gelişmiş akıl yürütme yeteneklerinden yararlanarak, ham web arama sonuçlarını normalde saatler sürecek manuel araştırma ve yazım gerektiren profesyonel raporlara dönüştürür. Kilit yetenekleri ayrıntılı olarak inceleyelim:

  • Bağlamsal gömme: Yukarıdaki kod, başlıkları ve özetleri numaralandırılmış bir formatta birleştirerek yapılandırılmamış arama isabetlerini yapılandırılmış metinsel araştırma notlarına dönüştürür. Bu, yüksek bilgi yoğunluğunu garanti eder ve modele aktarılırken bağlam parçalanmasını en aza indirir.
  • Dinamik istem oluşturma: sections_for_format() fonksiyonunu kullanarak, seçilen çıktı biçimine uyarlanmış rapor bölüm başlıkları üretir ve bunları, modelin davranışını kısıtlayan katı üretim kurallarıyla birlikte isteme enjekte ederiz.
  • Halüsinasyon azaltma: <final>...</final> etiketlerinin kullanımını zorlayıp sohbet tarzı iskeleyi yasaklayarak, modelin alakasız metin, spekülatif özetler veya gereksiz çerçevelemeler eklemesi engellenir.
  • Son işleme ve normalizasyon: Kod çözüldükten sonra, rapor markdown artifaktlarını, liste işaretlerini ve rastgele biçimlendirmeleri ayıklayan regex filtreleriyle temizlenir. Fonksiyon ayrıca, yapısal tutarlılığı artırmak için çıktının ilk geçerli bölüm başlığından başlamasını sağlar.

Adım 4: Ana Streamlit uygulama akışı

Son olarak, tüm araştırma yeteneklerimizi etkileşimli bir uygulamada bir araya getiren komple kullanıcı arayüzünü inşa edeceğiz.

def main():
    st.set_page_config(page_title="Deep Research Assistant", page_icon="", layout="wide")
    st.markdown("""
    <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 1.25rem; border-radius: 10px; color: white; text-align: center; margin-bottom: 1rem;">
        <h1 style="margin:0;"> Deep Research Assistant</h1>
    </div>
    """, unsafe_allow_html=True)
    if 'research_assistant' not in st.session_state:
        config = ResearchConfig()
        st.session_state.research_assistant = DeepResearchAssistant(config)
        st.session_state.model_loaded = st.session_state.research_assistant.load_model()
        st.session_state.research_results = None
    if not st.session_state.research_assistant.config.search_api_key:
        st.warning("SERPER_API_KEY not found in environment. Using fallback demo results.")
    st.header("Research Configuration")
    research_topic = st.text_area(
        "Research Topic",
        placeholder="e.g., Impact of artificial intelligence on healthcare efficiency and patient outcomes",
        height=100
    )
    col1a, col1b = st.columns(2)
    with col1a:
        research_depth = st.selectbox(
            "Research Depth",
            ["surface", "moderate", "deep", "comprehensive"],
            index=1,
            format_func=lambda x: {
                "surface": "Surface (5-8 sources)",
                "moderate": "Moderate (10-15)",
                "deep": "Deep Dive (20-30)",
                "comprehensive": "Comprehensive (40+)"
            }[x]
        )
        focus_area = st.selectbox("Focus Area", ["general", "academic", "business", "technical", "policy"], index=0, format_func=str.title)
    with col1b:
        time_frame = st.selectbox(
            "Time Frame",
            ["current", "recent", "comprehensive"],
            index=1,
            format_func=lambda x: {"current":"Current (≤6 months)","recent":"Recent (≤2 years)","comprehensive":"All time"}[x]
        )
        report_format = st.selectbox(
            "Report Format",
            ["executive", "detailed", "academic", "presentation"],
            index=1,
            format_func=lambda x: {
                "executive":"Executive Summary",
                "detailed":"Detailed Analysis",
                "academic":"Academic Style",
                "presentation":"Presentation Format"
            }[x]
        )
    if st.button("Start Deep Research", type="primary", use_container_width=True):
        if not st.session_state.model_loaded:
            st.error("Model not loaded. See terminal logs for details.")
        elif not research_topic.strip():
            st.error("Please enter a research topic.")
        else:
            start_research(research_topic, research_depth, focus_area, time_frame, report_format)
    if st.session_state.research_results:
        display_research_results(st.session_state.research_results)
def start_research(topic: str, depth: str, focus: str, timeframe: str, format_type: str):
    assistant = st.session_state.research_assistant
    progress_bar = st.progress(0)
    status_text = st.empty()
    try:
        status_text.text("Generating search queries...")
        progress_bar.progress(15)
        queries = assistant.generate_search_queries(topic, focus, depth)
        status_text.text("Searching sources...")
        progress_bar.progress(40)
        all_results = []
        for i, query in enumerate(queries):
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            results = loop.run_until_complete(assistant.search_web(query, 5))
            all_results.extend(results)
            loop.close()
            progress_bar.progress(40 + int(((i + 1) / max(1, len(queries))) * 30))
            time.sleep(0.05)
        status_text.text("Synthesizing report...")
        progress_bar.progress(80)
        research_report = assistant.synthesize_research(topic, all_results, focus, format_type)
        status_text.text("Done.")
        progress_bar.progress(100)
        st.session_state.research_results = {
            'topic': topic,
            'report': research_report,
            'sources': all_results,
            'queries': queries,
            'config': {'depth': depth, 'focus': focus, 'timeframe': timeframe, 'format': format_type},
            'timestamp': datetime.now()
        }
        time.sleep(0.3)
        status_text.empty()
        progress_bar.empty()
    except Exception as e:
        st.error(f"Research failed: {str(e)}")
        status_text.empty()
        progress_bar.empty()
def display_research_results(results: Dict):
    st.header("Research Report")
    st.subheader(f"Topic: {results['topic']}")
    st.markdown(
        f'<div style="background:#f8f9ff;padding:1rem;border-radius:10px;border:1px solid #e1e8ed;">{results["report"]}</div>',
        unsafe_allow_html=True,
    )
    with st.expander("Sources", expanded=False):
        for i, source in enumerate(results['sources'][:12]):
            st.markdown(f"""
            <div style="background:#fff;padding:0.75rem;border-radius:8px;border:1px solid #e1e8ed;margin:0.4rem 0;">
                <h4 style="margin:0 0 .25rem 0;">{source['title']}</h4>
                <p style="margin:0 0 .25rem 0;">{source['snippet']}</p>
                <small><a href="{source['url']}" target="_blank">{source['url']}</a></small>
            </div>
            """, unsafe_allow_html=True)
    st.markdown("### Export")
    c1, c2, c3 = st.columns(3)
    with c1:
        report_text = f"Research Report: {results['topic']}\n\n{results['report']}"
        st.download_button("Download Text", data=report_text, file_name=f"research_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt", mime="text/plain")
    with c2:
        json_data = json.dumps(results, default=str, indent=2)
        st.download_button("Download JSON", data=json_data, file_name=f"research_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", mime="application/json")
    with c3:
        if st.button("Start New Research"):
            st.session_state.research_results = None
            st.experimental_rerun()
if __name__ == "__main__":
    main()

Yukarıdaki kod, model yüklemeden kullanıcı girişi toplamaya; sorgu oluşturma, web araması ve nihai rapor sentezine kadar katmanlara ayrılmıştır. Bu katmanları ayrıntılı olarak tartışalım:

  • UI katmanı (Streamlit ön yüz): Uygulama, gradyan tarzlı bir başlık ve cilalı bir kullanıcı deneyimi için duyarlı bir düzene sahiptir. Arayüz, araştırma parametreleri üzerinde ince ayarlı kontrol sunarken sezgisel kalır; bu da hem teknik hem de teknik olmayan kullanıcılar için idealdir.
  • Yapılandırılabilir hat: Kullanıcılar, derinlik, odak alanı (genel, akademik, iş), zaman aralığı ve çıktı stili (executive, akademik vb.) için seçimlerle araştırma iş akışını özelleştirebilir.
  • Durumlu ajan yönetimi: DeepResearchAssistant, model durumunu koruyup tekrarlı yüklemeyi önlemek için st.session_state kullanılarak oturum başına bir kez başlatılır. 
  • Gerçek zamanlı geri bildirim ve async arama: İlerleme, dinamik Streamlit ilerleme çubukları ve durum güncellemeleriyle izlenir. Web araması, asyncio aracılığıyla eşzamansız olarak yürütülür; böylece UI yanıt verebilirliğini engellemeden paralel sorgu yürütme sağlanır.
  • Sorgu ve sentez döngüsü: Sorgular, istem mühendisliği stratejisi kullanılarak konu ve derinliğe göre otomatik oluşturulur. Elde edilen sonuçlar toplanır ve yapılandırılmış rapor üretimi için Jan-v1 modeline aktarılır.
  • Çıktı görselleştirme ve dışa aktarma: Nihai rapor, genişletilebilir atıflarla bir Markdown bloğunda işlenir. Kullanıcılar raporu TXT veya JSON formatında dışa aktarabilir veya tek tıkla iş akışını yeniden çalıştırabilir.

Kendiniz denemek için kodu app.py olarak kaydedip şu komutla başlatın:

streamlit run app.py

Sonuç

Bu Derin Araştırma Asistanı, Jan-v1'in gelişmiş akıl yürütme yeteneklerinin karmaşık araştırma iş akışlarını otomatikleştirmedeki pratik gücünü gösterir. Sistem başarıyla şunları bir araya getirir:

  • Akıllı otomasyon: Sorgu oluşturmadan profesyonel rapor sentezine kadar uçtan uca araştırmaya olanak tanır ve saatler süren manuel çalışmayı ortadan kaldırır.
  • Ölçeklenebilir tasarım: Yapılandırılabilir araştırma derinliği özelliği, kullanıcı ihtiyaçlarına göre hızlı genel bakışlardan kapsamlı analizlere uyum sağlar.
  • Profesyonel kalite: Yönetici özetleri, akademik araştırmalar ve teknik dokümantasyon için uygun raporların üretilmesine yardımcı olur.
  • Kullanıcı erişilebilirliği: Bu arayüz, gelişmiş yapay zekâ araştırma yeteneklerini teknik geçmişi ne olursa olsun kullanıcılara sunar.

Uygulama, Jan-v1'in %91,1 SimpleQA doğruluğu ve geliştirilmiş akıl yürütme yeteneklerinin; araştırma, analiz ve içerik üretimi iş akışlarında anında değer sunan üretime hazır araçlar geliştirmek için nasıl kullanılabileceğini ortaya koyar.

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.

Konular

İlgili