Zephyrnet Logosu

LangChain'in LangGraph'ı ile Yapay Zeka Kodlama Aracısı Oluşturun

Tarih:

Giriş

Yapay zeka kodlama aracılarını kullanan uygulamalarda büyük bir artış yaşandı. Yüksek Lisans'ların artan kalitesi ve çıkarım maliyetinin azalmasıyla birlikte, yetenekli yapay zeka aracıları oluşturmak daha da kolaylaşıyor. Üstelik takım ekosistemi hızla gelişerek karmaşık yapay zeka kodlama aracılarının oluşturulmasını kolaylaştırıyor. Langchain çerçevesi bu cephede lider olmuştur. Üretime hazır yapay zeka uygulamaları oluşturmak için gerekli tüm araç ve tekniklere sahiptir.

Ancak şu ana kadar bir tek şey eksikti. Ve bu, döngüselliğe sahip çok etmenli bir işbirliğidir. Sorunun bölünüp uzman temsilcilere devredilebildiği karmaşık sorunları çözmek için bu çok önemlidir. Yapay zeka kodlama aracıları arasında çok aktörlü durum bilgisi olan işbirliğini barındırmak için tasarlanan Langchain çerçevesinin bir parçası olan LangGraph'ın devreye girdiği yer burasıdır. Ayrıca bu makalede LangGraph'ı ve onunla bir aracı oluştururken temel yapı taşlarını tartışacağız.

Öğrenme hedefleri

  • LangGraph'ın ne olduğunu anlayın.
  • Durum bilgisi olan Aracılar oluşturmak için LangGraph'ın temellerini keşfedin.
  • Aşağıdakiler gibi açık erişim modellerine erişmek için TogetherAI'yi keşfedin: DeepSeekCoder.
  • Birim testleri yazmak için LangGraph'ı kullanarak bir AI kodlama aracısı oluşturun.
Dil Zinciri

Bu makale, Veri Bilimi Blogatonu.

İçindekiler

LangGraph nedir?

LangGraph, LangChain ekosisteminin bir uzantısıdır. LangChain, görevleri yürütmek için birden fazla araç kullanabilen yapay zeka kodlama aracılarının oluşturulmasına izin verirken, adımlar arasında birden fazla zinciri veya aktörü koordine edemez. Bu, karmaşık görevleri yerine getiren aracılar oluşturmak için çok önemli bir davranıştır. LangGraph bunları akılda tutarak tasarlandı. Aracı iş akışlarını, her düğümün bir işlevi veya Langchain Çalıştırılabilir bir nesneyi temsil ettiği ve kenarların düğümler arasındaki bağlantı olduğu döngüsel bir Grafik yapısı olarak ele alır. 

LangGraph'ın ana özellikleri şunları içerir: 

  • Nodes : Herhangi bir fonksiyon veya Langchain Runnable nesnesi gibi bir araç.
  • kenarlar: Düğümler arasındaki yönü tanımlar.
  • Durum Grafikleri: Birincil grafik türü. Verileri düğümleri aracılığıyla işlerken durum nesnelerini yönetmek ve güncellemek için tasarlanmıştır.

LangGraph, etmen davranışı için çok önemli olan, durum sürekliliği ile döngüsel bir LLM çağrı yürütülmesini kolaylaştırmak için bundan yararlanır. Mimari ilham alıyor pelte ve Apache Kiriş

Bu yazımızda Python sınıfı için Pytest birim testlerini yöntemler ile yazmak için bir Agent oluşturacağız. Ve bu iş akışıdır.

Dil Zinciri

Basit birim testleri yazmaya yönelik yapay zeka kodlama aracımızı oluştururken kavramları ayrıntılı olarak tartışacağız. O halde gelelim kodlama kısmına.

Ancak ondan önce geliştirme ortamımızı kuralım.

Bağımlılıkları Yükle

İlk önce ilk şey. Her Python projesinde olduğu gibi sanal bir ortam oluşturun ve onu etkinleştirin.

python -m venv auto-unit-tests-writer
cd auto-unit-tests-writer
source bin/activate

Şimdi bağımlılıkları yükleyin.

