Στον πυρήνα του, LangChain είναι ένα καινοτόμο πλαίσιο προσαρμοσμένο για τη δημιουργία εφαρμογών που αξιοποιούν τις δυνατότητες των γλωσσικών μοντέλων. Είναι μια εργαλειοθήκη που έχει σχεδιαστεί για προγραμματιστές για τη δημιουργία εφαρμογών που έχουν επίγνωση του πλαισίου και μπορούν να συλλογιστούν πολύπλοκα.
Αυτό σημαίνει ότι οι εφαρμογές LangChain μπορούν να κατανοήσουν το πλαίσιο, όπως γρήγορες οδηγίες ή αποκρίσεις γείωσης περιεχομένου και να χρησιμοποιούν γλωσσικά μοντέλα για πολύπλοκες συλλογιστικές εργασίες, όπως να αποφασίσουν πώς να απαντήσουν ή ποιες ενέργειες θα κάνουν. Το LangChain αντιπροσωπεύει μια ενοποιημένη προσέγγιση για την ανάπτυξη έξυπνων εφαρμογών, απλοποιώντας το ταξίδι από την ιδέα στην εκτέλεση με τα διάφορα στοιχεία του.
Κατανόηση του LangChain
Το LangChain είναι πολύ περισσότερα από ένα απλό πλαίσιο. είναι ένα πλήρες οικοσύστημα που περιλαμβάνει πολλά αναπόσπαστα μέρη.
- Πρώτον, υπάρχουν οι Βιβλιοθήκες LangChain, διαθέσιμες τόσο σε Python όσο και σε JavaScript. Αυτές οι βιβλιοθήκες αποτελούν τη ραχοκοκαλιά του LangChain, προσφέροντας διεπαφές και ενσωματώσεις για διάφορα στοιχεία. Παρέχουν έναν βασικό χρόνο εκτέλεσης για το συνδυασμό αυτών των στοιχείων σε συνεκτικές αλυσίδες και πράκτορες, μαζί με έτοιμες υλοποιήσεις για άμεση χρήση.
- Στη συνέχεια, έχουμε Πρότυπα LangChain. Αυτές είναι μια συλλογή από αναπτυσσόμενες αρχιτεκτονικές αναφοράς προσαρμοσμένες για ένα ευρύ φάσμα εργασιών. Είτε δημιουργείτε ένα chatbot είτε ένα σύνθετο αναλυτικό εργαλείο, αυτά τα πρότυπα προσφέρουν ένα σταθερό σημείο εκκίνησης.
- Το LangServe λειτουργεί ως μια ευέλικτη βιβλιοθήκη για την ανάπτυξη αλυσίδων LangChain ως REST API. Αυτό το εργαλείο είναι απαραίτητο για τη μετατροπή των έργων LangChain σε προσβάσιμες και επεκτάσιμες υπηρεσίες web.
- Τέλος, ο LangSmith χρησιμεύει ως πλατφόρμα προγραμματιστών. Έχει σχεδιαστεί για εντοπισμό σφαλμάτων, δοκιμή, αξιολόγηση και παρακολούθηση αλυσίδων που έχουν δημιουργηθεί σε οποιοδήποτε πλαίσιο LLM. Η απρόσκοπτη ενσωμάτωση με το LangChain το καθιστά απαραίτητο εργαλείο για προγραμματιστές που στοχεύουν να βελτιώσουν και να τελειοποιήσουν τις εφαρμογές τους.
Μαζί, αυτά τα στοιχεία σάς δίνουν τη δυνατότητα να αναπτύσσετε, να παράγετε και να αναπτύσσετε εφαρμογές με ευκολία. Με το LangChain, ξεκινάτε γράφοντας τις εφαρμογές σας χρησιμοποιώντας τις βιβλιοθήκες, αναφέροντας πρότυπα για καθοδήγηση. Στη συνέχεια, ο LangSmith σας βοηθά στην επιθεώρηση, τη δοκιμή και την παρακολούθηση των αλυσίδων σας, διασφαλίζοντας ότι οι εφαρμογές σας βελτιώνονται συνεχώς και είναι έτοιμες για ανάπτυξη. Τέλος, με το LangServe, μπορείτε εύκολα να μετατρέψετε οποιαδήποτε αλυσίδα σε API, κάνοντας την ανάπτυξη παιχνιδάκι.
Στις επόμενες ενότητες, θα εμβαθύνουμε στο πώς να ρυθμίσετε το LangChain και να ξεκινήσετε το ταξίδι σας στη δημιουργία έξυπνων εφαρμογών που υποστηρίζονται από γλωσσικά μοντέλα.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
Εγκατάσταση και ρύθμιση
Είστε έτοιμοι να βουτήξετε στον κόσμο του LangChain; Η ρύθμιση του είναι απλή και αυτός ο οδηγός θα σας καθοδηγήσει στη διαδικασία βήμα προς βήμα.
Το πρώτο βήμα στο ταξίδι σας στο LangChain είναι να το εγκαταστήσετε. Μπορείτε να το κάνετε αυτό εύκολα χρησιμοποιώντας pip ή conda. Εκτελέστε την ακόλουθη εντολή στο τερματικό σας:
pip install langchain
Για όσους προτιμούν τις πιο πρόσφατες δυνατότητες και αισθάνονται άνετα με λίγο περισσότερη περιπέτεια, μπορείτε να εγκαταστήσετε το LangChain απευθείας από την πηγή. Κλωνοποιήστε το αποθετήριο και μεταβείτε στο langchain/libs/langchain
Ευρετήριο. Στη συνέχεια, τρέξτε:
pip install -e .
Για πειραματικές λειτουργίες, εξετάστε το ενδεχόμενο εγκατάστασης langchain-experimental
. Είναι ένα πακέτο που περιέχει κώδικα αιχμής και προορίζεται για ερευνητικούς και πειραματικούς σκοπούς. Εγκαταστήστε το χρησιμοποιώντας:
pip install langchain-experimental
Το LangChain CLI είναι ένα εύχρηστο εργαλείο για εργασία με πρότυπα LangChain και έργα LangServe. Για να εγκαταστήσετε το LangChain CLI, χρησιμοποιήστε:
pip install langchain-cli
Το LangServe είναι απαραίτητο για την ανάπτυξη των αλυσίδων LangChain ως REST API. Εγκαθίσταται παράλληλα με το LangChain CLI.
Το LangChain απαιτεί συχνά ενσωματώσεις με παρόχους μοντέλων, καταστήματα δεδομένων, API κ.λπ. Για αυτό το παράδειγμα, θα χρησιμοποιήσουμε τα μοντέλα API του OpenAI. Εγκαταστήστε το πακέτο OpenAI Python χρησιμοποιώντας:
pip install openai
Για πρόσβαση στο API, ορίστε το κλειδί OpenAI API ως μεταβλητή περιβάλλοντος:
export OPENAI_API_KEY="your_api_key"
Εναλλακτικά, περάστε το κλειδί απευθείας στο περιβάλλον python σας:
import os
os.environ['OPENAI_API_KEY'] = 'your_api_key'
Το LangChain επιτρέπει τη δημιουργία εφαρμογών γλωσσικών μοντέλων μέσω ενοτήτων. Αυτές οι μονάδες μπορούν είτε να είναι μόνες τους είτε να δημιουργηθούν για σύνθετες περιπτώσεις χρήσης. Αυτές οι ενότητες είναι -
- Μοντέλο I/O: Διευκολύνει την αλληλεπίδραση με διάφορα γλωσσικά μοντέλα, χειριζόμενη αποτελεσματικά τις εισόδους και τις εξόδους τους.
- Ανάκτηση: Επιτρέπει την πρόσβαση και την αλληλεπίδραση με δεδομένα για συγκεκριμένες εφαρμογές, ζωτικής σημασίας για τη δυναμική χρήση δεδομένων.
- Πράκτορες: Ενισχύστε τις εφαρμογές να επιλέγουν κατάλληλα εργαλεία με βάση οδηγίες υψηλού επιπέδου, ενισχύοντας τις δυνατότητες λήψης αποφάσεων.
- Αλυσίδες: Προσφέρει προκαθορισμένες, επαναχρησιμοποιήσιμες συνθέσεις που χρησιμεύουν ως δομικά στοιχεία για την ανάπτυξη εφαρμογών.
- Μνήμη: Διατηρεί την κατάσταση εφαρμογής σε πολλαπλές εκτελέσεις αλυσίδων, απαραίτητη για αλληλεπιδράσεις με επίγνωση του περιβάλλοντος.
Κάθε ενότητα στοχεύει συγκεκριμένες ανάγκες ανάπτυξης, καθιστώντας το LangChain μια ολοκληρωμένη εργαλειοθήκη για τη δημιουργία προηγμένων εφαρμογών μοντέλων γλώσσας.
Μαζί με τα παραπάνω εξαρτήματα έχουμε και Γλώσσα έκφρασης LangChain (LCEL), ο οποίος είναι ένας δηλωτικός τρόπος για να συνθέσετε εύκολα ενότητες μαζί και αυτό επιτρέπει την αλυσίδα των στοιχείων χρησιμοποιώντας μια καθολική διεπαφή Runnable.
Το LCEL μοιάζει κάπως έτσι -
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import BaseOutputParser # Example chain
chain = ChatPromptTemplate() | ChatOpenAI() | CustomOutputParser()
Τώρα που καλύψαμε τα βασικά, θα συνεχίσουμε:
- Σκάψτε πιο βαθιά σε κάθε ενότητα Langchain λεπτομερώς.
- Μάθετε πώς να χρησιμοποιείτε τη γλώσσα έκφρασης LangChain.
- Εξερευνήστε περιπτώσεις κοινής χρήσης και εφαρμόστε τις.
- Αναπτύξτε μια εφαρμογή από άκρο σε άκρο με το LangServe.
- Ελέγξτε το LangSmith για εντοπισμό σφαλμάτων, δοκιμές και παρακολούθηση.
Ας ξεκινήσουμε!
Ενότητα I : Μοντέλο I/O
Στο LangChain, το βασικό στοιχείο κάθε εφαρμογής περιστρέφεται γύρω από το γλωσσικό μοντέλο. Αυτή η ενότητα παρέχει τα βασικά δομικά στοιχεία για την αποτελεσματική διασύνδεση με οποιοδήποτε μοντέλο γλώσσας, διασφαλίζοντας απρόσκοπτη ενοποίηση και επικοινωνία.
Βασικά στοιχεία του μοντέλου I/O
- LLM και μοντέλα συνομιλίας (χρησιμοποιούνται εναλλακτικά):
- LLMs:
- Ορισμός: Μοντέλα συμπλήρωσης καθαρού κειμένου.
- Εισόδου-εξόδου: Πάρτε μια συμβολοσειρά κειμένου ως είσοδο και επιστρέψτε μια συμβολοσειρά κειμένου ως έξοδο.
- Μοντέλα συνομιλίας
- LLMs:
- Ορισμός: Μοντέλα που χρησιμοποιούν ένα μοντέλο γλώσσας ως βάση αλλά διαφέρουν σε μορφές εισόδου και εξόδου.
- Εισόδου-εξόδου: Αποδεχτείτε μια λίστα με μηνύματα συνομιλίας ως είσοδο και επιστρέψτε ένα μήνυμα συνομιλίας.
- Προτρέπει: Δημιουργία προτύπων, δυναμική επιλογή και διαχείριση εισόδων μοντέλου. Επιτρέπει τη δημιουργία ευέλικτων και ειδικών για το περιβάλλον προτροπών που καθοδηγούν τις απαντήσεις του γλωσσικού μοντέλου.
- Αναλυτές εξόδου: Εξαγωγή και μορφοποίηση πληροφοριών από τις εξόδους του μοντέλου. Χρήσιμο για τη μετατροπή της ακατέργαστης παραγωγής μοντέλων γλώσσας σε δομημένα δεδομένα ή συγκεκριμένες μορφές που απαιτούνται από την εφαρμογή.
LLMs
Η ενσωμάτωση του LangChain με μοντέλα μεγάλων γλωσσών (LLM) όπως το OpenAI, το Cohere και το Hugging Face είναι μια θεμελιώδης πτυχή της λειτουργικότητάς του. Το ίδιο το LangChain δεν φιλοξενεί LLM αλλά προσφέρει μια ομοιόμορφη διεπαφή για αλληλεπίδραση με διάφορα LLM.
Αυτή η ενότητα παρέχει μια επισκόπηση της χρήσης του περιτυλίγματος OpenAI LLM στο LangChain, που ισχύει και για άλλους τύπους LLM. Το έχουμε ήδη εγκαταστήσει στην ενότητα "Ξεκινώντας". Ας αρχικοποιήσουμε το LLM.
from langchain.llms import OpenAI
llm = OpenAI()
- Τα LLM εφαρμόζουν το Διεπαφή με δυνατότητα εκτέλεσης, το βασικό οικοδομικό τετράγωνο του Γλώσσα έκφρασης LangChain (LCEL). Αυτό σημαίνει ότι υποστηρίζουν
invoke
,ainvoke
,stream
,astream
,batch
,abatch
,astream_log
κλήσεις. - Τα LLM δέχονται χορδές ως είσοδοι ή αντικείμενα που μπορούν να εξαναγκαστούν σε προτροπές συμβολοσειρών, συμπεριλαμβανομένων
List[BaseMessage]
καιPromptValue
. (περισσότερα για αυτά αργότερα)
Ας δούμε μερικά παραδείγματα.
response = llm.invoke("List the seven wonders of the world.")
print(response)
Μπορείτε εναλλακτικά να καλέσετε τη μέθοδο ροής για ροή της απάντησης κειμένου.
for chunk in llm.stream("Where were the 2012 Olympics held?"): print(chunk, end="", flush=True)
Μοντέλα συνομιλίας
Η ενοποίηση του LangChain με μοντέλα συνομιλίας, μια εξειδικευμένη παραλλαγή μοντέλων γλώσσας, είναι απαραίτητη για τη δημιουργία διαδραστικών εφαρμογών συνομιλίας. Ενώ χρησιμοποιούν εσωτερικά μοντέλα γλώσσας, τα μοντέλα συνομιλίας παρουσιάζουν μια ξεχωριστή διεπαφή που επικεντρώνεται γύρω από τα μηνύματα συνομιλίας ως εισόδους και εξόδους. Αυτή η ενότητα παρέχει μια λεπτομερή επισκόπηση της χρήσης του μοντέλου συνομιλίας του OpenAI στο LangChain.
from langchain.chat_models import ChatOpenAI
chat = ChatOpenAI()
Τα μοντέλα συνομιλίας στο LangChain λειτουργούν με διαφορετικούς τύπους μηνυμάτων, όπως π.χ AIMessage
, HumanMessage
, SystemMessage
, FunctionMessage
, να ChatMessage
(με μια αυθαίρετη παράμετρο ρόλου). Γενικά, HumanMessage
, AIMessage
, να SystemMessage
είναι τα πιο συχνά χρησιμοποιούμενα.
Τα μοντέλα συνομιλίας δέχονται κυρίως List[BaseMessage]
ως εισροές. Οι συμβολοσειρές μπορούν να μετατραπούν σε HumanMessage
, να PromptValue
υποστηρίζεται επίσης.
from langchain.schema.messages import HumanMessage, SystemMessage
messages = [ SystemMessage(content="You are Micheal Jordan."), HumanMessage(content="Which shoe manufacturer are you associated with?"),
]
response = chat.invoke(messages)
print(response.content)
Προτρέπει
Οι προτροπές είναι ουσιαστικές για την καθοδήγηση γλωσσικών μοντέλων για τη δημιουργία συναφών και συνεκτικών αποτελεσμάτων. Μπορούν να κυμαίνονται από απλές οδηγίες έως πολύπλοκα παραδείγματα λίγων λήψεων. Στο LangChain, ο χειρισμός των προτροπών μπορεί να είναι μια πολύ βελτιωμένη διαδικασία, χάρη σε πολλές αποκλειστικές κλάσεις και λειτουργίες.
του LangChain PromptTemplate
Η class είναι ένα ευέλικτο εργαλείο για τη δημιουργία προτροπών συμβολοσειρών. Χρησιμοποιεί Python's str.format
σύνταξη, επιτρέποντας τη δυναμική δημιουργία προτροπών. Μπορείτε να ορίσετε ένα πρότυπο με σύμβολα κράτησης θέσης και να τα συμπληρώσετε με συγκεκριμένες τιμές, όπως απαιτείται.
from langchain.prompts import PromptTemplate # Simple prompt with placeholders
prompt_template = PromptTemplate.from_template( "Tell me a {adjective} joke about {content}."
) # Filling placeholders to create a prompt
filled_prompt = prompt_template.format(adjective="funny", content="robots")
print(filled_prompt)
Για μοντέλα συνομιλίας, τα μηνύματα προτροπής είναι πιο δομημένα και περιλαμβάνουν μηνύματα με συγκεκριμένους ρόλους. Προσφορές LangChain ChatPromptTemplate
για αυτό το σκοπό.
from langchain.prompts import ChatPromptTemplate # Defining a chat prompt with various roles
chat_template = ChatPromptTemplate.from_messages( [ ("system", "You are a helpful AI bot. Your name is {name}."), ("human", "Hello, how are you doing?"), ("ai", "I'm doing well, thanks!"), ("human", "{user_input}"), ]
) # Formatting the chat prompt
formatted_messages = chat_template.format_messages(name="Bob", user_input="What is your name?")
for message in formatted_messages: print(message)
Αυτή η προσέγγιση επιτρέπει τη δημιουργία διαδραστικών, ελκυστικών chatbots με δυναμικές αποκρίσεις.
Και τα δύο PromptTemplate
και ChatPromptTemplate
ενσωματώνονται απρόσκοπτα με τη γλώσσα έκφρασης LangChain (LCEL), δίνοντάς τους τη δυνατότητα να αποτελούν μέρος μεγαλύτερων, πολύπλοκων ροών εργασίας. Θα συζητήσουμε περισσότερα για αυτό αργότερα.
Τα προσαρμοσμένα πρότυπα προτροπών είναι μερικές φορές απαραίτητα για εργασίες που απαιτούν μοναδική μορφοποίηση ή συγκεκριμένες οδηγίες. Η δημιουργία ενός προσαρμοσμένου προτύπου προτροπής περιλαμβάνει τον καθορισμό μεταβλητών εισόδου και μια προσαρμοσμένη μέθοδο μορφοποίησης. Αυτή η ευελιξία επιτρέπει στο LangChain να καλύψει ένα ευρύ φάσμα απαιτήσεων για συγκεκριμένες εφαρμογές. Διαβάστε περισσότερα εδώ.
Το LangChain υποστηρίζει επίσης την προτροπή για λίγες λήψεις, επιτρέποντας στο μοντέλο να μαθαίνει από παραδείγματα. Αυτή η δυνατότητα είναι ζωτικής σημασίας για εργασίες που απαιτούν κατανόηση από τα συμφραζόμενα ή συγκεκριμένα μοτίβα. Μπορούν να δημιουργηθούν πρότυπα προτροπών για λίγα στιγμιότυπα από ένα σύνολο παραδειγμάτων ή χρησιμοποιώντας ένα αντικείμενο Επιλογέα παραδείγματος. Διαβάστε περισσότερα εδώ.
Αναλυτές εξόδου
Οι αναλυτές εξόδου διαδραματίζουν κρίσιμο ρόλο στο Langchain, επιτρέποντας στους χρήστες να δομούν τις απαντήσεις που δημιουργούνται από τα γλωσσικά μοντέλα. Σε αυτήν την ενότητα, θα εξερευνήσουμε την έννοια των αναλυτών εξόδου και θα παρέχουμε παραδείγματα κώδικα χρησιμοποιώντας τα PydanticOutputParser, SimpleJsonOutputParser, CommaSeparatedListOutputParser, DatetimeOutputParser και XMLOutputParser της Langchain.
PydanticOutputParser
Η Langchain παρέχει το PydanticOutputParser για την ανάλυση των απαντήσεων σε δομές δεδομένων Pydantic. Παρακάτω είναι ένα βήμα προς βήμα παράδειγμα για το πώς να το χρησιμοποιήσετε:
from typing import List
from langchain.llms import OpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.pydantic_v1 import BaseModel, Field, validator # Initialize the language model
model = OpenAI(model_name="text-davinci-003", temperature=0.0) # Define your desired data structure using Pydantic
class Joke(BaseModel): setup: str = Field(description="question to set up a joke") punchline: str = Field(description="answer to resolve the joke") @validator("setup") def question_ends_with_question_mark(cls, field): if field[-1] != "?": raise ValueError("Badly formed question!") return field # Set up a PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=Joke) # Create a prompt with format instructions
prompt = PromptTemplate( template="Answer the user query.n{format_instructions}n{query}n", input_variables=["query"], partial_variables={"format_instructions": parser.get_format_instructions()},
) # Define a query to prompt the language model
query = "Tell me a joke." # Combine prompt, model, and parser to get structured output
prompt_and_model = prompt | model
output = prompt_and_model.invoke({"query": query}) # Parse the output using the parser
parsed_result = parser.invoke(output) # The result is a structured object
print(parsed_result)
Η έξοδος θα είναι:
SimpleJsonOutputParser
Το SimpleJsonOutputParser της Langchain χρησιμοποιείται όταν θέλετε να αναλύσετε εξόδους τύπου JSON. Εδώ είναι ένα παράδειγμα:
from langchain.output_parsers.json import SimpleJsonOutputParser # Create a JSON prompt
json_prompt = PromptTemplate.from_template( "Return a JSON object with `birthdate` and `birthplace` key that answers the following question: {question}"
) # Initialize the JSON parser
json_parser = SimpleJsonOutputParser() # Create a chain with the prompt, model, and parser
json_chain = json_prompt | model | json_parser # Stream through the results
result_list = list(json_chain.stream({"question": "When and where was Elon Musk born?"})) # The result is a list of JSON-like dictionaries
print(result_list)
CommaSeparatedListOutputParser
Το CommaSeparatedListOutputParser είναι βολικό όταν θέλετε να εξαγάγετε λίστες διαχωρισμένες με κόμμα από απαντήσεις μοντέλων. Εδώ είναι ένα παράδειγμα:
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI # Initialize the parser
output_parser = CommaSeparatedListOutputParser() # Create format instructions
format_instructions = output_parser.get_format_instructions() # Create a prompt to request a list
prompt = PromptTemplate( template="List five {subject}.n{format_instructions}", input_variables=["subject"], partial_variables={"format_instructions": format_instructions}
) # Define a query to prompt the model
query = "English Premier League Teams" # Generate the output
output = model(prompt.format(subject=query)) # Parse the output using the parser
parsed_result = output_parser.parse(output) # The result is a list of items
print(parsed_result)
DatetimeOutputParser
Το DatetimeOutputParser της Langchain έχει σχεδιαστεί για να αναλύει πληροφορίες ημερομηνίας. Δείτε πώς να το χρησιμοποιήσετε:
from langchain.prompts import PromptTemplate
from langchain.output_parsers import DatetimeOutputParser
from langchain.chains import LLMChain
from langchain.llms import OpenAI # Initialize the DatetimeOutputParser
output_parser = DatetimeOutputParser() # Create a prompt with format instructions
template = """
Answer the user's question:
{question}
{format_instructions} """ prompt = PromptTemplate.from_template( template, partial_variables={"format_instructions": output_parser.get_format_instructions()},
) # Create a chain with the prompt and language model
chain = LLMChain(prompt=prompt, llm=OpenAI()) # Define a query to prompt the model
query = "when did Neil Armstrong land on the moon in terms of GMT?" # Run the chain
output = chain.run(query) # Parse the output using the datetime parser
parsed_result = output_parser.parse(output) # The result is a datetime object
print(parsed_result)
Αυτά τα παραδείγματα δείχνουν πώς οι αναλυτές εξόδου της Langchain μπορούν να χρησιμοποιηθούν για τη δομή διαφόρων τύπων αποκρίσεων μοντέλων, καθιστώντας τα κατάλληλα για διαφορετικές εφαρμογές και μορφές. Οι αναλυτές εξόδου είναι ένα πολύτιμο εργαλείο για τη βελτίωση της χρηστικότητας και της ερμηνείας των εξόδων γλωσσικών μοντέλων στο Langchain.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
Ενότητα II : Ανάκτηση
Η ανάκτηση στο LangChain διαδραματίζει κρίσιμο ρόλο σε εφαρμογές που απαιτούν δεδομένα ειδικά για τον χρήστη, τα οποία δεν περιλαμβάνονται στο εκπαιδευτικό σετ του μοντέλου. Αυτή η διαδικασία, γνωστή ως Retrieval Augmented Generation (RAG), περιλαμβάνει την ανάκτηση εξωτερικών δεδομένων και την ενσωμάτωσή τους στη διαδικασία δημιουργίας του γλωσσικού μοντέλου. Το LangChain παρέχει μια ολοκληρωμένη σειρά εργαλείων και λειτουργιών για τη διευκόλυνση αυτής της διαδικασίας, καλύπτοντας τόσο απλές όσο και σύνθετες εφαρμογές.
Το LangChain επιτυγχάνει την ανάκτηση μέσω μιας σειράς στοιχείων τα οποία θα συζητήσουμε ένα προς ένα.
Φορτωτές εγγράφων
Οι φορτωτές εγγράφων στο LangChain επιτρέπουν την εξαγωγή δεδομένων από διάφορες πηγές. Με περισσότερους από 100 διαθέσιμους φορτωτές, υποστηρίζουν μια σειρά τύπων εγγράφων, εφαρμογών και πηγών (ιδιωτικοί κάδοι s3, δημόσιοι ιστότοποι, βάσεις δεδομένων).
Μπορείτε να επιλέξετε ένα πρόγραμμα φόρτωσης εγγράφων με βάση τις απαιτήσεις σας εδώ.
Όλοι αυτοί οι φορτωτές απορροφούν δεδομένα Έγγραφο τάξεις. Θα μάθουμε πώς να χρησιμοποιούμε τα δεδομένα που λαμβάνονται στις τάξεις Document αργότερα.
Πρόγραμμα φόρτωσης αρχείων κειμένου: Φορτώστε ένα απλό .txt
αρχείο σε ένα έγγραφο.
from langchain.document_loaders import TextLoader loader = TextLoader("./sample.txt")
document = loader.load()
CSV Loader: Φορτώστε ένα αρχείο CSV σε ένα έγγραφο.
from langchain.document_loaders.csv_loader import CSVLoader loader = CSVLoader(file_path='./example_data/sample.csv')
documents = loader.load()
Μπορούμε να επιλέξουμε να προσαρμόσουμε την ανάλυση καθορίζοντας ονόματα πεδίων –
loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv', csv_args={ 'delimiter': ',', 'quotechar': '"', 'fieldnames': ['MLB Team', 'Payroll in millions', 'Wins']
})
documents = loader.load()
Φορτωτές PDF: Τα PDF Loaders στο LangChain προσφέρουν διάφορες μεθόδους ανάλυσης και εξαγωγής περιεχομένου από αρχεία PDF. Κάθε loader ικανοποιεί διαφορετικές απαιτήσεις και χρησιμοποιεί διαφορετικές υποκείμενες βιβλιοθήκες. Ακολουθούν αναλυτικά παραδείγματα για κάθε φορτωτή.
Το PyPDFLoader χρησιμοποιείται για βασική ανάλυση PDF.
from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("example_data/layout-parser-paper.pdf")
pages = loader.load_and_split()
Το MathPixLoader είναι ιδανικό για εξαγωγή μαθηματικού περιεχομένου και διαγραμμάτων.
from langchain.document_loaders import MathpixPDFLoader loader = MathpixPDFLoader("example_data/math-content.pdf")
data = loader.load()
Το PyMuPDFLoader είναι γρήγορο και περιλαμβάνει λεπτομερή εξαγωγή μεταδεδομένων.
from langchain.document_loaders import PyMuPDFLoader loader = PyMuPDFLoader("example_data/layout-parser-paper.pdf")
data = loader.load() # Optionally pass additional arguments for PyMuPDF's get_text() call
data = loader.load(option="text")
Το PDFMiner Loader χρησιμοποιείται για πιο λεπτομερή έλεγχο της εξαγωγής κειμένου.
from langchain.document_loaders import PDFMinerLoader loader = PDFMinerLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
Το AmazonTextractPDFParser χρησιμοποιεί το AWS Textract για OCR και άλλες προηγμένες δυνατότητες ανάλυσης PDF.
from langchain.document_loaders import AmazonTextractPDFLoader # Requires AWS account and configuration
loader = AmazonTextractPDFLoader("example_data/complex-layout.pdf")
documents = loader.load()
Το PDFMinerPDFasHTMLLoader δημιουργεί HTML από PDF για σημασιολογική ανάλυση.
from langchain.document_loaders import PDFMinerPDFasHTMLLoader loader = PDFMinerPDFasHTMLLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
Το PDFPlumberLoader παρέχει λεπτομερή μεταδεδομένα και υποστηρίζει ένα έγγραφο ανά σελίδα.
from langchain.document_loaders import PDFPlumberLoader loader = PDFPlumberLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
Ενσωματωμένοι φορτωτές: Το LangChain προσφέρει μια μεγάλη ποικιλία προσαρμοσμένων φορτωτών για άμεση φόρτωση δεδομένων από τις εφαρμογές σας (όπως Slack, Sigma, Notion, Confluence, Google Drive και πολλά άλλα) και βάσεις δεδομένων και χρήση τους σε εφαρμογές LLM.
Η πλήρης λίστα είναι εδώ.
Παρακάτω είναι μερικά παραδείγματα για να το καταδείξετε αυτό -
Παράδειγμα I – Slack
Το Slack, μια ευρέως χρησιμοποιούμενη πλατφόρμα ανταλλαγής άμεσων μηνυμάτων, μπορεί να ενσωματωθεί σε ροές εργασίας και εφαρμογές LLM.
- Μεταβείτε στη σελίδα σας Slack Workspace Management.
- Πλοηγηθείτε στο
{your_slack_domain}.slack.com/services/export
. - Επιλέξτε το επιθυμητό εύρος ημερομηνιών και ξεκινήστε την εξαγωγή.
- Το Slack ειδοποιεί μέσω email και DM μόλις η εξαγωγή είναι έτοιμη.
- Η εξαγωγή έχει ως αποτέλεσμα α
.zip
αρχείο που βρίσκεται στο φάκελο Λήψεις ή στην καθορισμένη διαδρομή λήψης. - Εκχωρήστε τη διαδρομή της λήψης
.zip
αρχείο στοLOCAL_ZIPFILE
. - Χρησιμοποιήστε το
SlackDirectoryLoader
από τοlangchain.document_loaders
πακέτο.
from langchain.document_loaders import SlackDirectoryLoader SLACK_WORKSPACE_URL = "https://xxx.slack.com" # Replace with your Slack URL
LOCAL_ZIPFILE = "" # Path to the Slack zip file loader = SlackDirectoryLoader(LOCAL_ZIPFILE, SLACK_WORKSPACE_URL)
docs = loader.load()
print(docs)
Παράδειγμα II – Figma
Το Figma, ένα δημοφιλές εργαλείο για το σχεδιασμό διεπαφής, προσφέρει ένα REST API για ενοποίηση δεδομένων.
- Λάβετε το κλειδί αρχείου Figma από τη μορφή URL:
https://www.figma.com/file/{filekey}/sampleFilename
. - Τα αναγνωριστικά κόμβων βρίσκονται στην παράμετρο URL
?node-id={node_id}
. - Δημιουργήστε ένα διακριτικό πρόσβασης ακολουθώντας τις οδηγίες στο Κέντρο βοήθειας Figma.
- Η
FigmaFileLoader
τάξη απόlangchain.document_loaders.figma
χρησιμοποιείται για τη φόρτωση δεδομένων Figma. - Διάφορες ενότητες LangChain όπως
CharacterTextSplitter
,ChatOpenAI
κ.λπ., χρησιμοποιούνται για επεξεργασία.
import os
from langchain.document_loaders.figma import FigmaFileLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.indexes import VectorstoreIndexCreator
from langchain.chains import ConversationChain, LLMChain
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts.chat import ChatPromptTemplate, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate figma_loader = FigmaFileLoader( os.environ.get("ACCESS_TOKEN"), os.environ.get("NODE_IDS"), os.environ.get("FILE_KEY"),
) index = VectorstoreIndexCreator().from_loaders([figma_loader])
figma_doc_retriever = index.vectorstore.as_retriever()
- Η
generate_code
Η συνάρτηση χρησιμοποιεί τα δεδομένα Figma για τη δημιουργία κώδικα HTML/CSS. - Χρησιμοποιεί μια συνομιλία με πρότυπο με ένα μοντέλο που βασίζεται σε GPT.
def generate_code(human_input): # Template for system and human prompts system_prompt_template = "Your coding instructions..." human_prompt_template = "Code the {text}. Ensure it's mobile responsive" # Creating prompt templates system_message_prompt = SystemMessagePromptTemplate.from_template(system_prompt_template) human_message_prompt = HumanMessagePromptTemplate.from_template(human_prompt_template) # Setting up the AI model gpt_4 = ChatOpenAI(temperature=0.02, model_name="gpt-4") # Retrieving relevant documents relevant_nodes = figma_doc_retriever.get_relevant_documents(human_input) # Generating and formatting the prompt conversation = [system_message_prompt, human_message_prompt] chat_prompt = ChatPromptTemplate.from_messages(conversation) response = gpt_4(chat_prompt.format_prompt(context=relevant_nodes, text=human_input).to_messages()) return response # Example usage
response = generate_code("page top header")
print(response.content)
- Η
generate_code
Η συνάρτηση, όταν εκτελείται, επιστρέφει κώδικα HTML/CSS με βάση την είσοδο σχεδίασης Figma.
Ας χρησιμοποιήσουμε τώρα τις γνώσεις μας για να δημιουργήσουμε μερικά σύνολα εγγράφων.
Αρχικά φορτώνουμε ένα PDF, την ετήσια έκθεση βιωσιμότητας της BCG.
Χρησιμοποιούμε το PyPDFLoader για αυτό.
from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("bcg-2022-annual-sustainability-report-apr-2023.pdf")
pdfpages = loader.load_and_split()
Θα λαμβάνουμε δεδομένα από το Airtable τώρα. Έχουμε ένα Airtable που περιέχει πληροφορίες σχετικά με διάφορα μοντέλα OCR και εξαγωγής δεδομένων –
Ας χρησιμοποιήσουμε το AirtableLoader για αυτό, που βρίσκεται στη λίστα των ενσωματωμένων φορτωτών.
from langchain.document_loaders import AirtableLoader api_key = "XXXXX"
base_id = "XXXXX"
table_id = "XXXXX" loader = AirtableLoader(api_key, table_id, base_id)
airtabledocs = loader.load()
Ας προχωρήσουμε τώρα και ας μάθουμε πώς να χρησιμοποιούμε αυτές τις τάξεις εγγράφων.
Μετασχηματιστές εγγράφων
Οι μετασχηματιστές εγγράφων στο LangChain είναι απαραίτητα εργαλεία που έχουν σχεδιαστεί για τον χειρισμό εγγράφων, τα οποία δημιουργήσαμε στην προηγούμενη υποενότητά μας.
Χρησιμοποιούνται για εργασίες όπως ο χωρισμός μεγάλων εγγράφων σε μικρότερα κομμάτια, ο συνδυασμός και το φιλτράρισμα, τα οποία είναι ζωτικής σημασίας για την προσαρμογή των εγγράφων στο παράθυρο περιβάλλοντος ενός μοντέλου ή την κάλυψη συγκεκριμένων αναγκών εφαρμογής.
Ένα τέτοιο εργαλείο είναι το RecursiveCharacterTextSplitter, ένας ευέλικτος διαχωριστής κειμένου που χρησιμοποιεί μια λίστα χαρακτήρων για διαχωρισμό. Επιτρέπει παραμέτρους όπως το μέγεθος του κομματιού, την επικάλυψη και τον αρχικό δείκτη. Ακολουθεί ένα παράδειγμα του πώς χρησιμοποιείται στην Python:
from langchain.text_splitter import RecursiveCharacterTextSplitter state_of_the_union = "Your long text here..." text_splitter = RecursiveCharacterTextSplitter( chunk_size=100, chunk_overlap=20, length_function=len, add_start_index=True,
) texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
print(texts[1])
Ένα άλλο εργαλείο είναι το CharacterTextSplitter, το οποίο διαχωρίζει κείμενο με βάση έναν καθορισμένο χαρακτήρα και περιλαμβάνει στοιχεία ελέγχου για το μέγεθος και την επικάλυψη του κομματιού:
from langchain.text_splitter import CharacterTextSplitter text_splitter = CharacterTextSplitter( separator="nn", chunk_size=1000, chunk_overlap=200, length_function=len, is_separator_regex=False,
) texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
Το HTMLHeaderTextSplitter έχει σχεδιαστεί για να διαχωρίζει περιεχόμενο HTML με βάση ετικέτες κεφαλίδας, διατηρώντας τη σημασιολογική δομή:
from langchain.text_splitter import HTMLHeaderTextSplitter html_string = "Your HTML content here..."
headers_to_split_on = [("h1", "Header 1"), ("h2", "Header 2")] html_splitter = HTMLHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
html_header_splits = html_splitter.split_text(html_string)
print(html_header_splits[0])
Ένας πιο περίπλοκος χειρισμός μπορεί να επιτευχθεί συνδυάζοντας το HTMLHeaderTextSplitter με έναν άλλο διαχωριστή, όπως το Pipelined Splitter:
from langchain.text_splitter import HTMLHeaderTextSplitter, RecursiveCharacterTextSplitter url = "https://example.com"
headers_to_split_on = [("h1", "Header 1"), ("h2", "Header 2")]
html_splitter = HTMLHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
html_header_splits = html_splitter.split_text_from_url(url) chunk_size = 500
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size)
splits = text_splitter.split_documents(html_header_splits)
print(splits[0])
Το LangChain προσφέρει επίσης συγκεκριμένους διαχωριστές για διαφορετικές γλώσσες προγραμματισμού, όπως το Python Code Splitter και το JavaScript Code Splitter:
from langchain.text_splitter import RecursiveCharacterTextSplitter, Language python_code = """
def hello_world(): print("Hello, World!")
hello_world() """ python_splitter = RecursiveCharacterTextSplitter.from_language( language=Language.PYTHON, chunk_size=50
)
python_docs = python_splitter.create_documents([python_code])
print(python_docs[0]) js_code = """
function helloWorld() { console.log("Hello, World!");
}
helloWorld(); """ js_splitter = RecursiveCharacterTextSplitter.from_language( language=Language.JS, chunk_size=60
)
js_docs = js_splitter.create_documents([js_code])
print(js_docs[0])
Για τον διαχωρισμό κειμένου με βάση τον αριθμό διακριτικών, που είναι χρήσιμος για μοντέλα γλώσσας με όρια διακριτικών, χρησιμοποιείται το TokenTextSplitter:
from langchain.text_splitter import TokenTextSplitter text_splitter = TokenTextSplitter(chunk_size=10)
texts = text_splitter.split_text(state_of_the_union)
print(texts[0])
Τέλος, το LongContextReorder αναδιατάσσει τα έγγραφα για να αποτρέψει την υποβάθμιση της απόδοσης στα μοντέλα λόγω μεγάλων πλαισίων:
from langchain.document_transformers import LongContextReorder reordering = LongContextReorder()
reordered_docs = reordering.transform_documents(docs)
print(reordered_docs[0])
Αυτά τα εργαλεία επιδεικνύουν διάφορους τρόπους μετατροπής εγγράφων στο LangChain, από απλό διαχωρισμό κειμένου έως πολύπλοκη αναδιάταξη και διαχωρισμό για συγκεκριμένη γλώσσα. Για πιο εις βάθος και συγκεκριμένες περιπτώσεις χρήσης, θα πρέπει να συμβουλευτείτε την ενότητα τεκμηρίωση και ενσωματώσεις LangChain.
Στα παραδείγματά μας, οι φορτωτές έχουν ήδη δημιουργήσει τεμαχισμένα έγγραφα για εμάς και αυτό το τμήμα έχει ήδη χειριστεί.
Μοντέλα ενσωμάτωσης κειμένου
Τα μοντέλα ενσωμάτωσης κειμένου στο LangChain παρέχουν μια τυποποιημένη διεπαφή για διάφορους παρόχους μοντέλων ενσωμάτωσης όπως το OpenAI, το Cohere και το Hugging Face. Αυτά τα μοντέλα μετατρέπουν το κείμενο σε διανυσματικές αναπαραστάσεις, επιτρέποντας λειτουργίες όπως η σημασιολογική αναζήτηση μέσω της ομοιότητας κειμένου στον διανυσματικό χώρο.
Για να ξεκινήσετε με μοντέλα ενσωμάτωσης κειμένου, συνήθως πρέπει να εγκαταστήσετε συγκεκριμένα πακέτα και να ρυθμίσετε κλειδιά API. Το έχουμε κάνει ήδη για το OpenAI
Στο LangChain, το embed_documents
Η μέθοδος χρησιμοποιείται για την ενσωμάτωση πολλών κειμένων, παρέχοντας μια λίστα διανυσματικών αναπαραστάσεων. Για παράδειγμα:
from langchain.embeddings import OpenAIEmbeddings # Initialize the model
embeddings_model = OpenAIEmbeddings() # Embed a list of texts
embeddings = embeddings_model.embed_documents( ["Hi there!", "Oh, hello!", "What's your name?", "My friends call me World", "Hello World!"]
)
print("Number of documents embedded:", len(embeddings))
print("Dimension of each embedding:", len(embeddings[0]))
Για την ενσωμάτωση ενός μεμονωμένου κειμένου, όπως ένα ερώτημα αναζήτησης, το embed_query
χρησιμοποιείται μέθοδος. Αυτό είναι χρήσιμο για τη σύγκριση ενός ερωτήματος με ένα σύνολο ενσωματώσεων εγγράφων. Για παράδειγμα:
from langchain.embeddings import OpenAIEmbeddings # Initialize the model
embeddings_model = OpenAIEmbeddings() # Embed a single query
embedded_query = embeddings_model.embed_query("What was the name mentioned in the conversation?")
print("First five dimensions of the embedded query:", embedded_query[:5])
Η κατανόηση αυτών των ενσωματώσεων είναι ζωτικής σημασίας. Κάθε κομμάτι κειμένου μετατρέπεται σε διάνυσμα, η διάσταση του οποίου εξαρτάται από το μοντέλο που χρησιμοποιείται. Για παράδειγμα, τα μοντέλα OpenAI παράγουν συνήθως διανύσματα 1536 διαστάσεων. Αυτές οι ενσωματώσεις χρησιμοποιούνται στη συνέχεια για την ανάκτηση σχετικών πληροφοριών.
Η λειτουργικότητα ενσωμάτωσης του LangChain δεν περιορίζεται στο OpenAI αλλά έχει σχεδιαστεί για να συνεργάζεται με διάφορους παρόχους. Η ρύθμιση και η χρήση ενδέχεται να διαφέρουν ελαφρώς ανάλογα με τον πάροχο, αλλά η βασική ιδέα της ενσωμάτωσης κειμένων στον διανυσματικό χώρο παραμένει η ίδια. Για λεπτομερή χρήση, συμπεριλαμβανομένων προηγμένων διαμορφώσεων και ενσωματώσεων με διαφορετικούς παρόχους μοντέλων ενσωμάτωσης, η τεκμηρίωση του LangChain στην ενότητα Ενσωματώσεις είναι ένας πολύτιμος πόρος.
Vector καταστήματα
Τα καταστήματα Vector στο LangChain υποστηρίζουν την αποτελεσματική αποθήκευση και αναζήτηση ενσωματώσεων κειμένου. Το LangChain ενσωματώνεται με πάνω από 50 διανυσματικά καταστήματα, παρέχοντας μια τυποποιημένη διεπαφή για ευκολία στη χρήση.
Παράδειγμα: Αποθήκευση και αναζήτηση ενσωματώσεων
Μετά την ενσωμάτωση κειμένων, μπορούμε να τα αποθηκεύσουμε σε ένα διανυσματικό κατάστημα όπως Chroma
και πραγματοποιήστε αναζητήσεις ομοιότητας:
from langchain.vectorstores import Chroma db = Chroma.from_texts(embedded_texts)
similar_texts = db.similarity_search("search query")
Ας χρησιμοποιήσουμε εναλλακτικά το διανυσματικό κατάστημα FAISS για να δημιουργήσουμε ευρετήρια για τα έγγραφά μας.
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS pdfstore = FAISS.from_documents(pdfpages, embedding=OpenAIEmbeddings()) airtablestore = FAISS.from_documents(airtabledocs, embedding=OpenAIEmbeddings())
Ριτρίβερ
Τα Retriever στο LangChain είναι διεπαφές που επιστρέφουν έγγραφα ως απάντηση σε ένα μη δομημένο ερώτημα. Είναι πιο γενικά από τα διανυσματικά καταστήματα, εστιάζοντας στην ανάκτηση παρά στην αποθήκευση. Αν και τα διανυσματικά καταστήματα μπορούν να χρησιμοποιηθούν ως η ραχοκοκαλιά ενός retriever, υπάρχουν και άλλοι τύποι retriever.
Για να ρυθμίσετε ένα Chroma retriever, πρέπει πρώτα να το εγκαταστήσετε χρησιμοποιώντας pip install chromadb
. Στη συνέχεια, φορτώνετε, χωρίζετε, ενσωματώνετε και ανακτάτε έγγραφα χρησιμοποιώντας μια σειρά από εντολές Python. Ακολουθεί ένα παράδειγμα κώδικα για τη ρύθμιση ενός Chroma retriever:
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma full_text = open("state_of_the_union.txt", "r").read()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
texts = text_splitter.split_text(full_text) embeddings = OpenAIEmbeddings()
db = Chroma.from_texts(texts, embeddings)
retriever = db.as_retriever() retrieved_docs = retriever.invoke("What did the president say about Ketanji Brown Jackson?")
print(retrieved_docs[0].page_content)
Το MultiQueryRetriever αυτοματοποιεί τον γρήγορο συντονισμό δημιουργώντας πολλαπλά ερωτήματα για ένα ερώτημα εισαγωγής χρήστη και συνδυάζει τα αποτελέσματα. Ακολουθεί ένα παράδειγμα απλής χρήσης του:
from langchain.chat_models import ChatOpenAI
from langchain.retrievers.multi_query import MultiQueryRetriever question = "What are the approaches to Task Decomposition?"
llm = ChatOpenAI(temperature=0)
retriever_from_llm = MultiQueryRetriever.from_llm( retriever=db.as_retriever(), llm=llm
) unique_docs = retriever_from_llm.get_relevant_documents(query=question)
print("Number of unique documents:", len(unique_docs))
Η συμπίεση συμφραζομένων στο LangChain συμπιέζει τα ανακτημένα έγγραφα χρησιμοποιώντας το πλαίσιο του ερωτήματος, διασφαλίζοντας ότι επιστρέφονται μόνο σχετικές πληροφορίες. Αυτό περιλαμβάνει μείωση περιεχομένου και φιλτράρισμα λιγότερο σχετικών εγγράφων. Το ακόλουθο παράδειγμα κώδικα δείχνει πώς να χρησιμοποιήσετε το Contextual Compression Retriever:
from langchain.llms import OpenAI
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor llm = OpenAI(temperature=0)
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=retriever) compressed_docs = compression_retriever.get_relevant_documents("What did the president say about Ketanji Jackson Brown")
print(compressed_docs[0].page_content)
Το EnsembleRetriever συνδυάζει διαφορετικούς αλγόριθμους ανάκτησης για να επιτύχει καλύτερη απόδοση. Ένα παράδειγμα συνδυασμού BM25 και FAISS Retriever φαίνεται στον ακόλουθο κώδικα:
from langchain.retrievers import BM25Retriever, EnsembleRetriever
from langchain.vectorstores import FAISS bm25_retriever = BM25Retriever.from_texts(doc_list).set_k(2)
faiss_vectorstore = FAISS.from_texts(doc_list, OpenAIEmbeddings())
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k": 2}) ensemble_retriever = EnsembleRetriever( retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]
) docs = ensemble_retriever.get_relevant_documents("apples")
print(docs[0].page_content)
Το MultiVector Retriever στο LangChain επιτρέπει την αναζήτηση εγγράφων με πολλαπλά διανύσματα ανά έγγραφο, κάτι που είναι χρήσιμο για την καταγραφή διαφορετικών σημασιολογικών πτυχών μέσα σε ένα έγγραφο. Οι μέθοδοι για τη δημιουργία πολλαπλών διανυσμάτων περιλαμβάνουν το διαχωρισμό σε μικρότερα κομμάτια, τη σύνοψη ή τη δημιουργία υποθετικών ερωτήσεων. Για το διαχωρισμό εγγράφων σε μικρότερα κομμάτια, μπορεί να χρησιμοποιηθεί ο ακόλουθος κώδικας Python:
python
from langchain.retrievers.multi_vector import MultiVectorRetriever
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.storage import InMemoryStore
from langchain.document_loaders from TextLoader
import uuid loaders = [TextLoader("file1.txt"), TextLoader("file2.txt")]
docs = [doc for loader in loaders for doc in loader.load()]
text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000)
docs = text_splitter.split_documents(docs) vectorstore = Chroma(collection_name="full_documents", embedding_function=OpenAIEmbeddings())
store = InMemoryStore()
id_key = "doc_id"
retriever = MultiVectorRetriever(vectorstore=vectorstore, docstore=store, id_key=id_key) doc_ids = [str(uuid.uuid4()) for _ in docs]
child_text_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
sub_docs = [sub_doc for doc in docs for sub_doc in child_text_splitter.split_documents([doc])]
for sub_doc in sub_docs: sub_doc.metadata[id_key] = doc_ids[sub_docs.index(sub_doc)] retriever.vectorstore.add_documents(sub_docs)
retriever.docstore.mset(list(zip(doc_ids, docs)))
Η δημιουργία περιλήψεων για καλύτερη ανάκτηση λόγω πιο εστιασμένης αναπαράστασης περιεχομένου είναι μια άλλη μέθοδος. Ακολουθεί ένα παράδειγμα δημιουργίας περιλήψεων:
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.document import Document chain = (lambda x: x.page_content) | ChatPromptTemplate.from_template("Summarize the following document:nn{doc}") | ChatOpenAI(max_retries=0) | StrOutputParser()
summaries = chain.batch(docs, {"max_concurrency": 5}) summary_docs = [Document(page_content=s, metadata={id_key: doc_ids[i]}) for i, s in enumerate(summaries)]
retriever.vectorstore.add_documents(summary_docs)
retriever.docstore.mset(list(zip(doc_ids, docs)))
Η δημιουργία υποθετικών ερωτήσεων σχετικών με κάθε έγγραφο χρησιμοποιώντας το LLM είναι μια άλλη προσέγγιση. Αυτό μπορεί να γίνει με τον ακόλουθο κώδικα:
functions = [{"name": "hypothetical_questions", "parameters": {"questions": {"type": "array", "items": {"type": "string"}}}}]
from langchain.output_parsers.openai_functions import JsonKeyOutputFunctionsParser chain = (lambda x: x.page_content) | ChatPromptTemplate.from_template("Generate 3 hypothetical questions:nn{doc}") | ChatOpenAI(max_retries=0).bind(functions=functions, function_call={"name": "hypothetical_questions"}) | JsonKeyOutputFunctionsParser(key_name="questions")
hypothetical_questions = chain.batch(docs, {"max_concurrency": 5}) question_docs = [Document(page_content=q, metadata={id_key: doc_ids[i]}) for i, questions in enumerate(hypothetical_questions) for q in questions]
retriever.vectorstore.add_documents(question_docs)
retriever.docstore.mset(list(zip(doc_ids, docs)))
Το Parent Document Retriever είναι ένα άλλο retriever που επιτυγχάνει μια ισορροπία μεταξύ της ακρίβειας ενσωμάτωσης και της διατήρησης του περιβάλλοντος, αποθηκεύοντας μικρά κομμάτια και ανακτώντας τα μεγαλύτερα γονικά τους έγγραφα. Η εφαρμογή του έχει ως εξής:
from langchain.retrievers import ParentDocumentRetriever loaders = [TextLoader("file1.txt"), TextLoader("file2.txt")]
docs = [doc for loader in loaders for doc in loader.load()] child_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
vectorstore = Chroma(collection_name="full_documents", embedding_function=OpenAIEmbeddings())
store = InMemoryStore()
retriever = ParentDocumentRetriever(vectorstore=vectorstore, docstore=store, child_splitter=child_splitter) retriever.add_documents(docs, ids=None) retrieved_docs = retriever.get_relevant_documents("query")
Ένα retriever που κάνει αυτόματο ερώτημα κατασκευάζει δομημένα ερωτήματα από εισόδους φυσικής γλώσσας και τα εφαρμόζει στο υποκείμενο VectorStore του. Η εφαρμογή του φαίνεται στον παρακάτω κώδικα:
from langchain.chat_models from ChatOpenAI
from langchain.chains.query_constructor.base from AttributeInfo
from langchain.retrievers.self_query.base from SelfQueryRetriever metadata_field_info = [AttributeInfo(name="genre", description="...", type="string"), ...]
document_content_description = "Brief summary of a movie"
llm = ChatOpenAI(temperature=0) retriever = SelfQueryRetriever.from_llm(llm, vectorstore, document_content_description, metadata_field_info) retrieved_docs = retriever.invoke("query")
Το WebResearchRetriever εκτελεί έρευνα ιστού με βάση ένα δεδομένο ερώτημα –
from langchain.retrievers.web_research import WebResearchRetriever # Initialize components
llm = ChatOpenAI(temperature=0)
search = GoogleSearchAPIWrapper()
vectorstore = Chroma(embedding_function=OpenAIEmbeddings()) # Instantiate WebResearchRetriever
web_research_retriever = WebResearchRetriever.from_llm(vectorstore=vectorstore, llm=llm, search=search) # Retrieve documents
docs = web_research_retriever.get_relevant_documents("query")
Για τα παραδείγματά μας, μπορούμε επίσης να χρησιμοποιήσουμε το τυπικό retriever που έχει ήδη υλοποιηθεί ως μέρος του αντικειμένου διανυσματικού χώρου αποθήκευσης ως εξής -
Μπορούμε τώρα να ρωτήσουμε τα retriever. Η έξοδος του ερώτημά μας θα είναι αντικείμενα εγγράφου που σχετίζονται με το ερώτημα. Αυτά θα χρησιμοποιηθούν τελικά για τη δημιουργία σχετικών απαντήσεων σε περαιτέρω ενότητες.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
Ενότητα III : Πράκτορες
Η LangChain εισάγει μια ισχυρή ιδέα που ονομάζεται "Agents" που μεταφέρει την ιδέα των αλυσίδων σε ένα εντελώς νέο επίπεδο. Οι πράκτορες αξιοποιούν μοντέλα γλώσσας για να προσδιορίσουν δυναμικά τις ακολουθίες ενεργειών που πρέπει να εκτελέσουν, καθιστώντας τα απίστευτα ευέλικτα και προσαρμοστικά. Σε αντίθεση με τις παραδοσιακές αλυσίδες, όπου οι ενέργειες είναι κωδικοποιημένες σε κώδικα, οι πράκτορες χρησιμοποιούν γλωσσικά μοντέλα ως μηχανισμούς συλλογισμού για να αποφασίσουν ποιες ενέργειες θα κάνουν και με ποια σειρά.
Ο πράκτορας είναι το βασικό συστατικό που είναι υπεύθυνο για τη λήψη αποφάσεων. Αξιοποιεί τη δύναμη ενός γλωσσικού μοντέλου και μια προτροπή για τον καθορισμό των επόμενων βημάτων για την επίτευξη ενός συγκεκριμένου στόχου. Οι εισροές σε έναν πράκτορα συνήθως περιλαμβάνουν:
- Εργαλεία: Περιγραφές των διαθέσιμων εργαλείων (περισσότερα για αυτό αργότερα).
- Εισαγωγή χρήστη: Ο στόχος ή το ερώτημα υψηλού επιπέδου από τον χρήστη.
- Ενδιάμεσα βήματα: Ένα ιστορικό ζευγών (ενέργεια, έξοδος εργαλείου) που εκτελούνται για την επίτευξη της τρέχουσας εισόδου χρήστη.
Η έξοδος ενός πράκτορα μπορεί να είναι η επόμενη δράση να προβεί σε ενέργειες (AgentActions) ή τον τελικό απάντησης για αποστολή στον χρήστη (AgentFinish). Ενα δράση ορίζει α εργαλείο και την εισαγωγή για αυτό το εργαλείο.
Εργαλεία
Τα εργαλεία είναι διεπαφές που μπορεί να χρησιμοποιήσει ένας πράκτορας για να αλληλεπιδράσει με τον κόσμο. Επιτρέπουν στους πράκτορες να εκτελούν διάφορες εργασίες, όπως αναζήτηση στον ιστό, εκτέλεση εντολών φλοιού ή πρόσβαση σε εξωτερικά API. Στο LangChain, τα εργαλεία είναι απαραίτητα για την επέκταση των δυνατοτήτων των πρακτόρων και για να τους επιτρέψουν να ολοκληρώσουν διάφορες εργασίες.
Για να χρησιμοποιήσετε εργαλεία στο LangChain, μπορείτε να τα φορτώσετε χρησιμοποιώντας το ακόλουθο απόσπασμα:
from langchain.agents import load_tools tool_names = [...]
tools = load_tools(tool_names)
Ορισμένα εργαλεία ενδέχεται να απαιτούν ένα βασικό μοντέλο γλώσσας (LLM) για προετοιμασία. Σε τέτοιες περιπτώσεις, μπορείτε επίσης να περάσετε ένα LLM:
from langchain.agents import load_tools tool_names = [...]
llm = ...
tools = load_tools(tool_names, llm=llm)
Αυτή η ρύθμιση σάς επιτρέπει να έχετε πρόσβαση σε μια ποικιλία εργαλείων και να τα ενσωματώνετε στις ροές εργασίας του αντιπροσώπου σας. Η πλήρης λίστα εργαλείων με τεκμηρίωση χρήσης είναι εδώ.
Ας δούμε μερικά παραδείγματα Εργαλείων.
DuckDuckGo
Το εργαλείο DuckDuckGo σάς δίνει τη δυνατότητα να πραγματοποιείτε αναζητήσεις στον ιστό χρησιμοποιώντας τη μηχανή αναζήτησής του. Δείτε πώς να το χρησιμοποιήσετε:
from langchain.tools import DuckDuckGoSearchRun
search = DuckDuckGoSearchRun()
search.run("manchester united vs luton town match summary")
DataForSeo
Η εργαλειοθήκη DataForSeo σάς επιτρέπει να λαμβάνετε αποτελέσματα μηχανών αναζήτησης χρησιμοποιώντας το DataForSeo API. Για να χρησιμοποιήσετε αυτήν την εργαλειοθήκη, θα πρέπει να ρυθμίσετε τα διαπιστευτήριά σας API. Δείτε πώς μπορείτε να ρυθμίσετε τις παραμέτρους των διαπιστευτηρίων:
import os os.environ["DATAFORSEO_LOGIN"] = "<your_api_access_username>"
os.environ["DATAFORSEO_PASSWORD"] = "<your_api_access_password>"
Αφού οριστούν τα διαπιστευτήριά σας, μπορείτε να δημιουργήσετε ένα DataForSeoAPIWrapper
εργαλείο για πρόσβαση στο API:
from langchain.utilities.dataforseo_api_search import DataForSeoAPIWrapper wrapper = DataForSeoAPIWrapper() result = wrapper.run("Weather in Los Angeles")
Η DataForSeoAPIWrapper
Το εργαλείο ανακτά αποτελέσματα μηχανών αναζήτησης από διάφορες πηγές.
Μπορείτε να προσαρμόσετε τον τύπο των αποτελεσμάτων και των πεδίων που επιστρέφονται στην απόκριση JSON. Για παράδειγμα, μπορείτε να καθορίσετε τους τύπους αποτελεσμάτων, τα πεδία και να ορίσετε ένα μέγιστο πλήθος για τον αριθμό των κορυφαίων αποτελεσμάτων προς επιστροφή:
json_wrapper = DataForSeoAPIWrapper( json_result_types=["organic", "knowledge_graph", "answer_box"], json_result_fields=["type", "title", "description", "text"], top_count=3,
) json_result = json_wrapper.results("Bill Gates")
Αυτό το παράδειγμα προσαρμόζει την απόκριση JSON καθορίζοντας τύπους αποτελεσμάτων, πεδία και περιορίζοντας τον αριθμό των αποτελεσμάτων.
Μπορείτε επίσης να καθορίσετε την τοποθεσία και τη γλώσσα για τα αποτελέσματα αναζήτησής σας περνώντας πρόσθετες παραμέτρους στο περιτύλιγμα API:
customized_wrapper = DataForSeoAPIWrapper( top_count=10, json_result_types=["organic", "local_pack"], json_result_fields=["title", "description", "type"], params={"location_name": "Germany", "language_code": "en"},
) customized_result = customized_wrapper.results("coffee near me")
Παρέχοντας παραμέτρους τοποθεσίας και γλώσσας, μπορείτε να προσαρμόσετε τα αποτελέσματα αναζήτησής σας σε συγκεκριμένες περιοχές και γλώσσες.
Έχετε την ευελιξία να επιλέξετε τη μηχανή αναζήτησης που θέλετε να χρησιμοποιήσετε. Απλώς καθορίστε την επιθυμητή μηχανή αναζήτησης:
customized_wrapper = DataForSeoAPIWrapper( top_count=10, json_result_types=["organic", "local_pack"], json_result_fields=["title", "description", "type"], params={"location_name": "Germany", "language_code": "en", "se_name": "bing"},
) customized_result = customized_wrapper.results("coffee near me")
Σε αυτό το παράδειγμα, η αναζήτηση είναι προσαρμοσμένη ώστε να χρησιμοποιεί το Bing ως μηχανή αναζήτησης.
Το περιτύλιγμα API σάς επιτρέπει επίσης να καθορίσετε τον τύπο αναζήτησης που θέλετε να εκτελέσετε. Για παράδειγμα, μπορείτε να πραγματοποιήσετε αναζήτηση χαρτών:
maps_search = DataForSeoAPIWrapper( top_count=10, json_result_fields=["title", "value", "address", "rating", "type"], params={ "location_coordinate": "52.512,13.36,12z", "language_code": "en", "se_type": "maps", },
) maps_search_result = maps_search.results("coffee near me")
Αυτό προσαρμόζει την αναζήτηση για την ανάκτηση πληροφοριών που σχετίζονται με χάρτες.
Κέλυφος (bash)
Η εργαλειοθήκη Shell παρέχει στους πράκτορες πρόσβαση στο περιβάλλον του κελύφους, επιτρέποντάς τους να εκτελούν εντολές φλοιού. Αυτή η δυνατότητα είναι ισχυρή, αλλά θα πρέπει να χρησιμοποιείται με προσοχή, ειδικά σε περιβάλλοντα με sandbox. Δείτε πώς μπορείτε να χρησιμοποιήσετε το εργαλείο Shell:
from langchain.tools import ShellTool shell_tool = ShellTool() result = shell_tool.run({"commands": ["echo 'Hello World!'", "time"]})
Σε αυτό το παράδειγμα, το εργαλείο Shell εκτελεί δύο εντολές φλοιού: ηχώ "Hello World!" και εμφανίζει την τρέχουσα ώρα.
Μπορείτε να παρέχετε το εργαλείο Shell σε έναν πράκτορα για την εκτέλεση πιο περίπλοκων εργασιών. Ακολουθεί ένα παράδειγμα ενός πράκτορα που ανακτά συνδέσμους από μια ιστοσελίδα χρησιμοποιώντας το εργαλείο Shell:
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(temperature=0.1) shell_tool.description = shell_tool.description + f"args {shell_tool.args}".replace( "{", "{{"
).replace("}", "}}")
self_ask_with_search = initialize_agent( [shell_tool], llm, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
self_ask_with_search.run( "Download the langchain.com webpage and grep for all urls. Return only a sorted list of them. Be sure to use double quotes."
)
Σε αυτό το σενάριο, ο πράκτορας χρησιμοποιεί το εργαλείο Shell για να εκτελέσει μια ακολουθία εντολών για ανάκτηση, φιλτράρισμα και ταξινόμηση διευθύνσεων URL από μια ιστοσελίδα.
Τα παραδείγματα που παρέχονται δείχνουν ορισμένα από τα διαθέσιμα εργαλεία στο LangChain. Αυτά τα εργαλεία εν τέλει επεκτείνουν τις δυνατότητες των πρακτόρων (που θα διερευνηθούν στην επόμενη υποενότητα) και τους δίνουν τη δυνατότητα να εκτελούν διάφορες εργασίες αποτελεσματικά. Ανάλογα με τις απαιτήσεις σας, μπορείτε να επιλέξετε τα εργαλεία και τα κιτ εργαλείων που ταιριάζουν καλύτερα στις ανάγκες του έργου σας και να τα ενσωματώσετε στις ροές εργασιών του αντιπροσώπου σας.
Επιστροφή στους Πράκτορες
Πάμε τώρα στους πράκτορες.
Το AgentExecutor είναι το περιβάλλον χρόνου εκτέλεσης για έναν πράκτορα. Είναι υπεύθυνος για την κλήση του πράκτορα, την εκτέλεση των ενεργειών που επιλέγει, την επιστροφή των εξόδων ενεργειών στον πράκτορα και την επανάληψη της διαδικασίας μέχρι να τελειώσει ο πράκτορας. Στον ψευδοκώδικα, το AgentExecutor μπορεί να μοιάζει κάπως έτσι:
next_action = agent.get_action(...)
while next_action != AgentFinish: observation = run(next_action) next_action = agent.get_action(..., next_action, observation)
return next_action
Το AgentExecutor χειρίζεται διάφορες πολυπλοκότητες, όπως η αντιμετώπιση περιπτώσεων όπου ο πράκτορας επιλέγει ένα ανύπαρκτο εργαλείο, ο χειρισμός σφαλμάτων εργαλείου, η διαχείριση των εξόδων που παράγονται από τον πράκτορα και η παροχή καταγραφής και παρατηρησιμότητας σε όλα τα επίπεδα.
Ενώ η κλάση AgentExecutor είναι ο κύριος χρόνος εκτέλεσης agent στο LangChain, υποστηρίζονται άλλοι, πιο πειραματικοί χρόνοι εκτέλεσης, όπως:
- Πράκτορας προγραμματισμού και εκτέλεσης
- Baby AGI
- Αυτόματο GPT
Για να κατανοήσουμε καλύτερα το πλαίσιο του πράκτορα, ας δημιουργήσουμε έναν βασικό πράκτορα από την αρχή και, στη συνέχεια, ας προχωρήσουμε στην εξερεύνηση προκατασκευασμένων πρακτόρων.
Πριν ξεκινήσουμε την κατασκευή του πράκτορα, είναι απαραίτητο να επανεξετάσουμε κάποια βασική ορολογία και σχήμα:
- AgentAction: Αυτή είναι μια κλάση δεδομένων που αντιπροσωπεύει την ενέργεια που πρέπει να κάνει ένας πράκτορας. Αποτελείται από α
tool
ιδιοκτησία (το όνομα του εργαλείου προς επίκληση) και αtool_input
ιδιοκτησία (η είσοδος για αυτό το εργαλείο). - AgentFinish: Αυτή η κλάση δεδομένων υποδεικνύει ότι ο πράκτορας έχει ολοκληρώσει την εργασία του και πρέπει να επιστρέψει μια απάντηση στον χρήστη. Συνήθως περιλαμβάνει ένα λεξικό επιστρεφόμενων τιμών, συχνά με ένα κλειδί "έξοδος" που περιέχει το κείμενο απάντησης.
- Ενδιάμεσα βήματα: Αυτά είναι τα αρχεία προηγούμενων ενεργειών του πράκτορα και τα αντίστοιχα αποτελέσματα. Είναι ζωτικής σημασίας για τη μετάδοση του πλαισίου σε μελλοντικές επαναλήψεις του πράκτορα.
Στο παράδειγμά μας, θα χρησιμοποιήσουμε το OpenAI Function Calling για να δημιουργήσουμε τον πράκτορά μας. Αυτή η προσέγγιση είναι αξιόπιστη για τη δημιουργία πρακτόρων. Θα ξεκινήσουμε δημιουργώντας ένα απλό εργαλείο που υπολογίζει το μήκος μιας λέξης. Αυτό το εργαλείο είναι χρήσιμο επειδή τα μοντέλα γλώσσας μπορεί μερικές φορές να κάνουν λάθη λόγω του tokenization κατά την καταμέτρηση του μήκους των λέξεων.
Αρχικά, ας φορτώσουμε το μοντέλο γλώσσας που θα χρησιμοποιήσουμε για τον έλεγχο του πράκτορα:
from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
Ας δοκιμάσουμε το μοντέλο με έναν υπολογισμό μήκους λέξης:
llm.invoke("how many letters in the word educa?")
Η απάντηση θα πρέπει να αναφέρει τον αριθμό των γραμμάτων στη λέξη "educa".
Στη συνέχεια, θα ορίσουμε μια απλή συνάρτηση Python για τον υπολογισμό του μήκους μιας λέξης:
from langchain.agents import tool @tool
def get_word_length(word: str) -> int: """Returns the length of a word.""" return len(word)
Δημιουργήσαμε ένα εργαλείο με το όνομα get_word_length
που παίρνει μια λέξη ως είσοδο και επιστρέφει το μήκος της.
Τώρα, ας δημιουργήσουμε την προτροπή για τον πράκτορα. Η προτροπή καθοδηγεί τον πράκτορα για το πώς να αιτιολογήσει και να μορφοποιήσει την έξοδο. Στην περίπτωσή μας, χρησιμοποιούμε το OpenAI Function Calling, το οποίο απαιτεί ελάχιστες οδηγίες. Θα ορίσουμε το μήνυμα προτροπής με σύμβολα κράτησης θέσης για την εισαγωγή χρήστη και το scratchpad του πράκτορα:
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are a very powerful assistant but not great at calculating word lengths.", ), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ]
)
Τώρα, πώς γνωρίζει ο πράκτορας ποια εργαλεία μπορεί να χρησιμοποιήσει; Βασιζόμαστε σε μοντέλα γλώσσας κλήσης συναρτήσεων OpenAI, τα οποία απαιτούν να περάσουν οι συναρτήσεις ξεχωριστά. Για να παρέχουμε τα εργαλεία μας στον πράκτορα, θα τα μορφοποιήσουμε όπως καλεί η λειτουργία OpenAI:
from langchain.tools.render import format_tool_to_openai_function llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])
Τώρα, μπορούμε να δημιουργήσουμε τον πράκτορα ορίζοντας αντιστοιχίσεις εισόδου και συνδέοντας τα στοιχεία:
Αυτή είναι η γλώσσα LCEL. Θα το συζητήσουμε αργότερα λεπτομερώς.
from langchain.agents.format_scratchpad import format_to_openai_function_messages
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai _function_messages( x["intermediate_steps"] ), } | prompt | llm_with_tools | OpenAIFunctionsAgentOutputParser()
)
Δημιουργήσαμε τον αντιπρόσωπό μας, ο οποίος κατανοεί τις εισαγωγές χρήστη, χρησιμοποιεί διαθέσιμα εργαλεία και μορφοποιεί την έξοδο. Τώρα, ας αλληλεπιδράσουμε με αυτό:
agent.invoke({"input": "how many letters in the word educa?", "intermediate_steps": []})
Ο πράκτορας θα πρέπει να απαντήσει με ένα AgentAction, υποδεικνύοντας την επόμενη ενέργεια που πρέπει να πραγματοποιηθεί.
Δημιουργήσαμε τον πράκτορα, αλλά τώρα πρέπει να γράψουμε έναν χρόνο εκτέλεσης για αυτόν. Ο απλούστερος χρόνος εκτέλεσης είναι αυτός που καλεί συνεχώς τον πράκτορα, εκτελεί ενέργειες και επαναλαμβάνει μέχρι να τελειώσει ο πράκτορας. Εδώ είναι ένα παράδειγμα:
from langchain.schema.agent import AgentFinish user_input = "how many letters in the word educa?"
intermediate_steps = [] while True: output = agent.invoke( { "input": user_input, "intermediate_steps": intermediate_steps, } ) if isinstance(output, AgentFinish): final_result = output.return_values["output"] break else: print(f"TOOL NAME: {output.tool}") print(f"TOOL INPUT: {output.tool_input}") tool = {"get_word_length": get_word_length}[output.tool] observation = tool.run(output.tool_input) intermediate_steps.append((output, observation)) print(final_result)
Σε αυτόν τον βρόχο, καλούμε επανειλημμένα τον πράκτορα, εκτελούμε ενέργειες και ενημερώνουμε τα ενδιάμεσα βήματα μέχρι να τελειώσει ο πράκτορας. Διαχειριζόμαστε επίσης αλληλεπιδράσεις εργαλείων εντός του βρόχου.
Για να απλοποιήσει αυτή τη διαδικασία, το LangChain παρέχει την κλάση AgentExecutor, η οποία ενσωματώνει την εκτέλεση πράκτορα και προσφέρει χειρισμό σφαλμάτων, πρόωρη διακοπή, ανίχνευση και άλλες βελτιώσεις. Ας χρησιμοποιήσουμε το AgentExecutor για να αλληλεπιδράσουμε με τον πράκτορα:
from langchain.agents import AgentExecutor agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) agent_executor.invoke({"input": "how many letters in the word educa?"})
Το AgentExecutor απλοποιεί τη διαδικασία εκτέλεσης και παρέχει έναν βολικό τρόπο αλληλεπίδρασης με τον πράκτορα.
Η μνήμη θα συζητηθεί επίσης λεπτομερώς αργότερα.
Ο πράκτορας που έχουμε δημιουργήσει μέχρι στιγμής είναι ανιθαγενής, που σημαίνει ότι δεν θυμάται προηγούμενες αλληλεπιδράσεις. Για να ενεργοποιήσουμε τις επακόλουθες ερωτήσεις και συνομιλίες, πρέπει να προσθέσουμε μνήμη στον πράκτορα. Αυτό περιλαμβάνει δύο βήματα:
- Προσθέστε μια μεταβλητή μνήμης στο μήνυμα για αποθήκευση του ιστορικού συνομιλίας.
- Παρακολουθήστε το ιστορικό συνομιλιών κατά τη διάρκεια των αλληλεπιδράσεων.
Ας ξεκινήσουμε προσθέτοντας ένα σύμβολο κράτησης θέσης μνήμης στη γραμμή εντολών:
from langchain.prompts import MessagesPlaceholder MEMORY_KEY = "chat_history"
prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are a very powerful assistant but not great at calculating word lengths.", ), MessagesPlaceholder(variable_name=MEMORY_KEY), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ]
)
Τώρα, δημιουργήστε μια λίστα για να παρακολουθείτε το ιστορικό συνομιλιών:
from langchain.schema.messages import HumanMessage, AIMessage chat_history = []
Στο βήμα δημιουργίας πράκτορα, θα συμπεριλάβουμε και τη μνήμη:
agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_function_messages( x["intermediate_steps"] ), "chat_history": lambda x: x["chat_history"], } | prompt | llm_with_tools | OpenAIFunctionsAgentOutputParser()
)
Τώρα, όταν εκτελείτε τον πράκτορα, φροντίστε να ενημερώσετε το ιστορικό συνομιλιών:
input1 = "how many letters in the word educa?"
result = agent_executor.invoke({"input": input1, "chat_history": chat_history})
chat_history.extend([ HumanMessage(content=input1), AIMessage(content=result["output"]),
])
agent_executor.invoke({"input": "is that a real word?", "chat_history": chat_history})
Αυτό δίνει τη δυνατότητα στον πράκτορα να διατηρεί ένα ιστορικό συνομιλιών και να απαντά σε επακόλουθες ερωτήσεις με βάση προηγούμενες αλληλεπιδράσεις.
Συγχαρητήρια! Δημιουργήσατε και εκτελέσατε με επιτυχία τον πρώτο σας από άκρο σε άκρο πράκτορα στο LangChain. Για να εμβαθύνετε στις δυνατότητες του LangChain, μπορείτε να εξερευνήσετε:
- Υποστηρίζονται διαφορετικοί τύποι πρακτόρων.
- Προκατασκευασμένοι Πράκτορες
- Πώς να εργαστείτε με εργαλεία και ενσωματώσεις εργαλείων.
Τύποι πρακτόρων
Η LangChain προσφέρει διάφορους τύπους πρακτόρων, ο καθένας κατάλληλος για συγκεκριμένες περιπτώσεις χρήσης. Εδώ είναι μερικοί από τους διαθέσιμους πράκτορες:
- Zero-shot ReAct: Αυτός ο πράκτορας χρησιμοποιεί το πλαίσιο ReAct για να επιλέξει εργαλεία που βασίζονται αποκλειστικά στις περιγραφές τους. Απαιτεί περιγραφές για κάθε εργαλείο και είναι εξαιρετικά ευέλικτο.
- Δομημένη είσοδος ReAct: Αυτός ο πράκτορας χειρίζεται εργαλεία πολλαπλών εισόδων και είναι κατάλληλος για περίπλοκες εργασίες όπως η πλοήγηση σε ένα πρόγραμμα περιήγησης ιστού. Χρησιμοποιεί ένα σχήμα ορίσματος εργαλείων για δομημένη είσοδο.
- Λειτουργίες OpenAI: Ειδικά σχεδιασμένο για μοντέλα που έχουν ρυθμιστεί με ακρίβεια για κλήση λειτουργιών, αυτός ο πράκτορας είναι συμβατός με μοντέλα όπως τα gpt-3.5-turbo-0613 και gpt-4-0613. Το χρησιμοποιήσαμε για να δημιουργήσουμε τον πρώτο μας πράκτορα παραπάνω.
- Ομιλητικός: Σχεδιασμένος για ρυθμίσεις συνομιλίας, αυτός ο πράκτορας χρησιμοποιεί το ReAct για επιλογή εργαλείου και χρησιμοποιεί τη μνήμη για να θυμάται προηγούμενες αλληλεπιδράσεις.
- Ρωτήστε τον εαυτό σας με αναζήτηση: Αυτός ο πράκτορας βασίζεται σε ένα μόνο εργαλείο, την "Ενδιάμεση Απάντηση", το οποίο αναζητά πραγματικές απαντήσεις σε ερωτήσεις. Είναι ισοδύναμο με το αρχικό αυτό-ρωτήστε με το χαρτί αναζήτησης.
- Αποθήκευση εγγράφων ReAct: Αυτός ο παράγοντας αλληλεπιδρά με έναν χώρο αποθήκευσης εγγράφων χρησιμοποιώντας το πλαίσιο ReAct. Απαιτεί εργαλεία «Αναζήτηση» και «Αναζήτηση» και είναι παρόμοια με το παράδειγμα της αρχικής εφημερίδας ReAct της Wikipedia.
Εξερευνήστε αυτούς τους τύπους πρακτόρων για να βρείτε αυτόν που ταιριάζει καλύτερα στις ανάγκες σας στο LangChain. Αυτοί οι πράκτορες σάς επιτρέπουν να δεσμεύετε ένα σύνολο εργαλείων μέσα σε αυτά για να χειρίζονται ενέργειες και να δημιουργούν απαντήσεις. Μάθετε περισσότερα στο πώς να φτιάξετε τον δικό σας πράκτορα με εργαλεία εδώ.
Προκατασκευασμένοι Πράκτορες
Ας συνεχίσουμε την εξερεύνηση των πρακτόρων, εστιάζοντας σε προκατασκευασμένους πράκτορες που διατίθενται στο LangChain.
Gmail
Το LangChain προσφέρει μια εργαλειοθήκη Gmail που σας επιτρέπει να συνδέσετε το email σας στο LangChain με το Gmail API. Για να ξεκινήσετε, θα πρέπει να ρυθμίσετε τα διαπιστευτήριά σας, τα οποία εξηγούνται στην τεκμηρίωση του Gmail API. Μόλις κατεβάσετε το credentials.json
αρχείο, μπορείτε να συνεχίσετε με τη χρήση του Gmail API. Επιπλέον, θα χρειαστεί να εγκαταστήσετε ορισμένες απαιτούμενες βιβλιοθήκες χρησιμοποιώντας τις ακόλουθες εντολές:
pip install --upgrade google-api-python-client > /dev/null
pip install --upgrade google-auth-oauthlib > /dev/null
pip install --upgrade google-auth-httplib2 > /dev/null
pip install beautifulsoup4 > /dev/null # Optional for parsing HTML messages
Μπορείτε να δημιουργήσετε την εργαλειοθήκη Gmail ως εξής:
from langchain.agents.agent_toolkits import GmailToolkit toolkit = GmailToolkit()
Μπορείτε επίσης να προσαρμόσετε τον έλεγχο ταυτότητας σύμφωνα με τις ανάγκες σας. Στα παρασκήνια, δημιουργείται ένας πόρος googleapi χρησιμοποιώντας τις ακόλουθες μεθόδους:
from langchain.tools.gmail.utils import build_resource_service, get_gmail_credentials credentials = get_gmail_credentials( token_file="token.json", scopes=["https://mail.google.com/"], client_secrets_file="credentials.json",
)
api_resource = build_resource_service(credentials=credentials)
toolkit = GmailToolkit(api_resource=api_resource)
Η εργαλειοθήκη προσφέρει διάφορα εργαλεία που μπορούν να χρησιμοποιηθούν σε έναν πράκτορα, όπως:
GmailCreateDraft
: Δημιουργήστε ένα πρόχειρο email με καθορισμένα πεδία μηνυμάτων.GmailSendMessage
: Αποστολή μηνυμάτων email.GmailSearch
: Αναζήτηση για μηνύματα email ή νήματα.GmailGetMessage
: Λήψη email με αναγνωριστικό μηνύματος.GmailGetThread
: Αναζήτηση για μηνύματα email.
Για να χρησιμοποιήσετε αυτά τα εργαλεία σε έναν πράκτορα, μπορείτε να αρχικοποιήσετε τον πράκτορα ως εξής:
from langchain.llms import OpenAI
from langchain.agents import initialize_agent, AgentType llm = OpenAI(temperature=0)
agent = initialize_agent( tools=toolkit.get_tools(), llm=llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
)
Ακολουθούν μερικά παραδείγματα για το πώς μπορούν να χρησιμοποιηθούν αυτά τα εργαλεία:
- Δημιουργήστε ένα πρόχειρο Gmail για επεξεργασία:
agent.run( "Create a gmail draft for me to edit of a letter from the perspective of a sentient parrot " "who is looking to collaborate on some research with her estranged friend, a cat. " "Under no circumstances may you send the message, however."
)
- Αναζητήστε το πιο πρόσφατο email στα πρόχειρά σας:
agent.run("Could you search in my drafts for the latest email?")
Αυτά τα παραδείγματα δείχνουν τις δυνατότητες της εργαλειοθήκης Gmail της LangChain μέσα σε έναν πράκτορα, δίνοντάς σας τη δυνατότητα να αλληλεπιδράτε με το Gmail μέσω προγραμματισμού.
Πράκτορας βάσης δεδομένων SQL
Αυτή η ενότητα παρέχει μια επισκόπηση ενός πράκτορα που έχει σχεδιαστεί για να αλληλεπιδρά με βάσεις δεδομένων SQL, ιδιαίτερα τη βάση δεδομένων Chinook. Αυτός ο πράκτορας μπορεί να απαντήσει σε γενικές ερωτήσεις σχετικά με μια βάση δεδομένων και να ανακτήσει από σφάλματα. Λάβετε υπόψη ότι είναι ακόμα σε ενεργό ανάπτυξη και μπορεί να μην είναι όλες οι απαντήσεις σωστές. Να είστε προσεκτικοί όταν το εκτελείτε σε ευαίσθητα δεδομένα, καθώς μπορεί να εκτελέσει δηλώσεις DML στη βάση δεδομένων σας.
Για να χρησιμοποιήσετε αυτόν τον παράγοντα, μπορείτε να τον αρχικοποιήσετε ως εξής:
from langchain.agents import create_sql_agent
from langchain.agents.agent_toolkits import SQLDatabaseToolkit
from langchain.sql_database import SQLDatabase
from langchain.llms.openai import OpenAI
from langchain.agents import AgentExecutor
from langchain.agents.agent_types import AgentType
from langchain.chat_models import ChatOpenAI db = SQLDatabase.from_uri("sqlite:///../../../../../notebooks/Chinook.db")
toolkit = SQLDatabaseToolkit(db=db, llm=OpenAI(temperature=0)) agent_executor = create_sql_agent( llm=OpenAI(temperature=0), toolkit=toolkit, verbose=True, agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)
Αυτός ο παράγοντας μπορεί να αρχικοποιηθεί χρησιμοποιώντας το ZERO_SHOT_REACT_DESCRIPTION
τύπος πράκτορα. Έχει σχεδιαστεί για να απαντά σε ερωτήσεις και να παρέχει περιγραφές. Εναλλακτικά, μπορείτε να αρχικοποιήσετε τον πράκτορα χρησιμοποιώντας το OPENAI_FUNCTIONS
τύπος πράκτορα με το μοντέλο GPT-3.5-turbo του OpenAI, το οποίο χρησιμοποιήσαμε στον προηγούμενο πελάτη μας.
Αποποίηση ευθυνών
- Η αλυσίδα ερωτημάτων μπορεί να δημιουργήσει ερωτήματα εισαγωγής/ενημέρωσης/διαγραφής. Να είστε προσεκτικοί και χρησιμοποιήστε μια προσαρμοσμένη προτροπή ή δημιουργήστε έναν χρήστη SQL χωρίς δικαιώματα εγγραφής, εάν χρειάζεται.
- Λάβετε υπόψη ότι η εκτέλεση ορισμένων ερωτημάτων, όπως η "εκτέλεση του μεγαλύτερου δυνατού ερωτήματος", θα μπορούσε να υπερφορτώσει τη βάση δεδομένων SQL, ειδικά εάν περιέχει εκατομμύρια σειρές.
- Οι βάσεις δεδομένων που προσανατολίζονται στην αποθήκη δεδομένων συχνά υποστηρίζουν ποσοστώσεις σε επίπεδο χρήστη για τον περιορισμό της χρήσης πόρων.
Μπορείτε να ζητήσετε από τον πράκτορα να περιγράψει έναν πίνακα, όπως τον πίνακα "playlisttrack". Ακολουθεί ένα παράδειγμα για το πώς να το κάνετε:
agent_executor.run("Describe the playlisttrack table")
Ο πράκτορας θα παρέχει πληροφορίες σχετικά με το σχήμα και τις σειρές δειγμάτων του πίνακα.
Εάν ρωτήσετε κατά λάθος για έναν πίνακα που δεν υπάρχει, ο πράκτορας μπορεί να ανακτήσει και να παράσχει πληροφορίες σχετικά με τον πλησιέστερο πίνακα αντιστοίχισης. Για παράδειγμα:
agent_executor.run("Describe the playlistsong table")
Ο πράκτορας θα βρει τον πλησιέστερο πίνακα αντιστοίχισης και θα παράσχει πληροφορίες σχετικά με αυτόν.
Μπορείτε επίσης να ζητήσετε από τον πράκτορα να εκτελέσει ερωτήματα στη βάση δεδομένων. Για παράδειγμα:
agent_executor.run("List the total sales per country. Which country's customers spent the most?")
Ο πράκτορας θα εκτελέσει το ερώτημα και θα παρέχει το αποτέλεσμα, όπως τη χώρα με τις υψηλότερες συνολικές πωλήσεις.
Για να λάβετε τον συνολικό αριθμό κομματιών σε κάθε playlist, μπορείτε να χρησιμοποιήσετε το ακόλουθο ερώτημα:
agent_executor.run("Show the total number of tracks in each playlist. The Playlist name should be included in the result.")
Ο πράκτορας θα επιστρέψει τα ονόματα των λιστών αναπαραγωγής μαζί με τον αντίστοιχο συνολικό αριθμό κομματιών.
Σε περιπτώσεις όπου ο πράκτορας αντιμετωπίζει σφάλματα, μπορεί να ανακτήσει και να παρέχει ακριβείς απαντήσεις. Για παράδειγμα:
agent_executor.run("Who are the top 3 best selling artists?")
Ακόμη και μετά την αντιμετώπιση ενός αρχικού σφάλματος, ο πράκτορας θα προσαρμόσει και θα δώσει τη σωστή απάντηση, η οποία, σε αυτήν την περίπτωση, είναι οι 3 κορυφαίοι καλλιτέχνες με τις μεγαλύτερες πωλήσεις.
Pandas DataFrame Agent
Αυτή η ενότητα παρουσιάζει έναν πράκτορα που έχει σχεδιαστεί για να αλληλεπιδρά με το Pandas DataFrames για σκοπούς απάντησης ερωτήσεων. Λάβετε υπόψη ότι αυτός ο πράκτορας χρησιμοποιεί τον παράγοντα Python κάτω από την κουκούλα για την εκτέλεση κώδικα Python που δημιουργείται από ένα μοντέλο γλώσσας (LLM). Να είστε προσεκτικοί όταν χρησιμοποιείτε αυτόν τον παράγοντα για να αποτρέψετε πιθανή βλάβη από κακόβουλο κώδικα Python που δημιουργείται από το LLM.
Μπορείτε να αρχικοποιήσετε τον πράκτορα Pandas DataFrame ως εξής:
from langchain_experimental.agents.agent_toolkits import create_pandas_dataframe_agent
from langchain.chat_models import ChatOpenAI
from langchain.agents.agent_types import AgentType from langchain.llms import OpenAI
import pandas as pd df = pd.read_csv("titanic.csv") # Using ZERO_SHOT_REACT_DESCRIPTION agent type
agent = create_pandas_dataframe_agent(OpenAI(temperature=0), df, verbose=True) # Alternatively, using OPENAI_FUNCTIONS agent type
# agent = create_pandas_dataframe_agent(
# ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613"),
# df,
# verbose=True,
# agent_type=AgentType.OPENAI_FUNCTIONS,
# )
Μπορείτε να ζητήσετε από τον πράκτορα να μετρήσει τον αριθμό των σειρών στο DataFrame:
agent.run("how many rows are there?")
Ο πράκτορας θα εκτελέσει τον κώδικα df.shape[0]
και δώστε την απάντηση, όπως "Υπάρχουν 891 σειρές στο πλαίσιο δεδομένων".
Μπορείτε επίσης να ζητήσετε από τον πράκτορα να φιλτράρει τις σειρές με βάση συγκεκριμένα κριτήρια, όπως η εύρεση του αριθμού των ατόμων με περισσότερα από 3 αδέρφια:
agent.run("how many people have more than 3 siblings")
Ο πράκτορας θα εκτελέσει τον κώδικα df[df['SibSp'] > 3].shape[0]
και δώστε την απάντηση, όπως «30 άτομα έχουν περισσότερα από 3 αδέρφια».
Εάν θέλετε να υπολογίσετε την τετραγωνική ρίζα του μέσου όρου ηλικίας, μπορείτε να ρωτήσετε τον πράκτορα:
agent.run("whats the square root of the average age?")
Ο πράκτορας θα υπολογίσει τη μέση ηλικία χρησιμοποιώντας df['Age'].mean()
και στη συνέχεια υπολογίστε την τετραγωνική ρίζα χρησιμοποιώντας math.sqrt()
. Θα δώσει την απάντηση, όπως "Η τετραγωνική ρίζα του μέσου όρου ηλικίας είναι 5.449689683556195."
Ας δημιουργήσουμε ένα αντίγραφο του DataFrame και οι τιμές ηλικίας που λείπουν συμπληρώνονται με τη μέση ηλικία:
df1 = df.copy()
df1["Age"] = df1["Age"].fillna(df1["Age"].mean())
Στη συνέχεια, μπορείτε να αρχικοποιήσετε τον πράκτορα και με τα δύο DataFrames και να του κάνετε μια ερώτηση:
agent = create_pandas_dataframe_agent(OpenAI(temperature=0), [df, df1], verbose=True)
agent.run("how many rows in the age column are different?")
Ο πράκτορας θα συγκρίνει τις στήλες ηλικίας και στα δύο DataFrames και θα δώσει την απάντηση, όπως "177 σειρές στη στήλη ηλικία είναι διαφορετικές".
Εργαλειοθήκη Jira
Αυτή η ενότητα εξηγεί πώς να χρησιμοποιήσετε το κιτ εργαλείων Jira, το οποίο επιτρέπει στους πράκτορες να αλληλεπιδρούν με μια παρουσία Jira. Μπορείτε να εκτελέσετε διάφορες ενέργειες, όπως αναζήτηση ζητημάτων και δημιουργία προβλημάτων χρησιμοποιώντας αυτήν την εργαλειοθήκη. Χρησιμοποιεί τη βιβλιοθήκη atlassian-python-api. Για να χρησιμοποιήσετε αυτήν την εργαλειοθήκη, πρέπει να ορίσετε μεταβλητές περιβάλλοντος για την παρουσία σας Jira, συμπεριλαμβανομένων των JIRA_API_TOKEN, JIRA_USERNAME και JIRA_INSTANCE_URL. Επιπλέον, μπορεί να χρειαστεί να ορίσετε το κλειδί OpenAI API ως μεταβλητή περιβάλλοντος.
Για να ξεκινήσετε, εγκαταστήστε τη βιβλιοθήκη atlassian-python-api και ορίστε τις απαιτούμενες μεταβλητές περιβάλλοντος:
%pip install atlassian-python-api import os
from langchain.agents import AgentType
from langchain.agents import initialize_agent
from langchain.agents.agent_toolkits.jira.toolkit import JiraToolkit
from langchain.llms import OpenAI
from langchain.utilities.jira import JiraAPIWrapper os.environ["JIRA_API_TOKEN"] = "abc"
os.environ["JIRA_USERNAME"] = "123"
os.environ["JIRA_INSTANCE_URL"] = "https://jira.atlassian.com"
os.environ["OPENAI_API_KEY"] = "xyz" llm = OpenAI(temperature=0)
jira = JiraAPIWrapper()
toolkit = JiraToolkit.from_jira_api_wrapper(jira)
agent = initialize_agent( toolkit.get_tools(), llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
Μπορείτε να δώσετε εντολή στον πράκτορα να δημιουργήσει ένα νέο τεύχος σε ένα συγκεκριμένο έργο με περίληψη και περιγραφή:
agent.run("make a new issue in project PW to remind me to make more fried rice")
Ο πράκτορας θα εκτελέσει τις απαραίτητες ενέργειες για να δημιουργήσει το ζήτημα και να δώσει μια απάντηση, όπως "Ένα νέο τεύχος έχει δημιουργηθεί στο έργο PW με τη σύνοψη "Φτιάξτε περισσότερο τηγανητό ρύζι" και περιγραφή "Υπενθύμιση για να φτιάξετε περισσότερο τηγανητό ρύζι".
Αυτό σας επιτρέπει να αλληλεπιδράτε με την παρουσία σας Jira χρησιμοποιώντας οδηγίες φυσικής γλώσσας και την εργαλειοθήκη Jira.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
Ενότητα IV : Αλυσίδες
Το LangChain είναι ένα εργαλείο σχεδιασμένο για τη χρήση μοντέλων μεγάλων γλωσσών (LLM) σε πολύπλοκες εφαρμογές. Παρέχει πλαίσια για τη δημιουργία αλυσίδων στοιχείων, συμπεριλαμβανομένων των LLM και άλλων τύπων στοιχείων. Δύο βασικά πλαίσια
- Η γλώσσα έκφρασης LangChain (LCEL)
- Διασύνδεση αλυσίδας παλαιού τύπου
Η γλώσσα έκφρασης LangChain (LCEL) είναι μια σύνταξη που επιτρέπει τη διαισθητική σύνθεση των αλυσίδων. Υποστηρίζει προηγμένες λειτουργίες όπως ροή, ασύγχρονες κλήσεις, ομαδοποίηση, παραλληλοποίηση, επαναλήψεις, εναλλακτικές και ανίχνευση. Για παράδειγμα, μπορείτε να συνθέσετε μια προτροπή, ένα μοντέλο και έναν αναλυτή εξόδου στο LCEL όπως φαίνεται στον ακόλουθο κώδικα:
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser model = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
prompt = ChatPromptTemplate.from_messages([ ("system", "You're a very knowledgeable historian who provides accurate and eloquent answers to historical questions."), ("human", "{question}")
])
runnable = prompt | model | StrOutputParser() for chunk in runnable.stream({"question": "What are the seven wonders of the world"}): print(chunk, end="", flush=True)
Εναλλακτικά, το LLMChain είναι μια επιλογή παρόμοια με το LCEL για τη σύνθεση εξαρτημάτων. Το παράδειγμα LLMChain είναι το εξής:
from langchain.chains import LLMChain chain = LLMChain(llm=model, prompt=prompt, output_parser=StrOutputParser())
chain.run(question="What are the seven wonders of the world")
Οι αλυσίδες στο LangChain μπορούν επίσης να έχουν κατάσταση με την ενσωμάτωση ενός αντικειμένου μνήμης. Αυτό επιτρέπει τη διατήρηση δεδομένων σε όλες τις κλήσεις, όπως φαίνεται σε αυτό το παράδειγμα:
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory conversation = ConversationChain(llm=chat, memory=ConversationBufferMemory())
conversation.run("Answer briefly. What are the first 3 colors of a rainbow?")
conversation.run("And the next 4?")
Το LangChain υποστηρίζει επίσης την ενοποίηση με τα API κλήσης συναρτήσεων του OpenAI, τα οποία είναι χρήσιμα για τη λήψη δομημένων εξόδων και την εκτέλεση συναρτήσεων εντός μιας αλυσίδας. Για να λάβετε δομημένα αποτελέσματα, μπορείτε να τα καθορίσετε χρησιμοποιώντας κλάσεις Pydantic ή JsonSchema, όπως φαίνεται παρακάτω:
from langchain.pydantic_v1 import BaseModel, Field
from langchain.chains.openai_functions import create_structured_output_runnable
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate class Person(BaseModel): name: str = Field(..., description="The person's name") age: int = Field(..., description="The person's age") fav_food: Optional[str] = Field(None, description="The person's favorite food") llm = ChatOpenAI(model="gpt-4", temperature=0)
prompt = ChatPromptTemplate.from_messages([ # Prompt messages here
]) runnable = create_structured_output_runnable(Person, llm, prompt)
runnable.invoke({"input": "Sally is 13"})
Για δομημένα αποτελέσματα, είναι επίσης διαθέσιμη μια προσέγγιση παλαιού τύπου που χρησιμοποιεί το LLMChain:
from langchain.chains.openai_functions import create_structured_output_chain class Person(BaseModel): name: str = Field(..., description="The person's name") age: int = Field(..., description="The person's age") chain = create_structured_output_chain(Person, llm, prompt, verbose=True)
chain.run("Sally is 13")
Το LangChain αξιοποιεί τις λειτουργίες OpenAI για να δημιουργήσει διάφορες συγκεκριμένες αλυσίδες για διαφορετικούς σκοπούς. Αυτά περιλαμβάνουν αλυσίδες για εξαγωγή, προσθήκη ετικετών, OpenAPI και QA με παραπομπές.
Στο πλαίσιο της εξαγωγής, η διαδικασία είναι παρόμοια με τη δομημένη αλυσίδα εξόδου, αλλά εστιάζει στην εξαγωγή πληροφοριών ή οντοτήτων. Για την προσθήκη ετικετών, η ιδέα είναι να επισημάνετε ένα έγγραφο με κατηγορίες όπως συναίσθημα, γλώσσα, στυλ, καλυμμένα θέματα ή πολιτικές τάσεις.
Ένα παράδειγμα του πώς λειτουργεί η προσθήκη ετικετών στο LangChain μπορεί να αποδειχθεί με έναν κώδικα Python. Η διαδικασία ξεκινά με την εγκατάσταση των απαραίτητων πακέτων και τη ρύθμιση του περιβάλλοντος:
pip install langchain openai
# Set env var OPENAI_API_KEY or load from a .env file:
# import dotenv
# dotenv.load_dotenv() from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.chains import create_tagging_chain, create_tagging_chain_pydantic
Το σχήμα για την προσθήκη ετικετών ορίζεται, προσδιορίζοντας τις ιδιότητες και τους αναμενόμενους τύπους τους:
schema = { "properties": { "sentiment": {"type": "string"}, "aggressiveness": {"type": "integer"}, "language": {"type": "string"}, }
} llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
chain = create_tagging_chain(schema, llm)
Παραδείγματα εκτέλεσης της αλυσίδας επισήμανσης με διαφορετικές εισόδους δείχνουν την ικανότητα του μοντέλου να ερμηνεύει συναισθήματα, γλώσσες και επιθετικότητα:
inp = "Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!"
chain.run(inp)
# {'sentiment': 'positive', 'language': 'Spanish'} inp = "Estoy muy enojado con vos! Te voy a dar tu merecido!"
chain.run(inp)
# {'sentiment': 'enojado', 'aggressiveness': 1, 'language': 'es'}
Για καλύτερο έλεγχο, το σχήμα μπορεί να οριστεί πιο συγκεκριμένα, συμπεριλαμβανομένων πιθανών τιμών, περιγραφών και απαιτούμενων ιδιοτήτων. Ένα παράδειγμα αυτού του ενισχυμένου ελέγχου φαίνεται παρακάτω:
schema = { "properties": { # Schema definitions here }, "required": ["language", "sentiment", "aggressiveness"],
} chain = create_tagging_chain(schema, llm)
Τα πυδαντικά σχήματα μπορούν επίσης να χρησιμοποιηθούν για τον καθορισμό κριτηρίων προσθήκης ετικετών, παρέχοντας έναν Pythonic τρόπο για τον καθορισμό των απαιτούμενων ιδιοτήτων και τύπων:
from enum import Enum
from pydantic import BaseModel, Field class Tags(BaseModel): # Class fields here chain = create_tagging_chain_pydantic(Tags, llm)
Επιπλέον, ο μετασχηματιστής εγγράφων tagger μεταδεδομένων της LangChain μπορεί να χρησιμοποιηθεί για την εξαγωγή μεταδεδομένων από τα έγγραφα LangChain, προσφέροντας παρόμοια λειτουργικότητα με την αλυσίδα επισήμανσης, αλλά εφαρμόζεται σε ένα έγγραφο LangChain.
Η αναφορά πηγών ανάκτησης είναι ένα άλλο χαρακτηριστικό του LangChain, χρησιμοποιώντας λειτουργίες OpenAI για εξαγωγή παραπομπών από κείμενο. Αυτό αποδεικνύεται στον ακόλουθο κώδικα:
from langchain.chains import create_citation_fuzzy_match_chain
from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
chain = create_citation_fuzzy_match_chain(llm)
# Further code for running the chain and displaying results
Στο LangChain, η αλυσίδα σε εφαρμογές Large Language Model (LLM) συνήθως περιλαμβάνει συνδυασμό ενός προτύπου προτροπής με ένα LLM και προαιρετικά έναν αναλυτή εξόδου. Ο συνιστώμενος τρόπος για να γίνει αυτό είναι μέσω της γλώσσας έκφρασης LangChain (LCEL), αν και υποστηρίζεται επίσης η παλαιού τύπου προσέγγιση LLMChain.
Χρησιμοποιώντας το LCEL, το BasePromptTemplate, το BaseLanguageModel και το BaseOutputParser όλα υλοποιούν τη διεπαφή Runnable και μπορούν εύκολα να μεταφερθούν το ένα στο άλλο. Ακολουθεί ένα παράδειγμα που αποδεικνύει αυτό:
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import StrOutputParser prompt = PromptTemplate.from_template( "What is a good name for a company that makes {product}?"
)
runnable = prompt | ChatOpenAI() | StrOutputParser()
runnable.invoke({"product": "colorful socks"})
# Output: 'VibrantSocks'
Η δρομολόγηση στο LangChain επιτρέπει τη δημιουργία μη ντετερμινιστικών αλυσίδων όπου η έξοδος ενός προηγούμενου βήματος καθορίζει το επόμενο βήμα. Αυτό βοηθά στη δόμηση και τη διατήρηση της συνέπειας στις αλληλεπιδράσεις με τα LLM. Για παράδειγμα, εάν έχετε δύο πρότυπα βελτιστοποιημένα για διαφορετικούς τύπους ερωτήσεων, μπορείτε να επιλέξετε το πρότυπο με βάση τα δεδομένα χρήστη.
Δείτε πώς μπορείτε να το επιτύχετε αυτό χρησιμοποιώντας το LCEL με ένα RunnableBranch, το οποίο προετοιμάζεται με μια λίστα ζευγών (συνθήκη, δυνατότητα εκτέλεσης) και μια προεπιλεγμένη δυνατότητα εκτέλεσης:
from langchain.chat_models import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnableBranch
# Code for defining physics_prompt and math_prompt general_prompt = PromptTemplate.from_template( "You are a helpful assistant. Answer the question as accurately as you can.nn{input}"
)
prompt_branch = RunnableBranch( (lambda x: x["topic"] == "math", math_prompt), (lambda x: x["topic"] == "physics", physics_prompt), general_prompt,
) # More code for setting up the classifier and final chain
Στη συνέχεια, η τελική αλυσίδα κατασκευάζεται χρησιμοποιώντας διάφορα στοιχεία, όπως έναν ταξινομητή θεμάτων, έναν κλάδο προτροπής και έναν αναλυτή εξόδου, για τον προσδιορισμό της ροής με βάση το θέμα της εισόδου:
from operator import itemgetter
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough final_chain = ( RunnablePassthrough.assign(topic=itemgetter("input") | classifier_chain) | prompt_branch | ChatOpenAI() | StrOutputParser()
) final_chain.invoke( { "input": "What is the first prime number greater than 40 such that one plus the prime number is divisible by 3?" }
)
# Output: Detailed answer to the math question
Αυτή η προσέγγιση αποτελεί παράδειγμα της ευελιξίας και της ισχύος του LangChain στον χειρισμό σύνθετων ερωτημάτων και στη δρομολόγησή τους κατάλληλα με βάση την είσοδο.
Στον τομέα των γλωσσικών μοντέλων, μια κοινή πρακτική είναι η παρακολούθηση μιας αρχικής κλήσης με μια σειρά από επόμενες κλήσεις, χρησιμοποιώντας την έξοδο μιας κλήσης ως είσοδο για την επόμενη. Αυτή η διαδοχική προσέγγιση είναι ιδιαίτερα ωφέλιμη όταν θέλετε να αξιοποιήσετε τις πληροφορίες που δημιουργήθηκαν σε προηγούμενες αλληλεπιδράσεις. Ενώ η γλώσσα έκφρασης LangChain (LCEL) είναι η προτεινόμενη μέθοδος για τη δημιουργία αυτών των ακολουθιών, η μέθοδος SequentialChain εξακολουθεί να είναι τεκμηριωμένη για τη συμβατότητά της προς τα πίσω.
Για να το δείξουμε αυτό, ας εξετάσουμε ένα σενάριο όπου δημιουργούμε πρώτα μια σύνοψη του παιχνιδιού και μετά μια ανασκόπηση που βασίζεται σε αυτήν τη σύνοψη. Χρησιμοποιώντας Python langchain.prompts
, δημιουργούμε δύο PromptTemplate
περιπτώσεις: ένα για τη σύνοψη και ένα άλλο για την ανασκόπηση. Ακολουθεί ο κώδικας για τη ρύθμιση αυτών των προτύπων:
from langchain.prompts import PromptTemplate synopsis_prompt = PromptTemplate.from_template( "You are a playwright. Given the title of play, it is your job to write a synopsis for that title.nnTitle: {title}nPlaywright: This is a synopsis for the above play:"
) review_prompt = PromptTemplate.from_template( "You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.nnPlay Synopsis:n{synopsis}nReview from a New York Times play critic of the above play:"
)
Στην προσέγγιση LCEL, συνδέουμε αυτές τις προτροπές με ChatOpenAI
και StrOutputParser
για να δημιουργήσετε μια ακολουθία που δημιουργεί πρώτα μια σύνοψη και μετά μια ανασκόπηση. Το απόσπασμα κώδικα έχει ως εξής:
from langchain.chat_models import ChatOpenAI
from langchain.schema import StrOutputParser llm = ChatOpenAI()
chain = ( {"synopsis": synopsis_prompt | llm | StrOutputParser()} | review_prompt | llm | StrOutputParser()
)
chain.invoke({"title": "Tragedy at sunset on the beach"})
Εάν χρειαζόμαστε τόσο τη σύνοψη όσο και την αναθεώρηση, μπορούμε να χρησιμοποιήσουμε RunnablePassthrough
για να δημιουργήσετε μια ξεχωριστή αλυσίδα για το καθένα και στη συνέχεια να τα συνδυάσετε:
from langchain.schema.runnable import RunnablePassthrough synopsis_chain = synopsis_prompt | llm | StrOutputParser()
review_chain = review_prompt | llm | StrOutputParser()
chain = {"synopsis": synopsis_chain} | RunnablePassthrough.assign(review=review_chain)
chain.invoke({"title": "Tragedy at sunset on the beach"})
Για σενάρια που περιλαμβάνουν πιο σύνθετες ακολουθίες, το SequentialChain
η μέθοδος μπαίνει στο παιχνίδι. Αυτό επιτρέπει πολλαπλές εισόδους και εξόδους. Σκεφτείτε μια περίπτωση όπου χρειαζόμαστε μια σύνοψη βασισμένη στον τίτλο και την εποχή ενός έργου. Δείτε πώς μπορούμε να το ρυθμίσουμε:
from langchain.llms import OpenAI
from langchain.chains import LLMChain, SequentialChain
from langchain.prompts import PromptTemplate llm = OpenAI(temperature=0.7) synopsis_template = "You are a playwright. Given the title of play and the era it is set in, it is your job to write a synopsis for that title.nnTitle: {title}nEra: {era}nPlaywright: This is a synopsis for the above play:"
synopsis_prompt_template = PromptTemplate(input_variables=["title", "era"], template=synopsis_template)
synopsis_chain = LLMChain(llm=llm, prompt=synopsis_prompt_template, output_key="synopsis") review_template = "You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.nnPlay Synopsis:n{synopsis}nReview from a New York Times play critic of the above play:"
prompt_template = PromptTemplate(input_variables=["synopsis"], template=review_template)
review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="review") overall_chain = SequentialChain( chains=[synopsis_chain, review_chain], input_variables=["era", "title"], output_variables=["synopsis", "review"], verbose=True,
) overall_chain({"title": "Tragedy at sunset on the beach", "era": "Victorian England"})
Σε σενάρια όπου θέλετε να διατηρήσετε το πλαίσιο σε μια αλυσίδα ή για ένα μεταγενέστερο μέρος της αλυσίδας, SimpleMemory
μπορεί να χρησιμοποιηθεί. Αυτό είναι ιδιαίτερα χρήσιμο για τη διαχείριση πολύπλοκων σχέσεων εισόδου/εξόδου. Για παράδειγμα, σε ένα σενάριο όπου θέλουμε να δημιουργήσουμε αναρτήσεις στα μέσα κοινωνικής δικτύωσης με βάση τον τίτλο, την εποχή, τη σύνοψη και την κριτική ενός έργου, SimpleMemory
μπορεί να βοηθήσει στη διαχείριση αυτών των μεταβλητών:
from langchain.memory import SimpleMemory
from langchain.chains import SequentialChain template = "You are a social media manager for a theater company. Given the title of play, the era it is set in, the date, time and location, the synopsis of the play, and the review of the play, it is your job to write a social media post for that play.nnHere is some context about the time and location of the play:nDate and Time: {time}nLocation: {location}nnPlay Synopsis:n{synopsis}nReview from a New York Times play critic of the above play:n{review}nnSocial Media Post:"
prompt_template = PromptTemplate(input_variables=["synopsis", "review", "time", "location"], template=template)
social_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="social_post_text") overall_chain = SequentialChain( memory=SimpleMemory(memories={"time": "December 25th, 8pm PST", "location": "Theater in the Park"}), chains=[synopsis_chain, review_chain, social_chain], input_variables=["era", "title"], output_variables=["social_post_text"], verbose=True,
) overall_chain({"title": "Tragedy at sunset on the beach", "era": "Victorian England"})
Εκτός από τις διαδοχικές αλυσίδες, υπάρχουν εξειδικευμένες αλυσίδες για εργασία με έγγραφα. Κάθε μία από αυτές τις αλυσίδες εξυπηρετεί διαφορετικό σκοπό, από το συνδυασμό εγγράφων έως τη βελτίωση των απαντήσεων που βασίζονται σε επαναληπτική ανάλυση εγγράφων, έως τη χαρτογράφηση και τη μείωση του περιεχομένου των εγγράφων για σύνοψη ή την ανακατάταξη με βάση τις βαθμολογημένες απαντήσεις. Αυτές οι αλυσίδες μπορούν να αναδημιουργηθούν με το LCEL για πρόσθετη ευελιξία και προσαρμογή.
-
StuffDocumentsChain
συνδυάζει μια λίστα εγγράφων σε μια ενιαία προτροπή που μεταβιβάζεται σε ένα LLM. -
RefineDocumentsChain
ενημερώνει την απάντησή του επαναληπτικά για κάθε έγγραφο, κατάλληλο για εργασίες όπου τα έγγραφα υπερβαίνουν τη χωρητικότητα περιβάλλοντος του μοντέλου. -
MapReduceDocumentsChain
εφαρμόζει μια αλυσίδα σε κάθε έγγραφο ξεχωριστά και στη συνέχεια συνδυάζει τα αποτελέσματα. -
MapRerankDocumentsChain
βαθμολογεί κάθε απάντηση που βασίζεται σε έγγραφο και επιλέγει αυτή με την υψηλότερη βαθμολογία.
Ακολουθεί ένα παράδειγμα για το πώς μπορείτε να ρυθμίσετε ένα MapReduceDocumentsChain
χρησιμοποιώντας LCEL:
from functools import partial
from langchain.chains.combine_documents import collapse_docs, split_list_of_docs
from langchain.schema import Document, StrOutputParser
from langchain.schema.prompt_template import format_document
from langchain.schema.runnable import RunnableParallel, RunnablePassthrough llm = ChatAnthropic()
document_prompt = PromptTemplate.from_template("{page_content}")
partial_format_document = partial(format_document, prompt=document_prompt) map_chain = ( {"context": partial_format_document} | PromptTemplate.from_template("Summarize this content:nn{context}") | llm | StrOutputParser()
) map_as_doc_chain = ( RunnableParallel({"doc": RunnablePassthrough(), "content": map_chain}) | (lambda x: Document(page_content=x["content"], metadata=x["doc"].metadata))
).with_config(run_name="Summarize (return doc)") def format_docs(docs): return "nn".join(partial_format_document(doc) for doc in docs) collapse_chain = ( {"context": format_docs} | PromptTemplate.from_template("Collapse this content:nn{context}") | llm | StrOutputParser()
) reduce_chain = ( {"context": format_docs} | PromptTemplate.from_template("Combine these summaries:nn{context}") | llm | StrOutputParser()
).with_config(run_name="Reduce") map_reduce = (map_as_doc_chain.map() | collapse | reduce_chain).with_config(run_name="Map reduce")
Αυτή η διαμόρφωση επιτρέπει μια λεπτομερή και ολοκληρωμένη ανάλυση του περιεχομένου του εγγράφου, αξιοποιώντας τα δυνατά σημεία του LCEL και του υποκείμενου γλωσσικού μοντέλου.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
Ενότητα V : Μνήμη
Στο LangChain, η μνήμη είναι μια θεμελιώδης πτυχή των διεπαφών συνομιλίας, επιτρέποντας στα συστήματα να αναφέρονται σε προηγούμενες αλληλεπιδράσεις. Αυτό επιτυγχάνεται μέσω της αποθήκευσης και αναζήτησης πληροφοριών, με δύο κύριες ενέργειες: την ανάγνωση και τη γραφή. Το σύστημα μνήμης αλληλεπιδρά με μια αλυσίδα δύο φορές κατά τη διάρκεια μιας εκτέλεσης, αυξάνοντας τις εισόδους του χρήστη και αποθηκεύοντας τις εισόδους και τις εξόδους για μελλοντική αναφορά.
Χτίζοντας τη μνήμη σε ένα σύστημα
- Αποθήκευση μηνυμάτων συνομιλίας: Η μονάδα μνήμης LangChain ενσωματώνει διάφορες μεθόδους αποθήκευσης μηνυμάτων συνομιλίας, που κυμαίνονται από λίστες στη μνήμη έως βάσεις δεδομένων. Αυτό διασφαλίζει ότι όλες οι αλληλεπιδράσεις συνομιλίας καταγράφονται για μελλοντική αναφορά.
- Ερώτηση μηνυμάτων συνομιλίας: Πέρα από την αποθήκευση μηνυμάτων συνομιλίας, το LangChain χρησιμοποιεί δομές δεδομένων και αλγόριθμους για να δημιουργήσει μια χρήσιμη προβολή αυτών των μηνυμάτων. Τα απλά συστήματα μνήμης ενδέχεται να επιστρέφουν πρόσφατα μηνύματα, ενώ τα πιο προηγμένα συστήματα θα μπορούσαν να συνοψίσουν προηγούμενες αλληλεπιδράσεις ή να επικεντρωθούν σε οντότητες που αναφέρονται στην τρέχουσα αλληλεπίδραση.
Για να δείξετε τη χρήση της μνήμης στο LangChain, εξετάστε το ConversationBufferMemory
class, μια απλή φόρμα μνήμης που αποθηκεύει μηνύματα συνομιλίας σε buffer. Εδώ είναι ένα παράδειγμα:
from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory()
memory.chat_memory.add_user_message("Hello!")
memory.chat_memory.add_ai_message("How can I assist you?")
Όταν ενσωματώνετε τη μνήμη σε μια αλυσίδα, είναι σημαντικό να κατανοήσετε τις μεταβλητές που επιστρέφονται από τη μνήμη και πώς χρησιμοποιούνται στην αλυσίδα. Για παράδειγμα, το load_memory_variables
Η μέθοδος βοηθά στην ευθυγράμμιση των μεταβλητών που διαβάζονται από τη μνήμη με τις προσδοκίες της αλυσίδας.
Παράδειγμα από άκρη σε άκρη με το LangChain
Σκεφτείτε να χρησιμοποιήσετε ConversationBufferMemory
σε ένα LLMChain
. Η αλυσίδα, σε συνδυασμό με ένα κατάλληλο πρότυπο προτροπής και τη μνήμη, παρέχει μια απρόσκοπτη εμπειρία συνομιλίας. Ακολουθεί ένα απλοποιημένο παράδειγμα:
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory llm = OpenAI(temperature=0)
template = "Your conversation template here..."
prompt = PromptTemplate.from_template(template)
memory = ConversationBufferMemory(memory_key="chat_history")
conversation = LLMChain(llm=llm, prompt=prompt, memory=memory) response = conversation({"question": "What's the weather like?"})
Αυτό το παράδειγμα επεξηγεί πώς το σύστημα μνήμης του LangChain ενσωματώνεται με τις αλυσίδες του για να παρέχει μια συνεκτική και συνειδητή εμπειρία συνομιλίας.
Τύποι μνήμης στο Langchain
Η Langchain προσφέρει διάφορους τύπους μνήμης που μπορούν να χρησιμοποιηθούν για τη βελτίωση των αλληλεπιδράσεων με τα μοντέλα AI. Κάθε τύπος μνήμης έχει τις δικές του παραμέτρους και τύπους επιστροφής, καθιστώντας τους κατάλληλους για διαφορετικά σενάρια. Ας εξερευνήσουμε μερικούς από τους τύπους μνήμης που είναι διαθέσιμοι στο Langchain μαζί με παραδείγματα κώδικα.
1. Μνήμη προσωρινής μνήμης συνομιλίας
Αυτός ο τύπος μνήμης σάς επιτρέπει να αποθηκεύετε και να εξάγετε μηνύματα από συνομιλίες. Μπορείτε να εξαγάγετε το ιστορικό ως συμβολοσειρά ή ως λίστα μηνυμάτων.
from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory()
memory.save_context({"input": "hi"}, {"output": "whats up"})
memory.load_memory_variables({}) # Extract history as a string
{'history': 'Human: hinAI: whats up'} # Extract history as a list of messages
{'history': [HumanMessage(content='hi', additional_kwargs={}), AIMessage(content='whats up', additional_kwargs={})]}
Μπορείτε επίσης να χρησιμοποιήσετε την προσωρινή μνήμη συνομιλίας σε μια αλυσίδα για αλληλεπιδράσεις που μοιάζουν με συνομιλίες.
2. Μνήμη παραθύρου buffer συνομιλίας
Αυτός ο τύπος μνήμης διατηρεί μια λίστα με πρόσφατες αλληλεπιδράσεις και χρησιμοποιεί τις τελευταίες αλληλεπιδράσεις K, αποτρέποντας την υπερβολική αύξηση του buffer.
from langchain.memory import ConversationBufferWindowMemory memory = ConversationBufferWindowMemory(k=1)
memory.save_context({"input": "hi"}, {"output": "whats up"})
memory.save_context({"input": "not much you"}, {"output": "not much"})
memory.load_memory_variables({}) {'history': 'Human: not much younAI: not much'}
Όπως το Conversation Buffer Memory, μπορείτε επίσης να χρησιμοποιήσετε αυτόν τον τύπο μνήμης σε μια αλυσίδα για αλληλεπιδράσεις τύπου συνομιλίας.
3. Μνήμη οντότητας συνομιλίας
Αυτός ο τύπος μνήμης θυμάται γεγονότα για συγκεκριμένες οντότητες σε μια συνομιλία και εξάγει πληροφορίες χρησιμοποιώντας ένα LLM.
from langchain.memory import ConversationEntityMemory
from langchain.llms import OpenAI llm = OpenAI(temperature=0)
memory = ConversationEntityMemory(llm=llm)
_input = {"input": "Deven & Sam are working on a hackathon project"}
memory.load_memory_variables(_input)
memory.save_context( _input, {"output": " That sounds like a great project! What kind of project are they working on?"}
)
memory.load_memory_variables({"input": 'who is Sam'}) {'history': 'Human: Deven & Sam are working on a hackathon projectnAI: That sounds like a great project! What kind of project are they working on?', 'entities': {'Sam': 'Sam is working on a hackathon project with Deven.'}}
4. Μνήμη γραφήματος γνώσης συνομιλίας
Αυτός ο τύπος μνήμης χρησιμοποιεί ένα γράφημα γνώσης για να αναδημιουργήσει τη μνήμη. Μπορείτε να εξαγάγετε τρέχουσες οντότητες και τριπλέτες γνώσεων από μηνύματα.
from langchain.memory import ConversationKGMemory
from langchain.llms import OpenAI llm = OpenAI(temperature=0)
memory = ConversationKGMemory(llm=llm)
memory.save_context({"input": "say hi to sam"}, {"output": "who is sam"})
memory.save_context({"input": "sam is a friend"}, {"output": "okay"})
memory.load_memory_variables({"input": "who is sam"}) {'history': 'On Sam: Sam is friend.'}
Μπορείτε επίσης να χρησιμοποιήσετε αυτόν τον τύπο μνήμης σε μια αλυσίδα για ανάκτηση γνώσης βάσει συνομιλιών.
5. Μνήμη περίληψης συνομιλίας
Αυτός ο τύπος μνήμης δημιουργεί μια περίληψη της συνομιλίας με την πάροδο του χρόνου, χρήσιμη για τη συμπύκνωση πληροφοριών από μεγαλύτερες συνομιλίες.
from langchain.memory import ConversationSummaryMemory
from langchain.llms import OpenAI llm = OpenAI(temperature=0)
memory = ConversationSummaryMemory(llm=llm)
memory.save_context({"input": "hi"}, {"output": "whats up"})
memory.load_memory_variables({}) {'history': 'nThe human greets the AI, to which the AI responds.'}
6. Μνήμη buffer περίληψης συνομιλίας
Αυτός ο τύπος μνήμης συνδυάζει τη σύνοψη συνομιλίας και την προσωρινή μνήμη, διατηρώντας μια ισορροπία μεταξύ των πρόσφατων αλληλεπιδράσεων και μιας σύνοψης. Χρησιμοποιεί μήκος διακριτικού για να καθορίσει πότε πρέπει να ξεπλυθούν οι αλληλεπιδράσεις.
from langchain.memory import ConversationSummaryBufferMemory
from langchain.llms import OpenAI llm = OpenAI()
memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=10)
memory.save_context({"input": "hi"}, {"output": "whats up"})
memory.save_context({"input": "not much you"}, {"output": "not much"})
memory.load_memory_variables({}) {'history': 'System: nThe human says "hi", and the AI responds with "whats up".nHuman: not much younAI: not much'}
Μπορείτε να χρησιμοποιήσετε αυτούς τους τύπους μνήμης για να βελτιώσετε τις αλληλεπιδράσεις σας με μοντέλα τεχνητής νοημοσύνης στο Langchain. Κάθε τύπος μνήμης εξυπηρετεί έναν συγκεκριμένο σκοπό και μπορεί να επιλεγεί με βάση τις απαιτήσεις σας.
7. Μνήμη προσωρινής μνήμης διακριτικού συνομιλίας
Το ConversationTokenBufferMemory είναι ένας άλλος τύπος μνήμης που διατηρεί ένα buffer πρόσφατων αλληλεπιδράσεων στη μνήμη. Σε αντίθεση με τους προηγούμενους τύπους μνήμης που εστιάζουν στον αριθμό των αλληλεπιδράσεων, αυτός χρησιμοποιεί μήκος διακριτικού για να καθορίσει πότε πρέπει να ξεπλυθούν οι αλληλεπιδράσεις.
Χρήση μνήμης με LLM:
from langchain.memory import ConversationTokenBufferMemory
from langchain.llms import OpenAI llm = OpenAI() memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=10)
memory.save_context({"input": "hi"}, {"output": "whats up"})
memory.save_context({"input": "not much you"}, {"output": "not much"}) memory.load_memory_variables({}) {'history': 'Human: not much younAI: not much'}
Σε αυτό το παράδειγμα, η μνήμη έχει ρυθμιστεί να περιορίζει τις αλληλεπιδράσεις με βάση το μήκος διακριτικού και όχι τον αριθμό των αλληλεπιδράσεων.
Μπορείτε επίσης να λάβετε το ιστορικό ως λίστα μηνυμάτων όταν χρησιμοποιείτε αυτόν τον τύπο μνήμης.
memory = ConversationTokenBufferMemory( llm=llm, max_token_limit=10, return_messages=True
)
memory.save_context({"input": "hi"}, {"output": "whats up"})
memory.save_context({"input": "not much you"}, {"output": "not much"})
Χρήση σε αλυσίδα:
Μπορείτε να χρησιμοποιήσετε το ConversationTokenBufferMemory σε μια αλυσίδα για να βελτιώσετε τις αλληλεπιδράσεις με το μοντέλο AI.
from langchain.chains import ConversationChain conversation_with_summary = ConversationChain( llm=llm, # We set a very low max_token_limit for the purposes of testing. memory=ConversationTokenBufferMemory(llm=OpenAI(), max_token_limit=60), verbose=True,
)
conversation_with_summary.predict(input="Hi, what's up?")
Σε αυτό το παράδειγμα, το ConversationTokenBufferMemory χρησιμοποιείται σε ένα ConversationChain για τη διαχείριση της συνομιλίας και τον περιορισμό των αλληλεπιδράσεων με βάση το μήκος του διακριτικού.
8. VectorStoreRetrieverMemory
Το VectorStoreRetrieverMemory αποθηκεύει τις μνήμες σε ένα διανυσματικό κατάστημα και ρωτά τα κορυφαία K πιο «εξέχοντα» έγγραφα κάθε φορά που καλείται. Αυτός ο τύπος μνήμης δεν παρακολουθεί ρητά τη σειρά των αλληλεπιδράσεων, αλλά χρησιμοποιεί την ανάκτηση διανυσμάτων για την ανάκτηση σχετικών αναμνήσεων.
from datetime import datetime
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate # Initialize your vector store (specifics depend on the chosen vector store)
import faiss
from langchain.docstore import InMemoryDocstore
from langchain.vectorstores import FAISS embedding_size = 1536 # Dimensions of the OpenAIEmbeddings
index = faiss.IndexFlatL2(embedding_size)
embedding_fn = OpenAIEmbeddings().embed_query
vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {}) # Create your VectorStoreRetrieverMemory
retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))
memory = VectorStoreRetrieverMemory(retriever=retriever) # Save context and relevant information to the memory
memory.save_context({"input": "My favorite food is pizza"}, {"output": "that's good to know"})
memory.save_context({"input": "My favorite sport is soccer"}, {"output": "..."})
memory.save_context({"input": "I don't like the Celtics"}, {"output": "ok"}) # Retrieve relevant information from memory based on a query
print(memory.load_memory_variables({"prompt": "what sport should i watch?"})["history"])
Σε αυτό το παράδειγμα, το VectorStoreRetrieverMemory χρησιμοποιείται για την αποθήκευση και ανάκτηση σχετικών πληροφοριών από μια συνομιλία που βασίζεται στην ανάκτηση διανύσματος.
Μπορείτε επίσης να χρησιμοποιήσετε το VectorStoreRetrieverMemory σε μια αλυσίδα για ανάκτηση γνώσης που βασίζεται σε συνομιλίες, όπως φαίνεται στα προηγούμενα παραδείγματα.
Αυτοί οι διαφορετικοί τύποι μνήμης στο Langchain παρέχουν διάφορους τρόπους διαχείρισης και ανάκτησης πληροφοριών από συνομιλίες, ενισχύοντας τις δυνατότητες των μοντέλων τεχνητής νοημοσύνης να κατανοούν και να ανταποκρίνονται στα ερωτήματα και το πλαίσιο των χρηστών. Κάθε τύπος μνήμης μπορεί να επιλεγεί με βάση τις συγκεκριμένες απαιτήσεις της εφαρμογής σας.
Τώρα θα μάθουμε πώς να χρησιμοποιούμε τη μνήμη με μια αλυσίδα LLMC. Η μνήμη σε μια αλυσίδα LLMC επιτρέπει στο μοντέλο να θυμάται προηγούμενες αλληλεπιδράσεις και περιβάλλον για να παρέχει πιο συνεκτικές και συνειδητοποιημένες απαντήσεις.
Για να ρυθμίσετε τη μνήμη σε μια αλυσίδα LLMChain, πρέπει να δημιουργήσετε μια κλάση μνήμης, όπως το ConversationBufferMemory. Δείτε πώς μπορείτε να το ρυθμίσετε:
from langchain.chains import LLMChain
from langchain.llms import OpenAI
from langchain.memory import ConversationBufferMemory
from langchain.prompts import PromptTemplate template = """You are a chatbot having a conversation with a human. {chat_history}
Human: {human_input}
Chatbot:""" prompt = PromptTemplate( input_variables=["chat_history", "human_input"], template=template
)
memory = ConversationBufferMemory(memory_key="chat_history") llm = OpenAI()
llm_chain = LLMChain( llm=llm, prompt=prompt, verbose=True, memory=memory,
) llm_chain.predict(human_input="Hi there my friend")
Σε αυτό το παράδειγμα, το ConversationBufferMemory χρησιμοποιείται για την αποθήκευση του ιστορικού συνομιλιών. ο memory_key
Η παράμετρος καθορίζει το κλειδί που χρησιμοποιείται για την αποθήκευση του ιστορικού συνομιλιών.
Εάν χρησιμοποιείτε ένα μοντέλο συνομιλίας αντί για ένα μοντέλο τύπου ολοκλήρωσης, μπορείτε να δομήσετε διαφορετικά τα μηνύματα προτροπής για να χρησιμοποιήσετε καλύτερα τη μνήμη. Ακολουθεί ένα παράδειγμα για το πώς να ρυθμίσετε ένα LLMCchain που βασίζεται σε μοντέλο συνομιλίας με μνήμη:
from langchain.chat_models import ChatOpenAI
from langchain.schema import SystemMessage
from langchain.prompts import ( ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder,
) # Create a ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages( [ SystemMessage( content="You are a chatbot having a conversation with a human." ), # The persistent system prompt MessagesPlaceholder( variable_name="chat_history" ), # Where the memory will be stored. HumanMessagePromptTemplate.from_template( "{human_input}" ), # Where the human input will be injected ]
) memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) llm = ChatOpenAI() chat_llm_chain = LLMChain( llm=llm, prompt=prompt, verbose=True, memory=memory,
) chat_llm_chain.predict(human_input="Hi there my friend")
Σε αυτό το παράδειγμα, το ChatPromptTemplate χρησιμοποιείται για τη δομή της προτροπής και το ConversationBufferMemory χρησιμοποιείται για την αποθήκευση και την ανάκτηση του ιστορικού συνομιλιών. Αυτή η προσέγγιση είναι ιδιαίτερα χρήσιμη για συνομιλίες τύπου συνομιλίας όπου το πλαίσιο και η ιστορία διαδραματίζουν κρίσιμο ρόλο.
Η μνήμη μπορεί επίσης να προστεθεί σε μια αλυσίδα με πολλαπλές εισόδους, όπως μια αλυσίδα ερωτήσεων/απαντήσεων. Ακολουθεί ένα παράδειγμα για το πώς να ρυθμίσετε τη μνήμη σε μια αλυσίδα ερωτήσεων/απαντήσεων:
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.embeddings.cohere import CohereEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores.elastic_vector_search import ElasticVectorSearch
from langchain.vectorstores import Chroma
from langchain.docstore.document import Document
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory # Split a long document into smaller chunks
with open("../../state_of_the_union.txt") as f: state_of_the_union = f.read()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_text(state_of_the_union) # Create an ElasticVectorSearch instance to index and search the document chunks
embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_texts( texts, embeddings, metadatas=[{"source": i} for i in range(len(texts))]
) # Perform a question about the document
query = "What did the president say about Justice Breyer"
docs = docsearch.similarity_search(query) # Set up a prompt for the question-answering chain with memory
template = """You are a chatbot having a conversation with a human. Given the following extracted parts of a long document and a question, create a final answer. {context} {chat_history}
Human: {human_input}
Chatbot:""" prompt = PromptTemplate( input_variables=["chat_history", "human_input", "context"], template=template
)
memory = ConversationBufferMemory(memory_key="chat_history", input_key="human_input")
chain = load_qa_chain( OpenAI(temperature=0), chain_type="stuff", memory=memory, prompt=prompt
) # Ask the question and retrieve the answer
query = "What did the president say about Justice Breyer"
result = chain({"input_documents": docs, "human_input": query}, return_only_outputs=True) print(result)
print(chain.memory.buffer)
Σε αυτό το παράδειγμα, μια ερώτηση απαντάται χρησιμοποιώντας ένα έγγραφο χωρισμένο σε μικρότερα κομμάτια. Το ConversationBufferMemory χρησιμοποιείται για την αποθήκευση και την ανάκτηση του ιστορικού συνομιλιών, επιτρέποντας στο μοντέλο να παρέχει απαντήσεις με επίγνωση του περιβάλλοντος.
Η προσθήκη μνήμης σε έναν πράκτορα του επιτρέπει να θυμάται και να χρησιμοποιεί προηγούμενες αλληλεπιδράσεις για να απαντά σε ερωτήσεις και να παρέχει απαντήσεις με επίγνωση του πλαισίου. Δείτε πώς μπορείτε να ρυθμίσετε τη μνήμη σε έναν πράκτορα:
from langchain.agents import ZeroShotAgent, Tool, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.utilities import GoogleSearchAPIWrapper # Create a tool for searching
search = GoogleSearchAPIWrapper()
tools = [ Tool( name="Search", func=search.run, description="useful for when you need to answer questions about current events", )
] # Create a prompt with memory
prefix = """Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:"""
suffix = """Begin!" {chat_history}
Question: {input}
{agent_scratchpad}""" prompt = ZeroShotAgent.create_prompt( tools, prefix=prefix, suffix=suffix, input_variables=["input", "chat_history", "agent_scratchpad"],
)
memory = ConversationBufferMemory(memory_key="chat_history") # Create an LLMChain with memory
llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)
agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=True)
agent_chain = AgentExecutor.from_agent_and_tools( agent=agent, tools=tools, verbose=True, memory=memory
) # Ask a question and retrieve the answer
response = agent_chain.run(input="How many people live in Canada?")
print(response) # Ask a follow-up question
response = agent_chain.run(input="What is their national anthem called?")
print(response)
Σε αυτό το παράδειγμα, η μνήμη προστίθεται σε έναν πράκτορα, επιτρέποντάς του να θυμάται το προηγούμενο ιστορικό συνομιλιών και να παρέχει απαντήσεις με επίγνωση του πλαισίου. Αυτό δίνει τη δυνατότητα στον πράκτορα να απαντά στις επακόλουθες ερωτήσεις με ακρίβεια με βάση τις πληροφορίες που είναι αποθηκευμένες στη μνήμη.
Γλώσσα έκφρασης LangChain
Στον κόσμο της επεξεργασίας φυσικής γλώσσας και της μηχανικής εκμάθησης, η σύνθεση σύνθετων αλυσίδων λειτουργιών μπορεί να είναι μια αποθαρρυντική εργασία. Ευτυχώς, η γλώσσα έκφρασης LangChain (LCEL) έρχεται στη διάσωση, παρέχοντας έναν δηλωτικό και αποτελεσματικό τρόπο για τη δημιουργία και την ανάπτυξη εξελιγμένων αγωγών επεξεργασίας γλώσσας. Το LCEL έχει σχεδιαστεί για να απλοποιεί τη διαδικασία σύνθεσης αλυσίδων, καθιστώντας δυνατή τη μετάβαση από το πρωτότυπο στην παραγωγή με ευκολία. Σε αυτό το ιστολόγιο, θα εξερευνήσουμε τι είναι το LCEL και γιατί μπορεί να θέλετε να το χρησιμοποιήσετε, μαζί με πρακτικά παραδείγματα κώδικα για να δείξουμε τις δυνατότητές του.
Το LCEL, ή LangChain Expression Language, είναι ένα ισχυρό εργαλείο για τη σύνθεση αλυσίδων επεξεργασίας γλώσσας. Κατασκευάστηκε ειδικά για να υποστηρίξει τη μετάβαση από το πρωτότυπο στην παραγωγή χωρίς προβλήματα, χωρίς να απαιτούνται εκτενείς αλλαγές κώδικα. Είτε κατασκευάζετε μια απλή αλυσίδα "prompt + LLM" είτε έναν περίπλοκο αγωγό με εκατοντάδες βήματα, το LCEL σας καλύπτει.
Ακολουθούν ορισμένοι λόγοι για να χρησιμοποιήσετε το LCEL στα έργα επεξεργασίας γλώσσας:
- Γρήγορη ροή διακριτικών: Το LCEL παραδίδει διακριτικά από ένα μοντέλο γλώσσας σε έναν αναλυτή εξόδου σε πραγματικό χρόνο, βελτιώνοντας την ανταπόκριση και την αποτελεσματικότητα.
- Ευέλικτα API: Το LCEL υποστηρίζει τόσο σύγχρονα όσο και ασύγχρονα API για χρήση πρωτοτύπων και παραγωγής, χειριζόμενη αποτελεσματικά πολλαπλά αιτήματα.
- Αυτόματη παραλληλοποίηση: Το LCEL βελτιστοποιεί την παράλληλη εκτέλεση όταν είναι δυνατό, μειώνοντας τον λανθάνοντα χρόνο τόσο στις διεπαφές συγχρονισμού όσο και στις ασύγχρονες.
- Αξιόπιστες διαμορφώσεις: Διαμορφώστε επαναλήψεις και εναλλακτικές λύσεις για βελτιωμένη αξιοπιστία αλυσίδας σε κλίμακα, με υποστήριξη ροής σε εξέλιξη.
- Ροή ενδιάμεσων αποτελεσμάτων: Πρόσβαση σε ενδιάμεσα αποτελέσματα κατά την επεξεργασία για ενημερώσεις χρήστη ή σκοπούς εντοπισμού σφαλμάτων.
- Δημιουργία σχήματος: Το LCEL δημιουργεί σχήματα Pydantic και JSONSchema για επικύρωση εισόδου και εξόδου.
- Ολοκληρωμένη ανίχνευση: Ο LangSmith εντοπίζει αυτόματα όλα τα βήματα σε πολύπλοκες αλυσίδες για παρατηρησιμότητα και εντοπισμό σφαλμάτων.
- Εύκολη ανάπτυξη: Αναπτύξτε αλυσίδες που έχουν δημιουργηθεί με LCEL χωρίς κόπο χρησιμοποιώντας το LangServe.
Τώρα, ας βουτήξουμε σε πρακτικά παραδείγματα κώδικα που δείχνουν τη δύναμη του LCEL. Θα εξερευνήσουμε κοινές εργασίες και σενάρια όπου το LCEL λάμπει.
Prompt + LLM
Η πιο θεμελιώδης σύνθεση περιλαμβάνει τον συνδυασμό μιας προτροπής και ενός μοντέλου γλώσσας για τη δημιουργία μιας αλυσίδας που λαμβάνει τα στοιχεία του χρήστη, τα προσθέτει σε μια προτροπή, τη μεταβιβάζει σε ένα μοντέλο και επιστρέφει την έξοδο του πρωτογενούς μοντέλου. Εδώ είναι ένα παράδειγμα:
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI prompt = ChatPromptTemplate.from_template("tell me a joke about {foo}")
model = ChatOpenAI()
chain = prompt | model result = chain.invoke({"foo": "bears"})
print(result)
Σε αυτό το παράδειγμα, η αλυσίδα δημιουργεί ένα αστείο για τις αρκούδες.
Μπορείτε να επισυνάψετε ακολουθίες διακοπής στην αλυσίδα σας για να ελέγξετε τον τρόπο με τον οποίο επεξεργάζεται το κείμενο. Για παράδειγμα:
chain = prompt | model.bind(stop=["n"])
result = chain.invoke({"foo": "bears"})
print(result)
Αυτή η διαμόρφωση σταματά τη δημιουργία κειμένου όταν συναντάται χαρακτήρας νέας γραμμής.
Το LCEL υποστηρίζει την προσάρτηση πληροφοριών κλήσης λειτουργίας στην αλυσίδα σας. Εδώ είναι ένα παράδειγμα:
functions = [ { "name": "joke", "description": "A joke", "parameters": { "type": "object", "properties": { "setup": {"type": "string", "description": "The setup for the joke"}, "punchline": { "type": "string", "description": "The punchline for the joke", }, }, "required": ["setup", "punchline"], }, }
]
chain = prompt | model.bind(function_call={"name": "joke"}, functions=functions)
result = chain.invoke({"foo": "bears"}, config={})
print(result)
Αυτό το παράδειγμα επισυνάπτει πληροφορίες κλήσης συνάρτησης για να δημιουργήσει ένα αστείο.
Prompt + LLM + OutputParser
Μπορείτε να προσθέσετε έναν αναλυτή εξόδου για να μετατρέψετε την έξοδο του πρωτογενούς μοντέλου σε μια πιο εφαρμόσιμη μορφή. Δείτε πώς μπορείτε να το κάνετε:
from langchain.schema.output_parser import StrOutputParser chain = prompt | model | StrOutputParser()
result = chain.invoke({"foo": "bears"})
print(result)
Η έξοδος είναι πλέον σε μορφή συμβολοσειράς, η οποία είναι πιο βολική για εργασίες κατάντη.
Όταν καθορίζετε μια συνάρτηση προς επιστροφή, μπορείτε να την αναλύσετε απευθείας χρησιμοποιώντας το LCEL. Για παράδειγμα:
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser chain = ( prompt | model.bind(function_call={"name": "joke"}, functions=functions) | JsonOutputFunctionsParser()
)
result = chain.invoke({"foo": "bears"})
print(result)
Αυτό το παράδειγμα αναλύει απευθείας την έξοδο της συνάρτησης "joke".
Αυτά είναι μόνο μερικά παραδείγματα για το πώς το LCEL απλοποιεί πολύπλοκες εργασίες επεξεργασίας γλώσσας. Είτε δημιουργείτε chatbot, είτε δημιουργείτε περιεχόμενο ή εκτελείτε πολύπλοκους μετασχηματισμούς κειμένου, το LCEL μπορεί να βελτιστοποιήσει τη ροή εργασίας σας και να κάνει τον κώδικά σας πιο διατηρητέο.
RAG (Αυξημένη γενιά ανάκτησης)
Το LCEL μπορεί να χρησιμοποιηθεί για τη δημιουργία αλυσίδων παραγωγής επαυξημένης ανάκτησης, οι οποίες συνδυάζουν βήματα ανάκτησης και δημιουργίας γλώσσας. Εδώ είναι ένα παράδειγμα:
from operator import itemgetter from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda
from langchain.vectorstores import FAISS # Create a vector store and retriever
vectorstore = FAISS.from_texts( ["harrison worked at kensho"], embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever() # Define templates for prompts
template = """Answer the question based only on the following context:
{context} Question: {question} """
prompt = ChatPromptTemplate.from_template(template) model = ChatOpenAI() # Create a retrieval-augmented generation chain
chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | model | StrOutputParser()
) result = chain.invoke("where did harrison work?")
print(result)
Σε αυτό το παράδειγμα, η αλυσίδα ανακτά σχετικές πληροφορίες από το περιβάλλον και δημιουργεί μια απάντηση στην ερώτηση.
Chanversational Retrieval Chain
Μπορείτε εύκολα να προσθέσετε ιστορικό συνομιλιών στις αλυσίδες σας. Ακολουθεί ένα παράδειγμα μιας αλυσίδας ανάκτησης συνομιλίας:
from langchain.schema.runnable import RunnableMap
from langchain.schema import format_document from langchain.prompts.prompt import PromptTemplate # Define templates for prompts
_template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language. Chat History:
{chat_history}
Follow Up Input: {question}
Standalone question:"""
CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template) template = """Answer the question based only on the following context:
{context} Question: {question} """
ANSWER_PROMPT = ChatPromptTemplate.from_template(template) # Define input map and context
_inputs = RunnableMap( standalone_question=RunnablePassthrough.assign( chat_history=lambda x: _format_chat_history(x["chat_history"]) ) | CONDENSE_QUESTION_PROMPT | ChatOpenAI(temperature=0) | StrOutputParser(),
)
_context = { "context": itemgetter("standalone_question") | retriever | _combine_documents, "question": lambda x: x["standalone_question"],
}
conversational_qa_chain = _inputs | _context | ANSWER_PROMPT | ChatOpenAI() result = conversational_qa_chain.invoke( { "question": "where did harrison work?", "chat_history": [], }
)
print(result)
Σε αυτό το παράδειγμα, η αλυσίδα χειρίζεται μια επόμενη ερώτηση μέσα σε ένα πλαίσιο συνομιλίας.
Με Μνήμη και Έγγραφα Πηγής Επιστροφής
Το LCEL υποστηρίζει επίσης τη μνήμη και την επιστροφή εγγράφων προέλευσης. Δείτε πώς μπορείτε να χρησιμοποιήσετε τη μνήμη σε μια αλυσίδα:
from operator import itemgetter
from langchain.memory import ConversationBufferMemory # Create a memory instance
memory = ConversationBufferMemory( return_messages=True, output_key="answer", input_key="question"
) # Define steps for the chain
loaded_memory = RunnablePassthrough.assign( chat_history=RunnableLambda(memory.load_memory_variables) | itemgetter("history"),
) standalone_question = { "standalone_question": { "question": lambda x: x["question"], "chat_history": lambda x: _format_chat_history(x["chat_history"]), } | CONDENSE_QUESTION_PROMPT | ChatOpenAI(temperature=0) | StrOutputParser(),
} retrieved_documents = { "docs": itemgetter("standalone_question") | retriever, "question": lambda x: x["standalone_question"],
} final_inputs = { "context": lambda x: _combine_documents(x["docs"]), "question": itemgetter("question"),
} answer = { "answer": final_inputs | ANSWER_PROMPT | ChatOpenAI(), "docs": itemgetter("docs"),
} # Create the final chain by combining the steps
final_chain = loaded_memory | standalone_question | retrieved_documents | answer inputs = {"question": "where did harrison work?"}
result = final_chain.invoke(inputs)
print(result)
Σε αυτό το παράδειγμα, η μνήμη χρησιμοποιείται για την αποθήκευση και ανάκτηση ιστορικού συνομιλιών και εγγράφων προέλευσης.
Πολλαπλές αλυσίδες
Μπορείτε να συνδέσετε πολλές αλυσίδες χρησιμοποιώντας το Runnables. Εδώ είναι ένα παράδειγμα:
from operator import itemgetter from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser prompt1 = ChatPromptTemplate.from_template("what is the city {person} is from?")
prompt2 = ChatPromptTemplate.from_template( "what country is the city {city} in? respond in {language}"
) model = ChatOpenAI() chain1 = prompt1 | model | StrOutputParser() chain2 = ( {"city": chain1, "language": itemgetter("language")} | prompt2 | model | StrOutputParser()
) result = chain2.invoke({"person": "obama", "language": "spanish"})
print(result)
Σε αυτό το παράδειγμα, δύο αλυσίδες συνδυάζονται για να δημιουργήσουν πληροφορίες για μια πόλη και τη χώρα της σε μια καθορισμένη γλώσσα.
Διακλάδωση και Συγχώνευση
Το LCEL σάς επιτρέπει να χωρίζετε και να συγχωνεύετε αλυσίδες χρησιμοποιώντας το RunnableMaps. Ακολουθεί ένα παράδειγμα διακλάδωσης και συγχώνευσης:
from operator import itemgetter from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser planner = ( ChatPromptTemplate.from_template("Generate an argument about: {input}") | ChatOpenAI() | StrOutputParser() | {"base_response": RunnablePassthrough()}
) arguments_for = ( ChatPromptTemplate.from_template( "List the pros or positive aspects of {base_response}" ) | ChatOpenAI() | StrOutputParser()
)
arguments_against = ( ChatPromptTemplate.from_template( "List the cons or negative aspects of {base_response}" ) | ChatOpenAI() | StrOutputParser()
) final_responder = ( ChatPromptTemplate.from_messages( [ ("ai", "{original_response}"), ("human", "Pros:n{results_1}nnCons:n{results_2}"), ("system", "Generate a final response given the critique"), ] ) | ChatOpenAI() | StrOutputParser()
) chain = ( planner | { "results_1": arguments_for, "results_2": arguments_against, "original_response": itemgetter("base_response"), } | final_responder
) result = chain.invoke({"input": "scrum"})
print(result)
Σε αυτό το παράδειγμα, μια αλυσίδα διακλάδωσης και συγχώνευσης χρησιμοποιείται για να δημιουργήσει ένα όρισμα και να αξιολογήσει τα πλεονεκτήματα και τα μειονεκτήματά του πριν δημιουργηθεί μια τελική απάντηση.
Γράψιμο κώδικα Python με LCEL
Μία από τις ισχυρές εφαρμογές της LangChain Expression Language (LCEL) είναι η συγγραφή κώδικα Python για την επίλυση προβλημάτων χρήστη. Παρακάτω είναι ένα παράδειγμα του τρόπου χρήσης του LCEL για τη σύνταξη κώδικα Python:
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain_experimental.utilities import PythonREPL template = """Write some python code to solve the user's problem. Return only python code in Markdown format, e.g.: ```python
....
```"""
prompt = ChatPromptTemplate.from_messages([("system", template), ("human", "{input}")]) model = ChatOpenAI() def _sanitize_output(text: str): _, after = text.split("```python") return after.split("```")[0] chain = prompt | model | StrOutputParser() | _sanitize_output | PythonREPL().run result = chain.invoke({"input": "what's 2 plus 2"})
print(result)
Σε αυτό το παράδειγμα, ένας χρήστης παρέχει είσοδο και το LCEL δημιουργεί κώδικα Python για να λύσει το πρόβλημα. Στη συνέχεια, ο κώδικας εκτελείται χρησιμοποιώντας ένα Python REPL και ο κώδικας Python που προκύπτει επιστρέφεται σε μορφή Markdown.
Λάβετε υπόψη ότι η χρήση ενός Python REPL μπορεί να εκτελέσει αυθαίρετο κώδικα, επομένως χρησιμοποιήστε τον με προσοχή.
Προσθήκη μνήμης σε αλυσίδα
Η μνήμη είναι απαραίτητη σε πολλές εφαρμογές τεχνητής νοημοσύνης συνομιλίας. Δείτε πώς μπορείτε να προσθέσετε μνήμη σε μια αυθαίρετη αλυσίδα:
from operator import itemgetter
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder model = ChatOpenAI()
prompt = ChatPromptTemplate.from_messages( [ ("system", "You are a helpful chatbot"), MessagesPlaceholder(variable_name="history"), ("human", "{input}"), ]
) memory = ConversationBufferMemory(return_messages=True) # Initialize memory
memory.load_memory_variables({}) chain = ( RunnablePassthrough.assign( history=RunnableLambda(memory.load_memory_variables) | itemgetter("history") ) | prompt | model
) inputs = {"input": "hi, I'm Bob"}
response = chain.invoke(inputs)
response # Save the conversation in memory
memory.save_context(inputs, {"output": response.content}) # Load memory to see the conversation history
memory.load_memory_variables({})
Σε αυτό το παράδειγμα, η μνήμη χρησιμοποιείται για την αποθήκευση και την ανάκτηση του ιστορικού συνομιλιών, επιτρέποντας στο chatbot να διατηρεί το πλαίσιο και να ανταποκρίνεται κατάλληλα.
Χρήση εξωτερικών εργαλείων με Runnables
Το LCEL σάς επιτρέπει να ενσωματώνετε απρόσκοπτα εξωτερικά εργαλεία με τα Runnables. Ακολουθεί ένα παράδειγμα χρησιμοποιώντας το εργαλείο αναζήτησης DuckDuckGo:
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.tools import DuckDuckGoSearchRun search = DuckDuckGoSearchRun() template = """Turn the following user input into a search query for a search engine: {input}"""
prompt = ChatPromptTemplate.from_template(template) model = ChatOpenAI() chain = prompt | model | StrOutputParser() | search search_result = chain.invoke({"input": "I'd like to figure out what games are tonight"})
print(search_result)
Σε αυτό το παράδειγμα, το LCEL ενσωματώνει το εργαλείο αναζήτησης DuckDuckGo στην αλυσίδα, επιτρέποντάς του να δημιουργήσει ένα ερώτημα αναζήτησης από τα στοιχεία του χρήστη και να ανακτήσει αποτελέσματα αναζήτησης.
Η ευελιξία του LCEL καθιστά εύκολη την ενσωμάτωση διαφόρων εξωτερικών εργαλείων και υπηρεσιών στους αγωγούς επεξεργασίας γλώσσας, ενισχύοντας τις δυνατότητες και τη λειτουργικότητά τους.
Προσθήκη εποπτείας σε μια εφαρμογή LLM
Για να διασφαλίσετε ότι η εφαρμογή LLM συμμορφώνεται με τις πολιτικές περιεχομένου και περιλαμβάνει διασφαλίσεις εποπτείας, μπορείτε να ενσωματώσετε ελέγχους εποπτείας στην αλυσίδα σας. Δείτε πώς μπορείτε να προσθέσετε εποπτεία χρησιμοποιώντας το LangChain:
from langchain.chains import OpenAIModerationChain
from langchain.llms import OpenAI
from langchain.prompts import ChatPromptTemplate moderate = OpenAIModerationChain() model = OpenAI()
prompt = ChatPromptTemplate.from_messages([("system", "repeat after me: {input}")]) chain = prompt | model # Original response without moderation
response_without_moderation = chain.invoke({"input": "you are stupid"})
print(response_without_moderation) moderated_chain = chain | moderate # Response after moderation
response_after_moderation = moderated_chain.invoke({"input": "you are stupid"})
print(response_after_moderation)
Σε αυτό το παράδειγμα, το OpenAIModerationChain
χρησιμοποιείται για να προσθέσει μέτρο στην απόκριση που δημιουργείται από το LLM. Η αλυσίδα εποπτείας ελέγχει την απόκριση για περιεχόμενο που παραβιάζει την πολιτική περιεχομένου του OpenAI. Εάν εντοπιστούν παραβάσεις, θα επισημάνει την απάντηση ανάλογα.
Δρομολόγηση με Σημασιολογική Ομοιότητα
Το LCEL σάς επιτρέπει να εφαρμόσετε προσαρμοσμένη λογική δρομολόγησης με βάση τη σημασιολογική ομοιότητα της εισαγωγής χρήστη. Ακολουθεί ένα παράδειγμα για τον δυναμικό προσδιορισμό της λογικής της αλυσίδας με βάση την είσοδο του χρήστη:
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.prompts import PromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnableLambda, RunnablePassthrough
from langchain.utils.math import cosine_similarity physics_template = """You are a very smart physics professor. You are great at answering questions about physics in a concise and easy to understand manner. When you don't know the answer to a question you admit that you don't know. Here is a question:
{query}""" math_template = """You are a very good mathematician. You are great at answering math questions. You are so good because you are able to break down hard problems into their component parts, answer the component parts, and then put them together to answer the broader question. Here is a question:
{query}""" embeddings = OpenAIEmbeddings()
prompt_templates = [physics_template, math_template]
prompt_embeddings = embeddings.embed_documents(prompt_templates) def prompt_router(input): query_embedding = embeddings.embed_query(input["query"]) similarity = cosine_similarity([query_embedding], prompt_embeddings)[0] most_similar = prompt_templates[similarity.argmax()] print("Using MATH" if most_similar == math_template else "Using PHYSICS") return PromptTemplate.from_template(most_similar) chain = ( {"query": RunnablePassthrough()} | RunnableLambda(prompt_router) | ChatOpenAI() | StrOutputParser()
) print(chain.invoke({"query": "What's a black hole"}))
print(chain.invoke({"query": "What's a path integral"}))
Σε αυτό το παράδειγμα, το prompt_router
Η συνάρτηση υπολογίζει την ομοιότητα του συνημιτόνου μεταξύ της εισαγωγής χρήστη και των προκαθορισμένων προτύπων προτροπής για ερωτήσεις φυσικής και μαθηματικών. Με βάση τη βαθμολογία ομοιότητας, η αλυσίδα επιλέγει δυναμικά το πιο σχετικό πρότυπο προτροπής, διασφαλίζοντας ότι το chatbot ανταποκρίνεται κατάλληλα στην ερώτηση του χρήστη.
Χρήση Agents και Runnables
Το LangChain σάς επιτρέπει να δημιουργείτε πράκτορες συνδυάζοντας Runnables, προτροπές, μοντέλα και εργαλεία. Ακολουθεί ένα παράδειγμα δημιουργίας ενός πράκτορα και χρήσης του:
from langchain.agents import XMLAgent, tool, AgentExecutor
from langchain.chat_models import ChatAnthropic model = ChatAnthropic(model="claude-2") @tool
def search(query: str) -> str: """Search things about current events.""" return "32 degrees" tool_list = [search] # Get prompt to use
prompt = XMLAgent.get_default_prompt() # Logic for going from intermediate steps to a string to pass into the model
def convert_intermediate_steps(intermediate_steps): log = "" for action, observation in intermediate_steps: log += ( f"<tool>{action.tool}</tool><tool_input>{action.tool_input}" f"</tool_input><observation>{observation}</observation>" ) return log # Logic for converting tools to a string to go in the prompt
def convert_tools(tools): return "n".join([f"{tool.name}: {tool.description}" for tool in tools]) agent = ( { "question": lambda x: x["question"], "intermediate_steps": lambda x: convert_intermediate_steps( x["intermediate_steps"] ), } | prompt.partial(tools=convert_tools(tool_list)) | model.bind(stop=["</tool_input>", "</final_answer>"]) | XMLAgent.get_default_output_parser()
) agent_executor = AgentExecutor(agent=agent, tools=tool_list, verbose=True) result = agent_executor.invoke({"question": "What's the weather in New York?"})
print(result)
Σε αυτό το παράδειγμα, δημιουργείται ένας πράκτορας συνδυάζοντας ένα μοντέλο, εργαλεία, μια προτροπή και μια προσαρμοσμένη λογική για ενδιάμεσα βήματα και μετατροπή εργαλείου. Στη συνέχεια, ο πράκτορας εκτελείται, παρέχοντας μια απάντηση στο ερώτημα του χρήστη.
Ερώτηση μιας βάσης δεδομένων SQL
Μπορείτε να χρησιμοποιήσετε το LangChain για να υποβάλετε ερωτήματα σε μια βάση δεδομένων SQL και να δημιουργήσετε ερωτήματα SQL με βάση ερωτήσεις χρήστη. Εδώ είναι ένα παράδειγμα:
from langchain.prompts import ChatPromptTemplate template = """Based on the table schema below, write a SQL query that would answer the user's question:
{schema} Question: {question}
SQL Query:"""
prompt = ChatPromptTemplate.from_template(template) from langchain.utilities import SQLDatabase # Initialize the database (you'll need the Chinook sample DB for this example)
db = SQLDatabase.from_uri("sqlite:///./Chinook.db") def get_schema(_): return db.get_table_info() def run_query(query): return db.run(query) from langchain.chat_models import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough model = ChatOpenAI() sql_response = ( RunnablePassthrough.assign(schema=get_schema) | prompt | model.bind(stop=["nSQLResult:"]) | StrOutputParser()
) result = sql_response.invoke({"question": "How many employees are there?"})
print(result) template = """Based on the table schema below, question, SQL query, and SQL response, write a natural language response:
{schema} Question: {question}
SQL Query: {query}
SQL Response: {response}"""
prompt_response = ChatPromptTemplate.from_template(template) full_chain = ( RunnablePassthrough.assign(query=sql_response) | RunnablePassthrough.assign( schema=get_schema, response=lambda x: db.run(x["query"]), ) | prompt_response | model
) response = full_chain.invoke({"question": "How many employees are there?"})
print(response)
Σε αυτό το παράδειγμα, το LangChain χρησιμοποιείται για τη δημιουργία ερωτημάτων SQL που βασίζονται σε ερωτήσεις χρήστη και την ανάκτηση απαντήσεων από μια βάση δεδομένων SQL. Οι προτροπές και οι απαντήσεις έχουν μορφοποιηθεί ώστε να παρέχουν αλληλεπιδράσεις φυσικής γλώσσας με τη βάση δεδομένων.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
LangServe & LangSmith
Το LangServe βοηθά τους προγραμματιστές να αναπτύξουν runnables και αλυσίδες LangChain ως REST API. Αυτή η βιβλιοθήκη είναι ενσωματωμένη στο FastAPI και χρησιμοποιεί pydantic για επικύρωση δεδομένων. Επιπλέον, παρέχει έναν υπολογιστή-πελάτη που μπορεί να χρησιμοποιηθεί για την κλήση σε runnables που έχουν αναπτυχθεί σε έναν διακομιστή και ένας πελάτης JavaScript είναι διαθέσιμος στο LangChainJS.
Χαρακτηριστικά
- Τα σχήματα εισόδου και εξόδου συνάγονται αυτόματα από το αντικείμενο LangChain και επιβάλλονται σε κάθε κλήση API, με πλούσια μηνύματα σφάλματος.
- Διατίθεται μια σελίδα εγγράφων API με JSONSchema και Swagger.
- Αποτελεσματικά τελικά σημεία /invoke, /batch και /stream με υποστήριξη για πολλές ταυτόχρονες αιτήσεις σε έναν μόνο διακομιστή.
- τελικό σημείο /stream_log για ροή όλων (ή ορισμένων) ενδιάμεσων βημάτων από την αλυσίδα/πράκτορά σας.
- Σελίδα Playground στο /playground με έξοδο ροής και ενδιάμεσα βήματα.
- Ενσωματωμένη (προαιρετική) ανίχνευση στο LangSmith. απλά προσθέστε το κλειδί API σας (δείτε Οδηγίες).
- Όλα έχουν δημιουργηθεί με βιβλιοθήκες Python ανοιχτού κώδικα δοκιμασμένες στη μάχη, όπως FastAPI, Pydantic, uvloop και asyncio.
Περιορισμοί
- Οι επανακλήσεις πελατών δεν υποστηρίζονται ακόμη για συμβάντα που προέρχονται από τον διακομιστή.
- Τα έγγραφα OpenAPI δεν θα δημιουργηθούν κατά τη χρήση του Pydantic V2. Το FastAPI δεν υποστηρίζει τη μίξη χώρων ονομάτων pydantic v1 και v2. Δείτε την παρακάτω ενότητα για περισσότερες λεπτομέρειες.
Χρησιμοποιήστε το LangChain CLI για γρήγορη εκκίνηση ενός έργου LangServe. Για να χρησιμοποιήσετε το langchain CLI, βεβαιωθείτε ότι έχετε εγκαταστήσει μια πρόσφατη έκδοση του langchain-cli. Μπορείτε να το εγκαταστήσετε με το pip install -U langchain-cli.
langchain app new ../path/to/directory
Ξεκινήστε γρήγορα την παρουσία σας LangServe με τα Πρότυπα LangChain. Για περισσότερα παραδείγματα, ανατρέξτε στο ευρετήριο προτύπων ή στον κατάλογο παραδειγμάτων.
Εδώ είναι ένας διακομιστής που αναπτύσσει ένα μοντέλο συνομιλίας OpenAI, ένα μοντέλο συνομιλίας Anthropic και μια αλυσίδα που χρησιμοποιεί το μοντέλο Anthropic για να πει ένα αστείο για ένα θέμα.
#!/usr/bin/env python
from fastapi import FastAPI
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatAnthropic, ChatOpenAI
from langserve import add_routes app = FastAPI( title="LangChain Server", version="1.0", description="A simple api server using Langchain's Runnable interfaces",
) add_routes( app, ChatOpenAI(), path="/openai",
) add_routes( app, ChatAnthropic(), path="/anthropic",
) model = ChatAnthropic()
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
add_routes( app, prompt | model, path="/chain",
) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="localhost", port=8000)
Αφού αναπτύξετε τον παραπάνω διακομιστή, μπορείτε να προβάλετε τα δημιουργημένα έγγραφα OpenAPI χρησιμοποιώντας:
curl localhost:8000/docs
Φροντίστε να προσθέσετε το επίθημα /docs.
from langchain.schema import SystemMessage, HumanMessage
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnableMap
from langserve import RemoteRunnable openai = RemoteRunnable("http://localhost:8000/openai/")
anthropic = RemoteRunnable("http://localhost:8000/anthropic/")
joke_chain = RemoteRunnable("http://localhost:8000/chain/") joke_chain.invoke({"topic": "parrots"}) # or async
await joke_chain.ainvoke({"topic": "parrots"}) prompt = [ SystemMessage(content='Act like either a cat or a parrot.'), HumanMessage(content='Hello!')
] # Supports astream
async for msg in anthropic.astream(prompt): print(msg, end="", flush=True) prompt = ChatPromptTemplate.from_messages( [("system", "Tell me a long story about {topic}")]
) # Can define custom chains
chain = prompt | RunnableMap({ "openai": openai, "anthropic": anthropic,
}) chain.batch([{ "topic": "parrots" }, { "topic": "cats" }])
Στο TypeScript (απαιτείται έκδοση LangChain.js 0.0.166 ή μεταγενέστερη):
import { RemoteRunnable } from "langchain/runnables/remote"; const chain = new RemoteRunnable({ url: `http://localhost:8000/chain/invoke/`,
});
const result = await chain.invoke({ topic: "cats",
});
Python που χρησιμοποιεί αιτήματα:
import requests
response = requests.post( "http://localhost:8000/chain/invoke/", json={'input': {'topic': 'cats'}}
)
response.json()
Μπορείτε επίσης να χρησιμοποιήσετε μπούκλα:
curl --location --request POST 'http://localhost:8000/chain/invoke/' --header 'Content-Type: application/json' --data-raw '{ "input": { "topic": "cats" } }'
Ο παρακάτω κώδικας:
...
add_routes( app, runnable, path="/my_runnable",
)
προσθέτει αυτά τα τελικά σημεία στον διακομιστή:
- POST /my_runnable/invoke – κλήση του runnable σε μία μόνο είσοδο
- POST /my_runnable/batch – κλήση του runnable σε μια παρτίδα εισόδων
- POST /my_runnable/stream – κλήση σε μία μόνο είσοδο και ροή της εξόδου
- POST /my_runnable/stream_log – κλήση σε μία μόνο είσοδο και ροή της εξόδου, συμπεριλαμβανομένης της εξόδου των ενδιάμεσων βημάτων καθώς δημιουργείται
- GET /my_runnable/input_schema – σχήμα json για είσοδο στο runnable
- GET /my_runnable/output_schema – σχήμα json για έξοδο του runnable
- GET /my_runnable/config_schema – σχήμα json για τη διαμόρφωση του τρέχοντος
Μπορείτε να βρείτε μια σελίδα παιδικής χαράς για το runnable σας στο /my_runnable/playground. Αυτό εκθέτει μια απλή διεπαφή χρήστη για τη διαμόρφωση και την κλήση του runnable σας με έξοδο ροής και ενδιάμεσα βήματα.
Τόσο για πελάτη όσο και για διακομιστή:
pip install "langserve[all]"
ή pip εγκατάσταση "langserve[client]" για τον κώδικα πελάτη και pip install "langserve[server]" για κώδικα διακομιστή.
Εάν χρειάζεται να προσθέσετε έλεγχο ταυτότητας στον διακομιστή σας, ανατρέξτε στην τεκμηρίωση ασφαλείας και την τεκμηρίωση του ενδιάμεσου λογισμικού του FastAPI.
Μπορείτε να αναπτύξετε στο GCP Cloud Run χρησιμοποιώντας την ακόλουθη εντολή:
gcloud run deploy [your-service-name] --source . --port 8001 --allow-unauthenticated --region us-central1 --set-env-vars=OPENAI_API_KEY=your_key
Το LangServe παρέχει υποστήριξη για το Pydantic 2 με ορισμένους περιορισμούς. Τα έγγραφα OpenAPI δεν θα δημιουργηθούν για invoke/batch/stream/stream_log όταν χρησιμοποιείτε το Pydantic V2. Το Fast API δεν υποστηρίζει τη μίξη χώρων ονομάτων pydantic v1 και v2. Το LangChain χρησιμοποιεί τον χώρο ονομάτων v1 στο Pydantic v2. Διαβάστε τις παρακάτω οδηγίες για να διασφαλίσετε τη συμβατότητα με το LangChain. Εκτός από αυτούς τους περιορισμούς, αναμένουμε ότι τα τελικά σημεία του API, η παιδική χαρά και οποιεσδήποτε άλλες λειτουργίες θα λειτουργήσουν όπως αναμένεται.
Οι εφαρμογές LLM συχνά ασχολούνται με αρχεία. Υπάρχουν διαφορετικές αρχιτεκτονικές που μπορούν να κατασκευαστούν για την υλοποίηση της επεξεργασίας αρχείων. σε υψηλό επίπεδο:
- Το αρχείο μπορεί να μεταφορτωθεί στον διακομιστή μέσω ενός αποκλειστικού τερματικού σημείου και να υποβληθεί σε επεξεργασία χρησιμοποιώντας ξεχωριστό τελικό σημείο.
- Το αρχείο μπορεί να μεταφορτωθεί είτε με τιμή (byte αρχείου) είτε με αναφορά (π.χ. s3 url στο περιεχόμενο αρχείου).
- Το τελικό σημείο επεξεργασίας μπορεί να είναι αποκλειστικό ή μη.
- Εάν απαιτείται σημαντική επεξεργασία, η επεξεργασία μπορεί να εκφορτωθεί σε μια ειδική ομάδα διεργασιών.
Θα πρέπει να καθορίσετε ποια είναι η κατάλληλη αρχιτεκτονική για την εφαρμογή σας. Επί του παρόντος, για να ανεβάσετε αρχεία ανά τιμή σε ένα runnable, χρησιμοποιήστε την κωδικοποίηση base64 για το αρχείο (τα δεδομένα πολλαπλών μερών/φόρμας δεν υποστηρίζονται ακόμη).
Εδώ είναι ένα παράδειγμα που δείχνει πώς να χρησιμοποιήσετε την κωδικοποίηση base64 για να στείλετε ένα αρχείο σε μια απομακρυσμένη δυνατότητα εκτέλεσης. Θυμηθείτε, μπορείτε πάντα να ανεβάσετε αρχεία με αναφορά (π.χ. s3 url) ή να τα ανεβάσετε ως δεδομένα πολλαπλών μερών/φόρμας σε ένα αποκλειστικό τελικό σημείο.
Οι τύποι εισόδου και εξόδου ορίζονται σε όλα τα runnables. Μπορείτε να αποκτήσετε πρόσβαση σε αυτά μέσω των ιδιοτήτων input_schema και output_schema. Το LangServe χρησιμοποιεί αυτούς τους τύπους για επικύρωση και τεκμηρίωση. Εάν θέλετε να παρακάμψετε τους προεπιλεγμένους συναγόμενους τύπους, μπορείτε να χρησιμοποιήσετε τη μέθοδο with_types.
Ακολουθεί ένα παράδειγμα παιχνιδιού για να διευκρινιστεί η ιδέα:
from typing import Any
from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda app = FastAPI() def func(x: Any) -> int: """Mistyped function that should accept an int but accepts anything.""" return x + 1 runnable = RunnableLambda(func).with_types( input_schema=int,
) add_routes(app, runnable)
Κληρονομήστε από το CustomUserType εάν θέλετε τα δεδομένα να αποσυνδεθούν σε ένα πυδατικό μοντέλο αντί για την ισοδύναμη αναπαράσταση υπαγορευμένου. Προς το παρόν, αυτός ο τύπος λειτουργεί μόνο από την πλευρά του διακομιστή και χρησιμοποιείται για τον καθορισμό της επιθυμητής συμπεριφοράς αποκωδικοποίησης. Εάν κληρονομήσει από αυτόν τον τύπο, ο διακομιστής θα διατηρήσει τον αποκωδικοποιημένο τύπο ως πυδατικό μοντέλο αντί να τον μετατρέψει σε dict.
from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda
from langserve import add_routes
from langserve.schema import CustomUserType app = FastAPI() class Foo(CustomUserType): bar: int def func(foo: Foo) -> int: """Sample function that expects a Foo type which is a pydantic model""" assert isinstance(foo, Foo) return foo.bar add_routes(app, RunnableLambda(func), path="/foo")
Η παιδική χαρά σάς επιτρέπει να ορίσετε προσαρμοσμένα widget για το runnable σας από το backend. Ένα γραφικό στοιχείο καθορίζεται σε επίπεδο πεδίου και αποστέλλεται ως μέρος του σχήματος JSON του τύπου εισόδου. Ένα γραφικό στοιχείο πρέπει να περιέχει ένα κλειδί που ονομάζεται τύπος με την τιμή να είναι μία από μια γνωστή λίστα γραφικών στοιχείων. Άλλα κλειδιά widget θα συσχετιστούν με τιμές που περιγράφουν διαδρομές σε ένα αντικείμενο JSON.
Γενικό σχήμα:
type JsonPath = number | string | (number | string)[];
type NameSpacedPath = { title: string; path: JsonPath }; // Using title to mimic json schema, but can use namespace
type OneOfPath = { oneOf: JsonPath[] }; type Widget = { type: string // Some well-known type (e.g., base64file, chat, etc.) [key: string]: JsonPath | NameSpacedPath | OneOfPath;
};
Επιτρέπει τη δημιουργία μιας εισαγωγής μεταφόρτωσης αρχείων στην παιδική χαρά της διεπαφής χρήστη για αρχεία που αποστέλλονται ως κωδικοποιημένες συμβολοσειρές base64. Εδώ είναι το πλήρες παράδειγμα.
try: from pydantic.v1 import Field
except ImportError: from pydantic import Field from langserve import CustomUserType # ATTENTION: Inherit from CustomUserType instead of BaseModel otherwise
# the server will decode it into a dict instead of a pydantic model.
class FileProcessingRequest(CustomUserType): """Request including a base64 encoded file.""" # The extra field is used to specify a widget for the playground UI. file: str = Field(..., extra={"widget": {"type": "base64file"}}) num_chars: int = 100
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
Εισαγωγή στον LangSmith
Το LangChain διευκολύνει τη δημιουργία πρωτοτύπων εφαρμογών και πρακτόρων LLM. Ωστόσο, η παράδοση εφαρμογών LLM στην παραγωγή μπορεί να είναι απατηλά δύσκολη. Πιθανότατα θα χρειαστεί να προσαρμόσετε σε μεγάλο βαθμό και να επαναλάβετε τις προτροπές, τις αλυσίδες και άλλα εξαρτήματά σας για να δημιουργήσετε ένα προϊόν υψηλής ποιότητας.
Για να βοηθήσει σε αυτή τη διαδικασία, εισήχθη το LangSmith, μια ενοποιημένη πλατφόρμα για τον εντοπισμό σφαλμάτων, τη δοκιμή και την παρακολούθηση των εφαρμογών σας LLM.
Πότε μπορεί να είναι χρήσιμο αυτό; Μπορεί να σας φανεί χρήσιμο όταν θέλετε να διορθώσετε γρήγορα μια νέα αλυσίδα, έναν πράκτορα ή ένα σύνολο εργαλείων, να απεικονίσετε τον τρόπο με τον οποίο συσχετίζονται και χρησιμοποιούνται στοιχεία (αλυσίδες, llms, retriever, κ.λπ.), αξιολογείτε διαφορετικές προτροπές και LLM για ένα μόνο στοιχείο, εκτελέστε μια δεδομένη αλυσίδα πολλές φορές σε ένα σύνολο δεδομένων για να βεβαιωθείτε ότι πληροί με συνέπεια μια γραμμή ποιότητας ή καταγράψτε ίχνη χρήσης και χρησιμοποιήστε LLM ή σωλήνες αναλυτικών στοιχείων για να δημιουργήσετε πληροφορίες.
Προαπαιτούμενα:
- Δημιουργήστε έναν λογαριασμό LangSmith και δημιουργήστε ένα κλειδί API (δείτε την κάτω αριστερή γωνία).
- Εξοικειωθείτε με την πλατφόρμα κοιτάζοντας τα έγγραφα.
Τώρα, ας ξεκινήσουμε!
Αρχικά, διαμορφώστε τις μεταβλητές περιβάλλοντος ώστε να ενημερώνουν το LangChain να καταγράφει ίχνη. Αυτό γίνεται ορίζοντας τη μεταβλητή περιβάλλοντος LANGCHAIN_TRACING_V2 σε true. Μπορείτε να πείτε στο LangChain σε ποιο έργο να συνδεθεί ορίζοντας τη μεταβλητή περιβάλλοντος LANGCHAIN_PROJECT (αν δεν έχει οριστεί, οι εκτελέσεις θα καταγραφούν στο προεπιλεγμένο έργο). Αυτό θα δημιουργήσει αυτόματα το έργο για εσάς εάν δεν υπάρχει. Πρέπει επίσης να ορίσετε τις μεταβλητές περιβάλλοντος LANGCHAIN_ENDPOINT και LANGCHAIN_API_KEY.
ΣΗΜΕΙΩΣΗ: Μπορείτε επίσης να χρησιμοποιήσετε έναν διαχειριστή περιβάλλοντος στην python για να καταγράψετε ίχνη χρησιμοποιώντας:
from langchain.callbacks.manager import tracing_v2_enabled with tracing_v2_enabled(project_name="My Project"): agent.run("How many people live in canada as of 2023?")
Ωστόσο, σε αυτό το παράδειγμα, θα χρησιμοποιήσουμε μεταβλητές περιβάλλοντος.
%pip install openai tiktoken pandas duckduckgo-search --quiet import os
from uuid import uuid4 unique_id = uuid4().hex[0:8]
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = f"Tracing Walkthrough - {unique_id}"
os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
os.environ["LANGCHAIN_API_KEY"] = "<YOUR-API-KEY>" # Update to your API key # Used by the agent in this tutorial
os.environ["OPENAI_API_KEY"] = "<YOUR-OPENAI-API-KEY>"
Δημιουργήστε τον πελάτη LangSmith για αλληλεπίδραση με το API:
from langsmith import Client client = Client()
Δημιουργήστε ένα στοιχείο LangChain και εκτελέστε καταγραφή στην πλατφόρμα. Σε αυτό το παράδειγμα, θα δημιουργήσουμε έναν πράκτορα τύπου ReAct με πρόσβαση σε ένα γενικό εργαλείο αναζήτησης (DuckDuckGo). Η προτροπή του πράκτορα μπορεί να προβληθεί στο Hub εδώ:
from langchain import hub
from langchain.agents import AgentExecutor
from langchain.agents.format_scratchpad import format_to_openai_function_messages
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
from langchain.chat_models import ChatOpenAI
from langchain.tools import DuckDuckGoSearchResults
from langchain.tools.render import format_tool_to_openai_function # Fetches the latest version of this prompt
prompt = hub.pull("wfh/langsmith-agent-prompt:latest") llm = ChatOpenAI( model="gpt-3.5-turbo-16k", temperature=0,
) tools = [ DuckDuckGoSearchResults( name="duck_duck_go" ), # General internet search using DuckDuckGo
] llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools]) runnable_agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_function_messages( x["intermediate_steps"] ), } | prompt | llm_with_tools | OpenAIFunctionsAgentOutputParser()
) agent_executor = AgentExecutor( agent=runnable_agent, tools=tools, handle_parsing_errors=True
)
Εκτελούμε τον παράγοντα ταυτόχρονα σε πολλαπλές εισόδους για να μειώσουμε τον λανθάνοντα χρόνο. Τα τρεξίματα καταγράφονται στο LangSmith στο παρασκήνιο, επομένως η καθυστέρηση εκτέλεσης δεν επηρεάζεται:
inputs = [ "What is LangChain?", "What's LangSmith?", "When was Llama-v2 released?", "What is the langsmith cookbook?", "When did langchain first announce the hub?",
] results = agent_executor.batch([{"input": x} for x in inputs], return_exceptions=True) results[:2]
Υποθέτοντας ότι έχετε ρυθμίσει με επιτυχία το περιβάλλον σας, τα ίχνη του αντιπροσώπου σας θα πρέπει να εμφανίζονται στην ενότητα Έργα της εφαρμογής. Συγχαρητήρια!
Ωστόσο, φαίνεται ότι ο πράκτορας δεν χρησιμοποιεί αποτελεσματικά τα εργαλεία. Ας το αξιολογήσουμε, ώστε να έχουμε μια βασική γραμμή.
Εκτός από τις εκτελέσεις καταγραφής, το LangSmith σας επιτρέπει επίσης να δοκιμάσετε και να αξιολογήσετε τις εφαρμογές σας LLM.
Σε αυτήν την ενότητα, θα αξιοποιήσετε τον LangSmith για να δημιουργήσετε ένα σύνολο δεδομένων αναφοράς και να εκτελέσετε αξιολογητές με τη βοήθεια AI σε έναν πράκτορα. Θα το κάνετε σε μερικά βήματα:
- Δημιουργήστε ένα σύνολο δεδομένων LangSmith:
Παρακάτω, χρησιμοποιούμε τον πελάτη LangSmith για να δημιουργήσουμε ένα σύνολο δεδομένων από τις ερωτήσεις εισαγωγής από πάνω και από τις ετικέτες λίστας. Θα τα χρησιμοποιήσετε αργότερα για να μετρήσετε την απόδοση ενός νέου πράκτορα. Ένα σύνολο δεδομένων είναι μια συλλογή παραδειγμάτων, τα οποία δεν είναι τίποτα άλλο από ζεύγη εισόδου-εξόδου που μπορείτε να χρησιμοποιήσετε ως δοκιμαστικές περιπτώσεις στην εφαρμογή σας:
outputs = [ "LangChain is an open-source framework for building applications using large language models. It is also the name of the company building LangSmith.", "LangSmith is a unified platform for debugging, testing, and monitoring language model applications and agents powered by LangChain", "July 18, 2023", "The langsmith cookbook is a github repository containing detailed examples of how to use LangSmith to debug, evaluate, and monitor large language model-powered applications.", "September 5, 2023",
] dataset_name = f"agent-qa-{unique_id}" dataset = client.create_dataset( dataset_name, description="An example dataset of questions over the LangSmith documentation.",
) for query, answer in zip(inputs, outputs): client.create_example( inputs={"input": query}, outputs={"output": answer}, dataset_id=dataset.id )
- Αρχικοποιήστε έναν νέο παράγοντα για συγκριτική αξιολόγηση:
Το LangSmith σάς επιτρέπει να αξιολογήσετε οποιοδήποτε LLM, αλυσίδα, πράκτορα ή ακόμα και μια προσαρμοσμένη λειτουργία. Οι συνομιλητές έχουν κατάσταση (έχουν μνήμη). για να διασφαλίσουμε ότι αυτή η κατάσταση δεν μοιράζεται μεταξύ των εκτελέσεων δεδομένων, θα περάσουμε σε ένα chain_factory (
aka a constructor) συνάρτηση για προετοιμασία για κάθε κλήση:
# Since chains can be stateful (e.g. they can have memory), we provide
# a way to initialize a new chain for each row in the dataset. This is done
# by passing in a factory function that returns a new chain for each row.
def agent_factory(prompt): llm_with_tools = llm.bind( functions=[format_tool_to_openai_function(t) for t in tools] ) runnable_agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_function_messages( x["intermediate_steps"] ), } | prompt | llm_with_tools | OpenAIFunctionsAgentOutputParser() ) return AgentExecutor(agent=runnable_agent, tools=tools, handle_parsing_errors=True)
- Διαμόρφωση αξιολόγησης:
Η μη αυτόματη σύγκριση των αποτελεσμάτων των αλυσίδων στη διεπαφή χρήστη είναι αποτελεσματική, αλλά μπορεί να είναι χρονοβόρα. Μπορεί να είναι χρήσιμο να χρησιμοποιείτε αυτοματοποιημένες μετρήσεις και σχόλια με τη βοήθεια AI για την αξιολόγηση της απόδοσης του στοιχείου σας:
from langchain.evaluation import EvaluatorType
from langchain.smith import RunEvalConfig evaluation_config = RunEvalConfig( evaluators=[ EvaluatorType.QA, EvaluatorType.EMBEDDING_DISTANCE, RunEvalConfig.LabeledCriteria("helpfulness"), RunEvalConfig.LabeledScoreString( { "accuracy": """
Score 1: The answer is completely unrelated to the reference.
Score 3: The answer has minor relevance but does not align with the reference.
Score 5: The answer has moderate relevance but contains inaccuracies.
Score 7: The answer aligns with the reference but has minor errors or omissions.
Score 10: The answer is completely accurate and aligns perfectly with the reference.""" }, normalize_by=10, ), ], custom_evaluators=[],
)
- Εκτελέστε τον πράκτορα και τους αξιολογητές:
Χρησιμοποιήστε τη συνάρτηση run_on_dataset (ή ασύγχρονη arun_on_dataset) για να αξιολογήσετε το μοντέλο σας. Αυτό θα:
- Λήψη παραδειγμάτων σειρών από το καθορισμένο σύνολο δεδομένων.
- Εκτελέστε τον πράκτορά σας (ή οποιαδήποτε προσαρμοσμένη συνάρτηση) σε κάθε παράδειγμα.
- Εφαρμόστε αξιολογητές στα ίχνη εκτέλεσης που προκύπτουν και αντίστοιχα παραδείγματα αναφοράς για τη δημιουργία αυτοματοποιημένων σχολίων.
Τα αποτελέσματα θα είναι ορατά στην εφαρμογή LangSmith:
chain_results = run_on_dataset( dataset_name=dataset_name, llm_or_chain_factory=functools.partial(agent_factory, prompt=prompt), evaluation=evaluation_config, verbose=True, client=client, project_name=f"runnable-agent-test-5d466cbc-{unique_id}", tags=[ "testing-notebook", "prompt:5d466cbc", ],
)
Τώρα που έχουμε τα αποτελέσματα της δοκιμής μας, μπορούμε να κάνουμε αλλαγές στον πράκτορά μας και να τους αξιολογήσουμε. Ας το δοκιμάσουμε ξανά με μια διαφορετική προτροπή και ας δούμε τα αποτελέσματα:
candidate_prompt = hub.pull("wfh/langsmith-agent-prompt:39f3bbd0") chain_results = run_on_dataset( dataset_name=dataset_name, llm_or_chain_factory=functools.partial(agent_factory, prompt=candidate_prompt), evaluation=evaluation_config, verbose=True, client=client, project_name=f"runnable-agent-test-39f3bbd0-{unique_id}", tags=[ "testing-notebook", "prompt:39f3bbd0", ],
)
Το LangSmith σάς επιτρέπει να εξάγετε δεδομένα σε κοινές μορφές όπως CSV ή JSONL απευθείας στην εφαρμογή Ιστού. Μπορείτε επίσης να χρησιμοποιήσετε τον πελάτη για να ανακτήσετε εκτελέσεις για περαιτέρω ανάλυση, για αποθήκευση στη δική σας βάση δεδομένων ή για κοινή χρήση με άλλους. Ας ανακτήσουμε τα ίχνη εκτέλεσης από την εκτέλεση αξιολόγησης:
runs = client.list_runs(project_name=chain_results["project_name"], execution_order=1) # After some time, these will be populated.
client.read_project(project_name=chain_results["project_name"]).feedback_stats
Αυτός ήταν ένας γρήγορος οδηγός για να ξεκινήσετε, αλλά υπάρχουν πολλοί περισσότεροι τρόποι να χρησιμοποιήσετε το LangSmith για να επιταχύνετε τη ροή των προγραμματιστών σας και να παράγετε καλύτερα αποτελέσματα.
Για περισσότερες πληροφορίες σχετικά με το πώς μπορείτε να αξιοποιήσετε στο έπακρο το LangSmith, ανατρέξτε στην τεκμηρίωση του LangSmith.
Ανεβείτε επίπεδο με τα Nanonets
Ενώ το LangChain είναι ένα πολύτιμο εργαλείο για την ενσωμάτωση γλωσσικών μοντέλων (LLM) με τις εφαρμογές σας, ενδέχεται να αντιμετωπίσει περιορισμούς όταν πρόκειται για περιπτώσεις εταιρικής χρήσης. Ας διερευνήσουμε πώς το Nanonets υπερβαίνει το LangChain για να αντιμετωπίσει αυτές τις προκλήσεις:
1. Ολοκληρωμένη συνδεσιμότητα δεδομένων:
Το LangChain προσφέρει συνδέσμους, αλλά ενδέχεται να μην καλύπτει όλες τις εφαρμογές χώρου εργασίας και τις μορφές δεδομένων στις οποίες βασίζονται οι επιχειρήσεις. Το Nanonets παρέχει συνδέσεις δεδομένων για περισσότερες από 100 ευρέως χρησιμοποιούμενες εφαρμογές χώρου εργασίας, συμπεριλαμβανομένων των Slack, Notion, Google Suite, Salesforce, Zendesk και πολλών άλλων. Υποστηρίζει επίσης όλους τους μη δομημένους τύπους δεδομένων όπως PDF, TXT, εικόνες, αρχεία ήχου και αρχεία βίντεο, καθώς και δομημένους τύπους δεδομένων όπως CSV, υπολογιστικά φύλλα, MongoDB και βάσεις δεδομένων SQL.
2. Αυτοματισμός εργασιών για εφαρμογές χώρου εργασίας:
Ενώ η δημιουργία κειμένου/απόκρισης λειτουργεί εξαιρετικά, οι δυνατότητες του LangChain είναι περιορισμένες όσον αφορά τη χρήση φυσικής γλώσσας για την εκτέλεση εργασιών σε διάφορες εφαρμογές. Το Nanonets προσφέρει πράκτορες ενεργοποίησης/δράσης για τις πιο δημοφιλείς εφαρμογές χώρου εργασίας, επιτρέποντάς σας να ρυθμίσετε ροές εργασίας που ακούν συμβάντα και εκτελούν ενέργειες. Για παράδειγμα, μπορείτε να αυτοματοποιήσετε απαντήσεις email, καταχωρίσεις CRM, ερωτήματα SQL και πολλά άλλα, όλα μέσω εντολών φυσικής γλώσσας.
3. Συγχρονισμός δεδομένων σε πραγματικό χρόνο:
Το LangChain ανακτά στατικά δεδομένα με συνδέσμους δεδομένων, τα οποία ενδέχεται να μην συμβαδίζουν με τις αλλαγές δεδομένων στη βάση δεδομένων προέλευσης. Αντίθετα, τα Nanonets διασφαλίζουν συγχρονισμό σε πραγματικό χρόνο με πηγές δεδομένων, διασφαλίζοντας ότι εργάζεστε πάντα με τις πιο πρόσφατες πληροφορίες.
3. Απλοποιημένη διαμόρφωση:
Η διαμόρφωση των στοιχείων του αγωγού LangChain, όπως τα retriever και τα synthesizers, μπορεί να είναι μια πολύπλοκη και χρονοβόρα διαδικασία. Τα Nanonets βελτιστοποιούν αυτό παρέχοντας βελτιστοποιημένη απορρόφηση δεδομένων και ευρετηρίαση για κάθε τύπο δεδομένων, όλα τα οποία χειρίζονται στο παρασκήνιο από το AI Assistant. Αυτό μειώνει το βάρος της μικρορύθμισης και διευκολύνει τη ρύθμιση και τη χρήση.
4. Ενοποιημένη λύση:
Σε αντίθεση με το LangChain, το οποίο μπορεί να απαιτεί μοναδικές υλοποιήσεις για κάθε εργασία, το Nanonets χρησιμεύει ως ενιαία λύση για τη σύνδεση των δεδομένων σας με LLM. Είτε θέλετε να δημιουργήσετε εφαρμογές LLM είτε ροές εργασίας AI, η Nanonets προσφέρει μια ενοποιημένη πλατφόρμα για τις διαφορετικές ανάγκες σας.
Ροές εργασίας Nanonets AI
Το Nanonets Workflows είναι ένας ασφαλής, πολλαπλών χρήσεων Βοηθός AI που απλοποιεί την ενοποίηση των γνώσεων και των δεδομένων σας με τα LLM και διευκολύνει τη δημιουργία εφαρμογών και ροών εργασίας χωρίς κώδικα. Προσφέρει ένα εύχρηστο περιβάλλον εργασίας χρήστη, καθιστώντας το προσβάσιμο τόσο για άτομα όσο και για οργανισμούς.
Για να ξεκινήσετε, μπορείτε να προγραμματίσετε μια κλήση με έναν από τους ειδικούς μας στην τεχνητή νοημοσύνη, ο οποίος μπορεί να παρέχει μια εξατομικευμένη επίδειξη και δοκιμή των ροών εργασίας Nanonets προσαρμοσμένη στη συγκεκριμένη περίπτωση χρήσης σας.
Μόλις ρυθμιστεί, μπορείτε να χρησιμοποιήσετε φυσική γλώσσα για να σχεδιάσετε και να εκτελέσετε σύνθετες εφαρμογές και ροές εργασίας που υποστηρίζονται από LLM, ενσωματώνοντας απρόσκοπτα τις εφαρμογές και τα δεδομένα σας.
Φορτίστε τις ομάδες σας με το Nanonets AI για να δημιουργήσετε εφαρμογές και να ενσωματώσετε τα δεδομένα σας με εφαρμογές και ροές εργασίας που βασίζονται σε τεχνητή νοημοσύνη, επιτρέποντας στις ομάδες σας να επικεντρωθούν σε ό,τι πραγματικά έχει σημασία.
Αυτοματοποιήστε τις μη αυτόματες εργασίες και τις ροές εργασιών με το εργαλείο δημιουργίας ροής εργασιών που βασίζεται σε AI, σχεδιασμένο από τη Nanonets για εσάς και τις ομάδες σας.
- SEO Powered Content & PR Distribution. Ενισχύστε σήμερα.
- PlatoData.Network Vertical Generative Ai. Ενδυναμώστε τον εαυτό σας. Πρόσβαση εδώ.
- PlatoAiStream. Web3 Intelligence. Ενισχύθηκε η γνώση. Πρόσβαση εδώ.
- PlatoESG. Ανθρακας, Cleantech, Ενέργεια, Περιβάλλον, Ηλιακός, Διαχείριση των αποβλήτων. Πρόσβαση εδώ.
- PlatoHealth. Ευφυΐα βιοτεχνολογίας και κλινικών δοκιμών. Πρόσβαση εδώ.
- πηγή: https://nanonets.com/blog/langchain/
- :έχει
- :είναι
- :δεν
- :που
- $UP
- 1
- 10
- 100
- 114
- 13
- 15%
- 2000
- 2012
- 2023
- 25
- 30
- 32
- 36
- 40
- 400
- 408
- 50
- 500
- 7
- 8
- a
- ABC
- ικανότητα
- Ικανός
- Σχετικα
- σχετικά με αυτό
- πάνω από
- Αποδέχομαι
- Αποδέχεται
- πρόσβαση
- προσιτός
- πρόσβαση
- ολοκληρώσει
- αναλόγως
- Λογαριασμός
- ακρίβεια
- ακριβής
- με ακρίβεια
- Κατορθώνω
- επιτευχθεί
- Επιτυγχάνει
- απέναντι
- Πράξη
- Ενέργειες
- ενεργειών
- ενεργός
- προσαρμογή
- προσαρμοστική
- προσθέτω
- προστιθέμενη
- προσθήκη
- Επιπλέον
- Πρόσθετος
- Επιπλέον
- διεύθυνση
- Προσθέτει
- ομολογώ
- προηγμένες
- Περιπέτεια
- Μετά το
- πάλι
- την ηλικία του
- Πράκτορας
- παράγοντες
- AI
- Βοηθός AI
- Μοντέλα AI
- Ενισχύσεις
- Στοχεύω
- αλγόριθμοι
- ευθυγράμμιση
- Ευθυγραμμίζει
- Όλα
- επιτρέπουν
- Επιτρέποντας
- επιτρέπει
- alone
- κατά μήκος
- κατά μήκος της πλευράς
- ήδη
- Επίσης
- Αν και
- πάντοτε
- an
- ανάλυση
- Αναλυτικός
- analytics
- και
- Angeles
- Ανακοινώστε
- ετήσιος
- Άλλος
- απάντηση
- απαντήσεις
- ύμνος
- Ανθρωπικός
- κάθε
- οτιδήποτε
- api
- ΚΛΕΙΔΙΑ API
- APIs
- app
- εφαρμόσιμος
- Εφαρμογή
- Ανάπτυξη Εφαρμογών
- εφαρμογές
- εφαρμοσμένος
- ισχύει
- πλησιάζω
- προσεγγίσεις
- κατάλληλος
- κατάλληλα
- εφαρμογές
- αρχιτεκτονική
- ΕΙΝΑΙ
- επιχείρημα
- επιχειρήματα
- Armstrong
- γύρω
- Παράταξη
- Καλλιτέχνες
- AS
- ζητώ
- άποψη
- πτυχές
- βοηθήσει
- Βοηθός
- συσχετισμένη
- At
- αποδίδουν
- προσοχή
- ήχου
- επαυξημένης
- Πιστοποίηση
- αυτοματοποίηση
- Αυτοματοποιημένη
- αυτοκίνητα
- αυτομάτως
- Αυτοματοποίηση
- διαθέσιμος
- μέσος
- αναμένω
- επίγνωση
- AWS
- πίσω
- Σπονδυλική στήλη
- Backend
- φόντο
- κακώς
- Υπόλοιπο
- μπαρ
- βάση
- βασίζονται
- Baseline
- βίαιο χτύπημα
- βασικός
- Βασικά
- BCG
- BE
- παραλία
- Αρκούδες
- επειδή
- ήταν
- πριν
- αρχίζουν
- συμπεριφορά
- πίσω
- στα παρασκήνια
- είναι
- παρακάτω
- αναφοράς
- ευεργετική
- ΚΑΛΎΤΕΡΟΣ
- Καλύτερα
- μεταξύ
- Πέρα
- Μεγαλύτερη
- Νομοσχέδιο
- Bill Gates
- δεσμεύουν
- Bing
- Κομμάτι
- Μαύρη
- Μαύρη Τρύπα
- Αποκλεισμός
- κλείδωμα
- Μπλοκ
- Μπλοκ
- σιτηρά
- Bootstrap
- γεννημένος
- Bot
- και οι δύο
- Κάτω μέρος
- Υποκατάστημα
- Διακοπή
- αύρα
- εν συντομία
- ευρύτερη
- καστανός
- πρόγραμμα περιήγησης
- ρυθμιστικό
- χτίζω
- Builder
- Κτίριο
- χτισμένο
- βάρος
- επιχειρήσεις
- αλλά
- by
- υπολογίσει
- υπολογίζει
- υπολογισμό
- υπολογισμός
- κλήση
- επιστροφές
- που ονομάζεται
- κλήση
- κλήσεις
- CAN
- Μπορεί να πάρει
- Canada
- δυνατότητες
- ικανός
- Χωρητικότητα
- πιάνω
- Καταγραφή
- περίπτωση
- περιπτώσεις
- CAT
- προμηθεύω
- τροφοδοσία
- εξυπηρετεί
- Γάτες
- προσοχή
- προσεκτικός
- στο κέντρο
- ορισμένες
- αλυσίδα
- αλυσίδες
- προκλήσεις
- Αλλαγές
- χαρακτήρας
- chatbot
- chatbots
- έλεγχος
- έλεγχοι
- Επιλέξτε
- επιλέγονται
- περιστάσεις
- Πόλη
- τάξη
- τάξεις
- πελάτης
- Backup
- κωδικός
- Κωδικοποίηση
- Καφές
- ΣΥΝΑΦΗΣ
- συνεκτικός
- συνεργάζομαι
- Κατάρρευση
- συλλογή
- πολύχρωμα
- Στήλη
- Στήλες
- COM
- συνδυασμός
- σε συνδυασμό
- συνδυάζει
- συνδυάζοντας
- Ελάτε
- έρχεται
- άνετος
- Κοινός
- Επικοινωνία
- εταίρα
- συγκρίνουν
- συγκρίνοντας
- συμβατότητα
- σύμφωνος
- πλήρης
- εντελώς
- ολοκλήρωση
- συγκρότημα
- πολυπλοκότητα
- συστατικό
- εξαρτήματα
- συγκείμενο
- σύνθεση
- περιεκτικός
- που περιλαμβάνει
- έννοια
- συνοπτικός
- ανταγωνιστής
- κατάσταση
- διαμόρφωση
- συμβολή
- Connect
- Συνδετικός
- Συνδεσιμότητα
- ΚΑΤΑ
- Εξετάστε
- με συνέπεια
- αποτελείται
- πρόξενος
- συνεχώς
- κατασκευές
- περιέχουν
- Περιέχει
- περιεχόμενο
- συμφραζόμενα
- πλαίσια
- συμφραζόμενα
- ΣΥΝΕΧΕΙΑ
- συνεχώς
- αντίθεση
- έλεγχος
- ελέγχους
- Βολικός
- Συνομιλία
- ομιλητικός
- συνομιλία AI
- συνομιλίες
- Μετατροπή
- μετατρέπονται
- μετατροπή
- πυρήνας
- Γωνία
- διορθώσει
- Αντίστοιχος
- θα μπορούσε να
- αρίθμηση
- χώρα
- Ζευγάρι
- κάλυμμα
- καλύπτονται
- δημιουργία
- δημιουργήθηκε
- δημιουργεί
- δημιουργία
- δημιουργία
- Διαπιστεύσεις
- κριτήρια
- Κριτικός
- CRM
- κρίσιμος
- Ρεύμα
- Τη στιγμή
- έθιμο
- Πελάτες
- παραμετροποίηση
- προσαρμόσετε
- προσαρμοσμένη
- αιχμής
- ημερομηνία
- Δομή δεδομένων
- βάση δεδομένων
- βάσεις δεδομένων
- Ημερομηνία
- ημερομηνία
- συμφωνία
- μοιρασιά
- Δεκέμβριος
- αποφασίζει
- Αποφασίζοντας
- Λήψη Αποφάσεων
- Αποκρυπτογράφηση
- αφιερωμένο
- βαθύτερη
- Προεπιλογή
- ορίζεται
- ορίζεται
- καθορίζοντας
- ορισμοί
- παράδοση
- παραδίδει
- σκάβω
- διαδήλωση
- αποδεικνύουν
- κατέδειξε
- αποδεικνύοντας
- εξαρτηθεί
- Σε συνάρτηση
- εξαρτάται
- παρατάσσω
- αναπτυχθεί
- ανάπτυξη
- ανάπτυξη
- αναπτύσσεται
- περιγράφουν
- περιγραφή
- Υπηρεσίες
- καθορισμένο
- σχεδιασμένα
- επιθυμητή
- λεπτομέρεια
- λεπτομερής
- καθέκαστα
- Προσδιορίστε
- καθορίζει
- ανάπτυξη
- Εργολάβος
- προγραμματιστές
- ανάπτυξη
- Ανάπτυξη
- διαγράμματα
- DICT
- DID
- διαφέρω
- διαφορετικές
- διαφορετικά
- δύσκολος
- Διάσταση
- Διαστάσεις
- οδηγιών
- κατευθείαν
- συζητήσουν
- συζήτηση
- εμφάνιση
- διακριτή
- κατάδυση
- διάφορα
- DM
- do
- έγγραφο
- τεκμηρίωση
- έγγραφα
- κάνει
- doesn
- πράξη
- Don
- γίνεται
- διπλασιαστεί
- κάτω
- κατεβάσετε
- λήψεις
- προσχέδιο
- αυτοκίνητο
- δυο
- κατά την διάρκεια
- δυναμικός
- δυναμικά
- e
- κάθε
- Νωρίτερα
- Νωρίς
- ευκολία
- ευκολία στη χρήση
- ευκολότερη
- εύκολα
- εύκολος
- εύκολο στη χρήση
- ηχώ
- οικοσύστημα
- Αποτελεσματικός
- αποτελεσματικά
- αποδοτικότητα
- αποτελεσματικός
- αποτελεσματικά
- αβίαστα
- είτε
- στοιχείο
- στοιχεία
- Elon
- Elon Musk
- αλλιώς
- ΗΛΕΚΤΡΟΝΙΚΗ ΔΙΕΥΘΥΝΣΗ
- embed
- ενσωματωμένο
- ενσωμάτωση
- μισθωτών
- υπαλλήλους
- απασχολεί
- εξουσιοδοτώ
- ενεργοποιήσετε
- δίνει τη δυνατότητα
- ενεργοποίηση
- ενθυλακώνει
- αντιμετωπίζω
- από άκρη σε άκρη
- Τελικό σημείο
- ελκυστικός
- Κινητήρας
- Κινητήρες
- Αγγλία
- Αγγλικά
- Αγγλική Premier League
- ενίσχυση
- ενισχυμένη
- ενίσχυση
- εξασφαλίζω
- εξασφαλίζει
- εξασφαλίζοντας
- Εταιρεία
- οντότητες
- οντότητα
- Περιβάλλον
- περιβάλλοντα
- Ισοδύναμος
- Εποχή
- σφάλμα
- λάθη
- ειδικά
- ουσιώδης
- αποξενωμένοι
- κ.λπ.
- αξιολογήσει
- εκτίμηση
- Even
- εκδηλώσεις
- Κάθε
- παράδειγμα
- παραδείγματα
- υπερβαίνω
- Εκτός
- εκτελέσει
- εκτελέστηκε
- Εκτελεί
- εκτέλεσης
- εκτέλεση
- αποτελεί παράδειγμα
- Άσκηση
- υπάρχουν
- αναμένω
- προσδοκίες
- αναμένεται
- αναμένει
- εμπειρία
- πειραματικός
- εμπειρογνώμονες
- εξήγησε
- Εξηγεί
- ρητά
- εξερεύνηση
- διερευνήσει
- Εξερευνήθηκε
- εξαγωγή
- έκφραση
- επεκτείνουν
- επέκταση
- εκτενής
- εξωτερικός
- επιπλέον
- εκχύλισμα
- εξαγωγή
- Εκχυλίσματα
- Πρόσωπο
- διευκολύνω
- διευκολύνει
- εργοστάσιο
- γεγονότα
- μακριά
- FAST
- Αγαπημένα
- Χαρακτηριστικό
- Χαρακτηριστικά
- ανατροφοδότηση
- λίγοι
- πεδίο
- Πεδία
- σύκο
- Εικόνα
- Αρχεία
- Αρχεία
- συμπληρώστε
- γεμάτο
- πλήρωση
- φιλτράρισμα
- φιλτράρισμα
- τελικός
- Τελικά
- Εύρεση
- εύρεση
- Όνομα
- πέντε
- Ευελιξία
- εύκαμπτος
- ροή
- Συγκέντρωση
- επικεντρώθηκε
- εστιάζει
- εστιάζοντας
- ακολουθήστε
- Εξής
- εξής
- τροφή
- Για
- μορφή
- μορφή
- σχηματίζεται
- Ευτυχώς
- Βρέθηκαν
- Πλαίσιο
- πλαισίων
- συχνά
- φίλος
- φίλους
- από
- πλήρη
- πλήρης
- λειτουργία
- λειτουργίες
- λειτουργικότητα
- λειτουργίες
- θεμελιώδης
- αστείος
- περαιτέρω
- μελλοντικός
- Κέρδος
- Games
- Πύλες
- General
- γενικά
- παράγουν
- παράγεται
- δημιουργεί
- παραγωγής
- γενεά
- είδος
- Germany
- παίρνω
- να πάρει
- gif
- GitHub
- δεδομένου
- GMT
- Go
- πηγαίνει
- μετάβαση
- καλός
- κοκκώδης
- γραφική παράσταση
- εξαιρετική
- μεγαλύτερη
- καθοδήγηση
- καθοδηγήσει
- κατευθυντήριων γραμμών
- hackathon
- λαβή
- Handles
- Χειρισμός
- κινητός
- Σκληρά
- βλάψει
- ιμάντες
- Έχω
- που έχει
- βαριά
- Ήρωας
- βοήθεια
- χρήσιμο
- βοηθά
- αυτήν
- εδώ
- hi
- Ψηλά
- υψηλού επιπέδου
- υψηλής ποιότητας
- υψηλότερο
- υψηλά
- ιστορικών
- ιστορία
- Τρύπα
- κουκούλα
- οικοδεσπότης
- Πως
- Πώς να
- Ωστόσο
- HTML
- http
- HTTPS
- Hub
- ανθρώπινος
- Εκατοντάδες
- i
- ID
- ιδέα
- ιδανικό
- ids
- if
- ii
- iii
- εικονογραφώ
- απεικονίζει
- εικόνες
- άμεσος
- εφαρμογή
- εκτέλεση
- υλοποιήσεις
- εφαρμοστεί
- εισαγωγή
- βελτιώσεις
- βελτίωση
- in
- σε βάθος
- περιλαμβάνουν
- περιλαμβάνονται
- περιλαμβάνει
- Συμπεριλαμβανομένου
- ενσωματώνω
- ενσωματώνοντας
- απίστευτα
- ευρετήριο
- δείκτες
- υποδεικνύω
- υποδηλώνει
- Μεμονωμένα
- άτομα
- πληροφορίες
- αρχικός
- κινήσει
- καινοτόμες
- εισαγωγή
- είσοδοι
- ιδέες
- εγκαθιστώ
- εγκατασταθεί
- εγκατάσταση
- παράδειγμα
- στιγμή
- αντί
- οδηγίες
- ολοκλήρωμα
- ενσωματώσει
- ενσωματωθεί
- Ενσωματώνει
- Ενσωμάτωση
- ολοκλήρωση
- ολοκληρώσεις
- Έξυπνος
- προορίζονται
- αλληλεπιδρούν
- αλληλεπίδραση
- αλληλεπιδράσεις
- διαδραστικό
- διαδραστικός
- περιβάλλον λειτουργίας
- διεπαφές
- εσωτερικώς
- Internet
- σε
- εισήγαγε
- Εισάγει
- διαισθητική
- συμμετοχή
- isn
- ζήτημα
- θέματα
- IT
- αντικειμένων
- επαναλήψεις
- ΤΟΥ
- εαυτό
- Τζάκσον
- το JavaScript
- Δουλειά
- Ιορδανία
- ταξίδι
- json
- Ιούλιος
- μόλις
- Δικαιοσύνη
- Διατήρηση
- κρατά
- Κλειδί
- πλήκτρα
- Είδος
- Ξέρω
- γνώση
- Γράφημα Γνώσης
- γνωστός
- επιγραφή
- Ετικέτες
- Οικόπεδο
- Γλώσσα
- Γλώσσες
- large
- μεγαλύτερος
- Επίθετο
- Αφάνεια
- αργότερα
- αργότερο
- Λιγκ
- ΜΑΘΑΊΝΩ
- μάθηση
- αριστερά
- Κληροδότημα
- Μήκος
- μείον
- ας
- Αφήνει
- επιστολή
- Επίπεδο
- επίπεδα
- Μόχλευση
- μόχλευσης
- μόχλευσης
- βιβλιοθήκες
- Βιβλιοθήκη
- Μου αρέσει
- Πιθανός
- LIMIT
- περιορισμούς
- Περιωρισμένος
- περιορίζοντας
- όρια
- ΣΥΝΔΕΣΜΟΙ
- Λιστα
- ακούω
- Λίστες
- ζω
- ll
- LLM
- φορτίο
- φορτωτής
- που βρίσκεται
- τοποθεσία
- κούτσουρο
- καταγραφεί
- ξύλευση
- λογική
- Μακριά
- πλέον
- ματιά
- κοιτάζοντας
- ΦΑΊΝΕΤΑΙ
- αναζήτηση
- ο
- Λος Άντζελες
- Χαμηλός
- μηχανή
- μάθηση μηχανής
- που
- διατηρήσουν
- Διατηρήσιμο
- Η διατήρηση
- διατηρεί
- κάνω
- ΚΑΝΕΙ
- Κατασκευή
- διαχείριση
- διαχείριση
- διευθυντής
- διαχείριση
- Μάντσεστερ
- Μάντσεστερ Γιουνάιτεντ
- Χειρισμός
- τρόπος
- Ταχύτητες
- Κατασκευαστής
- πολοί
- πολλοί άνθρωποι
- χάρτη
- χαρτης
- χάρτες
- Ταίριασμα
- ταιριάζουν
- μαθηματικά
- μαθηματικός
- Θέματα
- ανώτατο όριο
- Ενδέχεται..
- me
- εννοώ
- νόημα
- μέσα
- μέτρο
- Εικόνες / Βίντεο
- συνάντηση
- πληροί
- Μνήμες
- Μνήμη
- που αναφέρθηκαν
- πηγαίνω
- συγχώνευση
- μήνυμα
- μηνύματα
- μηνυμάτων
- Μεταδεδομένα
- μέθοδος
- μέθοδοι
- Metrics
- ενδέχεται να
- εκατομμύρια
- ελάχιστος
- ανήλικος
- Λείπει
- λάθη
- Μίξη
- MLB
- Κινητό
- μοντέλο
- μοντέλα
- μετριοπάθεια
- Μονάδα μέτρησης
- ενότητες
- στιγμή
- MongoDB
- Παρακολούθηση
- παρακολούθηση
- Σελήνη
- περισσότερο
- πλέον
- Δημοφιλέστερα
- μετακινήσετε
- ταινία
- πολύ
- πολλαπλούς
- πολλαπλές αλυσίδες
- Μόσχος
- πρέπει
- my
- όνομα
- Ονομάστηκε
- ονόματα
- εθνικός
- Φυσικό
- Επεξεργασία φυσικής γλώσσας
- Πλοηγηθείτε
- πλοήγηση
- Κοντά
- απαραίτητος
- Ανάγκη
- που απαιτούνται
- ανάγκες
- αρνητικός
- Νέα
- Νέα Υόρκη
- New York Times
- επόμενη
- Όχι.
- Ν/Α
- τίποτα
- Εννοια
- τώρα
- αριθμός
- Ομπάμα
- αντικείμενο
- σκοπός
- αντικειμένων
- παρατήρηση
- αποκτήσει
- την απόκτηση
- OCR
- of
- προσφορά
- προσφορά
- προσφορές
- συχνά
- oh
- Καλά
- Ολυμπιακοί Αγώνες
- on
- μια φορά
- ONE
- αποκλειστικά
- ανοικτού κώδικα
- OpenAI
- λειτουργίες
- χειριστής
- βελτιστοποιημένη
- Βελτιστοποιεί
- Επιλογή
- or
- τάξη
- οργανικές
- οργανώσεις
- πρωτότυπο
- OS
- ΑΛΛΑ
- Άλλα
- αλλιώς
- δικός μας
- έξω
- παραγωγή
- εξόδους
- επί
- καταπατώ
- επισκόπηση
- δική
- πακέτο
- Packages
- σελίδα
- σελίδες
- ζεύγη
- Πάντα
- Χαρτί
- Παράλληλο
- παράμετρος
- παράμετροι
- Πάρκο
- μέρος
- ιδιαίτερα
- εξαρτήματα
- passieren
- πέρασε
- περάσματα
- Πέρασμα
- Το παρελθόν
- μονοπάτι
- μονοπάτια
- πρότυπα
- Μισθολόγιο
- People
- για
- τέλειος
- τέλεια
- Εκτελέστε
- επίδοση
- εκτέλεση
- εκτελεί
- δικαιώματα
- επιμονή
- person
- Εξατομικευμένη
- προοπτική
- Φυσική
- κομμάτι
- αγωγού
- πίτσα
- κράτησης θέσης
- πλατφόρμες
- Πλάτων
- Πληροφορία δεδομένων Plato
- Πλάτωνα δεδομένα
- Δοκιμάστε να παίξετε
- παιδική χαρά
- παίζει
- σας παρακαλούμε
- συν
- Σημείο
- Πολιτικές
- πολιτική
- πολιτικός
- πισίνα
- Δημοφιλής
- κατοικημένη περιοχή
- θετικός
- δυνατός
- Θέση
- Δημοσιεύσεις
- δυναμικού
- δύναμη
- τροφοδοτείται
- ισχυρός
- Πρακτικός
- πρακτική
- προτιμώ
- πρωθυπουργός
- παρόν
- πρόεδρος
- πρόληψη
- πρόληψη
- προηγούμενος
- πρωτίστως
- πρωταρχικός
- Ακμή
- ιδιωτικός
- Πρόβλημα
- προβλήματα
- προχωρήσει
- διαδικασια μας
- Επεξεργασμένο
- Διεργασίες
- μεταποίηση
- παράγει
- Προϊόν
- παραγωγή
- Δάσκαλος
- Προγραμματισμός
- γλώσσες προγραμματισμού
- σχέδιο
- έργα
- ιδιότητες
- περιουσία
- PROS
- πρωτότυπο
- προτυποποίηση
- παρέχουν
- παρέχεται
- προμηθευτής
- Παρόχους υπηρεσιών
- παρέχει
- χορήγηση
- δημόσιο
- σκοπός
- σκοποί
- βάζω
- Python
- Ερωτήσεις και απαντήσεις
- ποιότητα
- ερωτήματα
- ερώτηση
- Ερωτήσεις
- Γρήγορα
- γρήγορα
- εισαγωγικά
- R
- αύξηση
- σειρά
- κυμαίνεται
- μάλλον
- εκτίμηση
- Ακατέργαστος
- RE
- φθάσουν
- Αντίδραση
- Διάβασε
- Ανάγνωση
- έτοιμος
- πραγματικός
- σε πραγματικό χρόνο
- δεδομένα σε πραγματικό χρόνο
- βασίλειο
- λόγος
- λόγους
- πρόσφατος
- συνιστάται
- καταγράφονται
- αρχεία
- Ανάκτηση
- μείωση
- μειώνει
- μείωση
- μείωση
- αναφορά
- αναφοράς
- τελειοποίηση
- διύλιση
- περιοχές
- Σχέσεις
- κυκλοφόρησε
- συνάφεια
- αξιοπιστία
- αξιόπιστος
- βασίζονται
- βασιζόμενοι
- λείψανα
- θυμάμαι
- υπενθύμιση
- μακρινός
- αποδώσει
- επαναλαμβάνω
- ΚΑΤ 'ΕΠΑΝΑΛΗΨΗ
- αναδιατύπωση
- αντικαθιστώ
- αναφέρουν
- Αποθήκη
- αντιπροσώπευση
- εκπροσωπούν
- αντιπροσωπεύει
- ζητήσει
- αιτήματα
- απαιτούν
- απαιτείται
- απαιτήσεις
- Απαιτεί
- διάσωση
- έρευνα
- επίλυση
- πόρος
- Απάντηση
- απαντώντας
- απάντησης
- απαντήσεις
- υπεύθυνος
- ανταποκρίνονται
- ΠΕΡΙΦΕΡΕΙΑ
- αποτέλεσμα
- με αποτέλεσμα
- Αποτελέσματα
- συγκράτησης
- κράτηση
- απόδοση
- επιστροφή
- Επιστροφές
- επαναχρησιμοποιήσιμη
- ανασκόπηση
- περιστρέφεται
- Ρύζι
- Πλούσιος
- ρομπότ
- Ρόλος
- ρόλους
- ρίζα
- δρομολόγηση
- ΣΕΙΡΑ
- τρέξιμο
- τρέξιμο
- τρέχει
- runtime
- s
- διασφαλίσεις
- εμπορικός
- salesforce
- Sam
- ίδιο
- Αποθήκευση
- λένε
- λέει
- επεκτάσιμη
- Κλίμακα
- σενάριο
- σενάρια
- Σκηνές
- πρόγραμμα
- σκορ
- μηδέν
- αδιάλειπτη
- άψογα
- Αναζήτηση
- μηχανή αναζήτησης
- αναζητήσεις
- αναζήτηση
- Τμήμα
- τμήματα
- προστατευμένο περιβάλλον
- ασφάλεια
- δείτε
- επιλέγονται
- επιλογή
- Τις Πωλήσεις
- στείλετε
- ευαίσθητος
- συναίσθημα
- συναισθήματα
- ξεχωριστό
- Σεπτέμβριος
- Ακολουθία
- Σειρές
- εξυπηρετούν
- διακομιστής
- εξυπηρετεί
- Υπηρεσίες
- σειρά
- Σέτς
- τον καθορισμό
- ρυθμίσεις
- setup
- επτά
- διάφοροι
- Κοινοποίηση
- Shared
- κέλυφος
- λάμπει
- αποστέλλονται
- θα πρέπει να
- δείχνουν
- βιτρίνα
- παρουσιάζεται
- Δείχνει
- Sigma
- σημαντικός
- παρόμοιες
- Απλούς
- απλοποιημένη
- απλοποίηση
- απλουστεύοντας
- απλά
- αφού
- ενιαίας
- Μέγεθος
- χαλαρότητα
- small
- μικρότερος
- έξυπνος
- Απόσπασμα
- So
- μέχρι τώρα
- Ποδόσφαιρο
- Μ.Κ.Δ
- social media
- Δημοσιεύσεις κοινωνικών μέσων
- μόνο
- στέρεο
- λύση
- SOLVE
- μερικοί
- κάτι
- μερικές φορές
- εξελιγμένα
- ήχοι
- Πηγή
- Πηγές
- Χώρος
- Ισπανικά
- ειδικευμένος
- συγκεκριμένες
- ειδικά
- ειδικότητες
- καθορίζεται
- ταχύτητα
- πέρασε
- διαίρεση
- Διαχωρίστε
- Άθλημα
- πλατεία
- σταθεί
- αυτόνομο
- πρότυπο
- Εκκίνηση
- ξεκίνησε
- Ξεκινήστε
- Κατάσταση
- δηλώσεις
- στατικός
- Βήμα
- Βήματα
- Ακόμη
- στάση
- στάθμευση
- Διακόπτει
- χώρος στο δίσκο
- κατάστημα
- αποθηκεύονται
- καταστήματα
- εναποθήκευση
- Ιστορία
- ειλικρινής
- μετάδοση
- ροής
- εξορθολογισμό
- εξορθολογισμένη
- δυνατά
- Απεργίες
- Σπάγγος
- δομή
- δομημένος
- δομές
- δομή
- στυλ
- θέμα
- μεταγενέστερος
- Επιτυχώς
- τέτοιος
- κοστούμι
- κατάλληλος
- σουίτα
- συνοψίζω
- ΠΕΡΙΛΗΨΗ
- Ηλιοβασίλεμα
- υποστήριξη
- υποστηριζόνται!
- Υποστηρίζει
- βέβαιος
- Βιωσιμότητα
- συγχρονισμός
- σύνοψη
- σύνταξη
- σύστημα
- συστήματα
- τραπέζι
- ράφτης
- επειξειργασμένος από ραπτήν
- Πάρτε
- παίρνει
- στόχους
- Έργο
- εργασίες
- ομάδες
- πει
- πρότυπο
- πρότυπα
- τερματικό
- ορολογία
- όροι
- δοκιμή
- Δοκιμές
- κείμενο
- από
- Ευχαριστώ
- ότι
- Η
- Τα Βασικά
- το κέντρο
- οι πληροφορίες
- Οι Νιου Γιορκ Ταιμς
- Οι εργασίες
- Η Πηγη
- ο κόσμος
- τους
- Τους
- τότε
- Εκεί.
- Αυτοί
- αυτοί
- πράγματα
- αυτό
- εκείνοι
- αν και?
- Μέσω
- παντού
- ώρα
- χρονοβόρος
- φορές
- Τίτλος
- προς την
- μαζι
- ένδειξη
- Τεκμηρίωση
- κουπόνια
- πολύ
- εργαλείο
- εργαλειοθήκη
- εργαλεία
- κορυφή
- τοπικός
- Θέματα
- Σύνολο
- πόλη
- Εντοπισμός
- τροχιά
- παραδοσιακός
- Εκπαίδευση
- Μεταμορφώστε
- μετασχηματισμούς
- μετασχηματιστής
- μετασχηματιστές
- μετάβαση
- δίκη
- αληθής
- όντως
- προσπαθώ
- βραχυχρόνιων διακυμάνσεων της ρευστότητας
- ΣΤΡΟΦΗ
- Στροφή
- φροντιστήριο
- Δυο φορές
- δύο
- τύπος
- τύποι
- Typescript
- συνήθως
- ui
- τελικά
- ανεπηρέαστος
- υπό
- υποκείμενες
- καταλαβαίνω
- κατανόηση
- καταλαβαίνει
- ενιαία
- μοναδικός
- Ενωμένος
- Παγκόσμιος
- διαφορετικός
- μέχρι
- Ενημέρωση
- ενημερώσεις
- Φορτώθηκε
- URL
- us
- χρηστικότητα
- Χρήση
- χρήση
- περίπτωση χρήσης
- μεταχειρισμένος
- Χρήστες
- Διεπαφής χρήστη
- Χρήστες
- χρησιμοποιεί
- χρησιμοποιώντας
- επιχειρήσεις κοινής ωφέλειας
- χρησιμοποιώ
- χρησιμοποιούνται
- χρησιμοποιεί
- αξιοποιώντας
- v1
- επικύρωση
- Επικύρωση
- Πολύτιμος
- αξία
- Αξίες
- μεταβλητή
- ποικιλία
- διάφορα
- Ve
- πολύπλευρος
- εκδοχή
- πολύ
- μέσω
- Βίντεο
- Δες
- Παραβιάσεις
- ορατός
- φαντάζομαι
- ζωτικής σημασίας
- vs
- walk
- περιδιάβαση
- θέλω
- ήταν
- Δες
- Τρόπος..
- τρόπους
- we
- Weather
- ιστός
- πρόγραμμα περιήγησης στο Web
- διαδικτυακές υπηρεσίες
- ιστοσελίδες
- ΛΟΙΠΌΝ
- πολύ γνωστό
- ήταν
- Τι
- Τι είναι
- Τι
- πότε
- αν
- Ποιό
- ενώ
- Ο ΟΠΟΊΟΣ
- ολόκληρο
- WHY
- ευρύς
- ευρέως
- widget
- Wikipedia
- θα
- παράθυρο
- Κερδίζει
- με
- εντός
- χωρίς
- λέξη
- Εργασία
- εργάστηκαν
- ροής εργασίας
- ροές εργασίας
- εργαζόμενος
- λειτουργεί
- κόσμος
- θα
- γράφω
- γραφή
- X
- ακόμη
- Υόρκη
- Εσείς
- Σας
- τον εαυτό σας
- YouTube
- Zendesk
- zephyrnet
- Zip