!pip install langgraph langchain langchain_openai colorama

Tüm kütüphaneleri ve sınıflarını içe aktarın.

from typing import TypedDict, List
import colorama
import os

from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage
from langchain_core.messages import HumanMessage
from langchain_core.runnables import RunnableConfig

from langgraph.graph import StateGraph, END
from langgraph.pregel import GraphRecursionError

Ayrıca test senaryoları için dizinler ve dosyalar oluşturmak isteyeceğiz. Bunun için manuel olarak dosya oluşturabilir veya Python'u kullanabilirsiniz.

# Define the paths.
search_path = os.path.join(os.getcwd(), "app")
code_file = os.path.join(search_path, "src/crud.py")
test_file = os.path.join(search_path, "test/test_crud.py")

# Create the folders and files if necessary.
if not os.path.exists(search_path):
    os.mkdir(search_path)
    os.mkdir(os.path.join(search_path, "src"))
    os.mkdir(os.path.join(search_path, "test"))

Şimdi crud.py dosyasını bellek içi CRUD uygulamasının koduyla güncelleyin. Bu kod parçasını birim testleri yazmak için kullanacağız. Bunun için Python programınızı kullanabilirsiniz. Aşağıdaki programı code.py dosyamıza ekleyeceğiz.

#crud.py
code = """class Item:
    def __init__(self, id, name, description=None):
        self.id = id
        self.name = name
        self.description = description

    def __repr__(self):
        return f"Item(id={self.id}, name={self.name}, description={self.description})"

class CRUDApp:
    def __init__(self):
        self.items = []

    def create_item(self, id, name, description=None):
        item = Item(id, name, description)
        self.items.append(item)
        return item

    def read_item(self, id):
        for item in self.items:
            if item.id == id:
                return item
        return None

    def update_item(self, id, name=None, description=None):
        for item in self.items:
            if item.id == id:
                if name:
                    item.name = name
                if description:
                    item.description = description
                return item
        return None

    def delete_item(self, id):
        for index, item in enumerate(self.items):
            if item.id == id:
                return self.items.pop(index)
        return None

    def list_items(self):
        return self.items"""
        
with open(code_file, 'w') as f:
  f.write(code)

LLM'yi kurun

Şimdi bu projede kullanacağımız LLM'yi belirleyeceğiz. Burada hangi modelin kullanılacağı, görevlere ve kaynakların kullanılabilirliğine bağlıdır. GPT-4, Gemini Ultra veya GPT-3.5 gibi tescilli, güçlü modelleri kullanabilirsiniz. Ayrıca Mixtral ve Llama-2 gibi açık erişimli modelleri de kullanabilirsiniz. Bu durumda kod yazmayı gerektirdiği için DeepSeekCoder-33B veya Llama-2 coder gibi ince ayarlı bir kodlama modeli kullanabiliriz. Artık LLM çıkarımı için Anayscale, Abacus ve Together gibi birden fazla platform var. DeepSeekCoder'ı anlamak için Together AI'yı kullanacağız. Yani, bir tane al API anahtarı Devam etmeden önce Birlikte'den. 

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(base_url="https://api.together.xyz/v1",
    api_key="your-key",
    model="deepseek-ai/deepseek-coder-33b-instruct")

Birlikte API, OpenAI SDK ile uyumlu olduğundan, base_url parametresini şu şekilde değiştirerek Together'da barındırılan modellerle iletişim kurmak için Langchain'in OpenAI SDK'sını kullanabiliriz. “https://api.together.xyz/v1”. api_key'de Together API anahtarınızı iletin ve modeller yerine model adı Together'da mevcuttur.

Temsilci Durumunu Tanımlayın

Bu LangGraph'ın önemli parçalarından biridir. Burada, yürütme boyunca Ajanların durumlarını takip etmekten sorumlu bir Ajan Durumu tanımlayacağız. Bu öncelikle Aracıların durumunu koruyan varlıklara sahip bir TypedDict sınıfıdır. AgentState'imizi tanımlayalım

class AgentState(TypedDict):
    class_source: str
    class_methods: List[str]
    tests_source: str

Yukarıdaki AgentState sınıfında, class_source orijinal Python sınıfını, sınıfın yöntemlerini depolamak için class_methods'u ve birim test kodları için testler_source'u saklar. Bunları yürütme adımlarında kullanmak için AgentState olarak tanımladık. 

Şimdi Grafiği AgentState ile tanımlayın.

# Create the graph.
workflow = StateGraph(AgentState)

Daha önce de belirttiğimiz gibi bu durum bilgisi olan bir grafiktir ve şimdi durum nesnemizi ekledik.

Düğümleri Tanımla

Artık AgentState'i tanımladığımıza göre düğümleri eklememiz gerekiyor. Peki düğümler tam olarak nedir? LangGraph'ta düğümler, tek bir eylemi gerçekleştiren işlevler veya Langchain araçları gibi çalıştırılabilir nesnelerdir. Bizim durumumuzda, sınıf yöntemlerini bulmaya yönelik bir işlev, durum nesnelerine birim testlerini çıkarmaya ve güncellemeye yönelik bir işlev ve bunu bir test dosyasına yazmaya yönelik bir işlev gibi birkaç düğüm tanımlayabiliriz.

Ayrıca bir LLM mesajından kodları çıkarmanın bir yoluna da ihtiyacımız var. İşte nasıl.

def extract_code_from_message(message):
    lines = message.split("n")
    code = ""
    in_code = False
    for line in lines:
        if "```" in line:
            in_code = not in_code
        elif in_code:
            code += line + "n"
    return code

Buradaki kod pasajı, kodların üçlü tırnak işaretleri içinde olduğunu varsayar.

Şimdi düğümlerimizi tanımlayalım.

import_prompt_template = """Here is a path of a file with code: {code_file}.
Here is the path of a file with tests: {test_file}.
Write a proper import statement for the class in the file.
"""
# Discover the class and its methods.
def discover_function(state: AgentState):
    assert os.path.exists(code_file)
    with open(code_file, "r") as f:
        source = f.read()
    state["class_source"] = source

    # Get the methods.
    methods = []
    for line in source.split("n"):
        if "def " in line:
            methods.append(line.split("def ")[1].split("(")[0])
    state["class_methods"] = methods

    # Generate the import statement and start the code.
    import_prompt = import_prompt_template.format(
        code_file=code_file,
        test_file=test_file
    )
    message = llm.invoke([HumanMessage(content=import_prompt)]).content
    code = extract_code_from_message(message)
    state["tests_source"] = code + "nn"

    return state


# Add a node to for discovery.
workflow.add_node(
    "discover",
    discover_function
)

Yukarıdaki kod parçasında kodları keşfetmeye yönelik bir fonksiyon tanımladık. Kodları AgentState'ten çıkarır sınıf_kaynağı öğesi, sınıfı bireysel yöntemlere ayırır ve istemlerle birlikte LLM'ye iletir. Çıktı AgentState'in belleğinde saklanır. testler_kaynağı eleman. Yalnızca birim test senaryoları için içe aktarma ifadeleri yazmasını sağlıyoruz.

Ayrıca ilk düğümü StateGraph nesnesine ekledik.

Şimdi bir sonraki düğüme geçelim. 

Ayrıca burada ihtiyacımız olacak bazı bilgi istemi şablonlarını da ayarlayabiliriz. Bunlar ihtiyaçlarınıza göre değiştirebileceğiniz örnek şablonlardır.

# System message template.

system_message_template = """You are a smart developer. You can do this! You will write unit 
tests that have a high quality. Use pytest.

Reply with the source code for the test only. 
Do not include the class in your response. I will add the imports myself.
If there is no test to write, reply with "# No test to write" and 
nothing more. Do not include the class in your response.

Example:

```
def test_function():
    ...
```

I will give you 200 EUR if you adhere to the instructions and write a high quality test. 
Do not write test classes, only methods.
"""

# Write the tests template.
write_test_template = """Here is a class:
'''
{class_source}
'''

Implement a test for the method "{class_method}".
"""

Şimdi düğümü tanımlayın.

# This method will write a test.
def write_tests_function(state: AgentState):

    # Get the next method to write a test for.
    class_method = state["class_methods"].pop(0)
    print(f"Writing test for {class_method}.")

    # Get the source code.
    class_source = state["class_source"]

    # Create the prompt.
    write_test_prompt = write_test_template.format(
        class_source=class_source,
        class_method=class_method
    )
    print(colorama.Fore.CYAN + write_test_prompt + colorama.Style.RESET_ALL)

    # Get the test source code.
    system_message = SystemMessage(system_message_template)
    human_message = HumanMessage(write_test_prompt)
    test_source = llm.invoke([system_message, human_message]).content
    test_source = extract_code_from_message(test_source)
    print(colorama.Fore.GREEN + test_source + colorama.Style.RESET_ALL)
    state["tests_source"] += test_source + "nn"

    return state

# Add the node.
workflow.add_node(
    "write_tests",
    write_tests_function
)

Burada LLM'nin her yöntem için test senaryoları yazmasını sağlayacağız, bunları AgentState'in testler_source öğesine güncelleyeceğiz ve bunları iş akışı StateGraph nesnesine ekleyeceğiz.

kenarlar

Artık iki düğümümüz olduğuna göre, aralarındaki yürütme yönünü belirlemek için aralarındaki kenarları tanımlayacağız. LangGraph öncelikle iki tür kenar sağlar.

  • Koşullu Kenar: Yürütmenin akışı aracıların tepkisine bağlıdır. Bu, iş akışlarına döngüsellik kazandırmak açısından çok önemlidir. Aracı, bazı koşullara bağlı olarak bir sonraki düğümün hangi düğüme taşınacağına karar verebilir. Önceki düğüme geri dönmek mi, geçerli düğümü tekrarlamak mı yoksa sonraki düğüme geçmek mi gerektiği.
  • Normal Kenar: Bu, bir düğümün her zaman öncekilerin çağrılmasından sonra çağrıldığı normal durumdur.

Discover ve write_tests'i bağlamak için bir koşula ihtiyacımız yok, bu yüzden normal bir kenar kullanacağız. Ayrıca yürütmenin nerede başlaması gerektiğini belirten bir giriş noktası tanımlayın.

# Define the entry point. This is where the flow will start.
workflow.set_entry_point("discover")

# Always go from discover to write_tests.
workflow.add_edge("discover", "write_tests")

Yürütme, yöntemlerin keşfedilmesiyle başlar ve test yazma işlevine geçer. Birim test kodlarını test dosyasına yazmak için başka bir düğüme ihtiyacımız var.

# Write the file.
def write_file(state: AgentState):
    with open(test_file, "w") as f:
        f.write(state["tests_source"])
    return state

# Add a node to write the file.
workflow.add_node(
    "write_file",
    write_file)

Bu bizim son düğümümüz olduğundan, yazma_testleri ve yazma_dosyası arasında bir kenar tanımlayacağız. Bunu şu şekilde yapabiliriz.

# Find out if we are done.
def should_continue(state: AgentState):
    if len(state["class_methods"]) == 0:
        return "end"
    else:
        return "continue"

# Add the conditional edge.
workflow.add_conditional_edges(
    "write_tests",
    should_continue,
    {
        "continue": "write_tests",
        "end": "write_file"
    }
)

add_conditional_edge işlevi, write_tests işlevini, class_methods girişlerine göre hangi adımın atılacağına karar veren bir Should_continue işlevini ve anahtar olarak dizeleri ve değer olarak diğer işlevleri içeren bir eşlemeyi alır.

Kenar, write_tests'te başlar ve Should_continue çıktısına bağlı olarak eşlemedeki seçeneklerden herhangi birini yürütür. Örneğin, eğer durum[“sınıf_yöntemleri”] boş değilse, tüm yöntemler için testler yazmamışız demektir; write_tests fonksiyonunu tekrarlıyoruz ve testleri yazmayı bitirdiğimizde write_file çalıştırılıyor.

Tüm yöntemlere ilişkin testler çıkarıldığında Yüksek Lisans, testler test dosyasına yazılır.

Şimdi kapatma için iş akışı nesnesine son kenarı ekleyin.

# Always go from write_file to end.
workflow.add_edge("write_file", END)

İş Akışını Yürütün

Geriye kalan son şey iş akışını derleyip çalıştırmaktı.

# Create the app and run it
app = workflow.compile()
inputs = {}
config = RunnableConfig(recursion_limit=100)
try:
    result = app.invoke(inputs, config)
    print(result)
except GraphRecursionError:
    print("Graph recursion limit reached.")

Bu, uygulamayı çağıracaktır. Yineleme sınırı, belirli bir iş akışı için LLM'nin kaç kez çıkarılacağıdır. Limit aşıldığında iş akışı durur.

Günlükleri terminalde veya dizüstü bilgisayarda görebilirsiniz. Bu basit bir CRUD uygulamasının yürütme günlüğüdür.

Uzun zincir

Ağır işlerin çoğu temel model tarafından yapılacaktır; bu, Deepseek kodlayıcı modeliyle yapılan bir demo uygulamasıydı; daha iyi performans için GPT-4 veya Claude Opus, haiku vb. kullanabilirsiniz.

 Langchain araçlarını internette gezinmek, hisse senedi fiyat analizi vb. için de kullanabilirsiniz.

LangChain vs LangGraph

Şimdi asıl soru LangChain'in ne zaman kullanılacağıdır. LangGrafik.

Amaç, aralarında koordinasyon olan çok etmenli bir sistem oluşturmaksa gidilecek yol LangGraph'tır. Ancak görevleri tamamlamak için DAG'ler veya zincirler oluşturmak istiyorsanız LangChain İfade Dili en uygunudur.

Neden LangGraph'ı kullanmalısınız?

LangGraph mevcut birçok çözümü geliştirebilecek güçlü bir çerçevedir. 

  • RAG boru hatlarını iyileştirin: LangGraph döngüsel grafik yapısıyla RAG'ı güçlendirebilir. Alınan nesnenin kalitesini değerlendirmek için bir geri bildirim döngüsü oluşturabilir ve gerekirse sorguyu geliştirip süreci tekrarlayabiliriz.
  • Çok Aracılı İş Akışları: LangGraph, çoklu aracılı iş akışlarını destekleyecek şekilde tasarlanmıştır. Bu, daha küçük alt görevlere bölünmüş karmaşık görevleri çözmek için çok önemlidir. Paylaşılan bir duruma ve farklı LLM'lere ve araçlara sahip farklı temsilciler, tek bir görevi çözmek için işbirliği yapabilir.
  • Insan-in-the-döngü: LangGraph, döngüdeki insan iş akışı için yerleşik desteğe sahiptir. Bu, bir insanın bir sonraki düğüme geçmeden önce durumları gözden geçirebileceği anlamına gelir.
  • Planlama Temsilcisi: LangGraph, bir LLM planlayıcısının bir kullanıcı isteğini planladığı ve ayrıştırdığı, bir uygulayıcının araçları ve işlevleri çağırdığı ve LLM'nin önceki çıktılara dayalı olarak yanıtları sentezlediği planlama aracıları oluşturmak için çok uygundur.
  • Çok Modlu Acenteler: LangGraph, görüş özellikli aracılar gibi çok modlu aracılar oluşturabilir web gezginleri.

Gerçek Hayattaki Kullanım Durumları

Karmaşık yapay zeka kodlama aracılarının faydalı olabileceği çok sayıda alan vardır. 

  1. Kişisel Temsilcis: Elektronik cihazlarınızda Jarvis benzeri asistanınızın olduğunu, komutlarınız dahilindeki görevlerde metin, ses ve hatta bir hareketle size yardım etmeye hazır olduğunu hayal edin. Yapay zeka ajanlarının en heyecan verici kullanımlarından biri bu!
  2. Yapay Zeka Eğitmenleri: Sohbet robotları harikadır ancak onların da sınırları vardır. Doğru araçlarla donatılmış yapay zeka temsilcileri, temel konuşmaların ötesine geçebilir. Öğretim yöntemlerini kullanıcı geri bildirimlerine göre uyarlayabilen sanal yapay zeka eğitmenleri oyunun kurallarını değiştirebilir.
  3. Yazılım Kullanıcı Deneyimi: Yazılımın kullanıcı deneyimi yapay zeka aracılarıyla iyileştirilebilir. Aracılar uygulamalarda manuel olarak gezinmek yerine görevleri sesli veya hareket komutlarıyla gerçekleştirebilir.
  4. Mekansal Hesaplama: AR/VR teknolojisinin popülaritesi arttıkça yapay zeka aracılarına olan talep de artacaktır. Aracılar çevredeki bilgileri işleyebilir ve talep üzerine görevleri yürütebilir. Bu, kısa süre içinde AI ajanlarının en iyi kullanım durumlarından biri olabilir.
  5. Yüksek Lisans İşletim Sistemi: Temsilcilerin birinci sınıf vatandaşlar olduğu yapay zeka öncelikli işletim sistemleri. Temsilciler sıradan ve karmaşık görevleri yapmaktan sorumlu olacak.

Sonuç

LangGraph, döngüsel durum bilgisi olan çok aktörlü etmen sistemleri oluşturmak için etkili bir çerçevedir. Orijinal LangChain çerçevesindeki boşluğu doldurur. LangChain'in bir uzantısı olduğu için LangChain ekosisteminin tüm güzel yanlarından faydalanabiliyoruz. LLM'lerin kalitesi ve kapasitesi arttıkça, karmaşık iş akışlarını otomatikleştirmek için aracı sistemler oluşturmak çok daha kolay olacaktır. İşte makaleden önemli çıkarımlar. 

Önemli Noktalar

  • LangGraph, döngüsel, durum bilgisi olan, çok aktörlü etmen sistemleri oluşturmamıza olanak sağlayan LangChain'in bir uzantısıdır.
  • Düğümler ve kenarlar içeren bir grafik yapısı uygular. Düğümler işlevler veya araçlardır ve kenarlar, düğümler arasındaki bağlantılardır.
  • Kenarlar iki türdür: koşullu ve normal. Koşullu kenarların birinden diğerine giderken koşulları vardır ve bu, iş akışına döngüsellik kazandırmak açısından önemlidir.
  • Döngüsel çok aktörlü etmenler oluşturmak için LangGraph tercih edilirken, LangChain zincirler veya yönlendirilmiş döngüsel olmayan sistemler oluşturmada daha iyidir.

Sık Sorulan Sorular

S1. LangGraph nedir?

Cevap. LangGraph, durum bilgisi olan döngüsel çok aktörlü etmen sistemleri oluşturmaya yönelik açık kaynaklı bir kütüphanedir. LangChain ekosisteminin üzerine inşa edilmiştir.

Q2. LangChain üzerinden LangGraph ne zaman kullanılır?

Cevap. Döngüsel çok aktörlü etmenler oluşturmak için LangGraph tercih edilirken, LangChain zincirler veya yönlendirilmiş döngüsel olmayan sistemler oluşturmada daha iyidir.

S3. Yapay zeka ajanı nedir?

Cevap. Yapay zeka aracıları, çevreleriyle etkileşime giren, kararlar veren ve nihai bir hedefe ulaşmak için harekete geçen yazılım programlarıdır.

S4. Yapay zeka aracılarıyla kullanılabilecek en iyi LLM hangisidir?

Cevap. Bu, kullanım durumlarınıza ve bütçenize bağlıdır. GPT 4 en yetenekli fakat pahalı olanıdır. Kodlama için DeepSeekCoder-33b çok daha ucuz bir seçenektir. 

S5. Zincirler ve acenteler arasındaki fark nedir?

Cevap. Zincirler, takip edilmesi gereken bir dizi sabit kodlanmış eylemden oluşurken, aracılar bilgiye göre akıl yürütmek ve hareket etmek için LLM'leri ve diğer araçları (ayrıca zincirleri) kullanırlar.

Bu makalede gösterilen medya Analytics Vidhya'ya ait değildir ve Yazarın takdirine bağlı olarak kullanılır.

spot_img

En Son İstihbarat

spot_img