Magjában, LangChain egy innovatív keretrendszer, amelyet olyan alkalmazások készítésére szabtak, amelyek kihasználják a nyelvi modellek képességeit. Ez egy olyan eszközkészlet, amelyet a fejlesztők számára terveztek olyan alkalmazások létrehozásához, amelyek környezettudatosak és képesek kifinomult érvelésre.
Ez azt jelenti, hogy a LangChain alkalmazások megérthetik a kontextust, például a gyors utasításokat vagy a tartalomra vonatkozó válaszokat, és nyelvi modelleket használhatnak összetett érvelési feladatokhoz, például a válaszadás vagy a teendők eldöntéséhez. A LangChain az intelligens alkalmazások fejlesztésének egységes megközelítését képviseli, különféle összetevőivel leegyszerűsíti az utat az ötlettől a megvalósításig.
A LangChain megértése
A LangChain sokkal több, mint egy keretrendszer; ez egy teljes értékű ökoszisztéma, amely több szerves részből áll.
- Először is ott vannak a LangChain könyvtárak, amelyek Pythonban és JavaScriptben is elérhetők. Ezek a könyvtárak képezik a LangChain gerincét, interfészeket és integrációkat kínálva a különböző komponensekhez. Alapvető futási időt biztosítanak ezen komponensek összefüggő láncokká és ügynökökké való kombinálásához, valamint kész implementációkat biztosítanak azonnali használatra.
- Ezután LangChain sablonjaink vannak. Ezek a feladatok széles körére szabott, telepíthető referenciaarchitektúrák gyűjteménye. Akár chatbotot, akár összetett elemző eszközt épít, ezek a sablonok szilárd kiindulási alapot kínálnak.
- A LangServe sokoldalú könyvtárként lép be a LangChain láncok REST API-kként történő telepítéséhez. Ez az eszköz elengedhetetlen ahhoz, hogy LangChain projektjeit hozzáférhető és méretezhető webszolgáltatásokká alakítsa.
- Végül a LangSmith fejlesztői platformként szolgál. Bármilyen LLM-keretrendszerre épülő láncok hibakeresésére, tesztelésére, értékelésére és figyelésére készült. A LangChain zökkenőmentes integrációja nélkülözhetetlen eszközzé teszi az alkalmazásaik finomítására és tökéletesítésére törekvő fejlesztők számára.
Ezek az összetevők együttesen lehetővé teszik az alkalmazások egyszerű fejlesztését, gyártását és üzembe helyezését. A LangChain segítségével először megírja az alkalmazásokat a könyvtárak használatával, és sablonokra hivatkozik útmutatásként. A LangSmith ezután segít a láncok ellenőrzésében, tesztelésében és felügyeletében, biztosítva, hogy alkalmazásai folyamatosan fejlődjenek és készen álljanak a telepítésre. Végül a LangServe segítségével bármilyen láncot könnyen átalakíthat API-vá, így a telepítés gyerekjáték.
A következő részekben részletesebben megvizsgáljuk a LangChain beállítását, és elkezdjük az intelligens, nyelvi modellekkel hajtott alkalmazások létrehozását.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
Telepítés és beállítás
Készen állsz, hogy belemerülj a LangChain világába? Beállítása egyszerű, és ez az útmutató lépésről lépésre végigvezeti a folyamaton.
A LangChain utazásának első lépése a telepítés. Ezt egyszerűen megteheti pip vagy conda használatával. Futtassa a következő parancsot a terminálon:
pip install langchain
Azok számára, akik a legújabb funkciókat kedvelik, és egy kicsit több kalandnak érzik magukat, közvetlenül a forrásból telepíthetik a LangChaint. Klónozza a tárolót, és navigáljon a langchain/libs/langchain
Könyvtár. Ezután futtassa:
pip install -e .
A kísérleti funkciókhoz fontolja meg a telepítést langchain-experimental
. Ez egy olyan csomag, amely élvonalbeli kódot tartalmaz, és kutatási és kísérleti célokra szolgál. Telepítse a következő használatával:
pip install langchain-experimental
A LangChain CLI egy praktikus eszköz a LangChain sablonokkal és LangServe projektekkel való munkához. A LangChain CLI telepítéséhez használja:
pip install langchain-cli
A LangServe elengedhetetlen a LangChain láncok REST API-ként történő üzembe helyezéséhez. A LangChain CLI mellé kerül telepítésre.
A LangChain gyakran igényel integrációt modellszolgáltatókkal, adattárolókkal, API-kkal stb. Ebben a példában az OpenAI modell API-jait fogjuk használni. Telepítse az OpenAI Python csomagot a következő használatával:
pip install openai
Az API eléréséhez állítsa be az OpenAI API-kulcsot környezeti változóként:
export OPENAI_API_KEY="your_api_key"
Alternatív megoldásként adja át a kulcsot közvetlenül a python-környezetben:
import os
os.environ['OPENAI_API_KEY'] = 'your_api_key'
A LangChain lehetővé teszi nyelvi modellalkalmazások létrehozását modulokon keresztül. Ezek a modulok önállóan vagy összetett felhasználási esetekre is összeállíthatók. Ezek a modulok –
- I/O modell: Megkönnyíti a különböző nyelvi modellekkel való interakciót, hatékonyan kezeli bemeneteiket és kimeneteiket.
- visszakeresés: Lehetővé teszi az alkalmazás-specifikus adatokhoz való hozzáférést és az azokkal való interakciót, ami kulcsfontosságú a dinamikus adathasználathoz.
- Ügynökök: Lehetővé teszi az alkalmazások számára a megfelelő eszközök kiválasztását magas szintű direktívák alapján, javítva ezzel a döntéshozatali képességeket.
- Láncok: Előre meghatározott, újrafelhasználható kompozíciókat kínál, amelyek az alkalmazásfejlesztés építőköveiként szolgálnak.
- Memory design: Fenntartja az alkalmazás állapotát több láncvégrehajtáson keresztül, ami elengedhetetlen a környezettudatos interakciókhoz.
Minden modul konkrét fejlesztési igényeket céloz meg, így a LangChain egy átfogó eszközkészlet a fejlett nyelvi modellalkalmazások létrehozásához.
A fenti komponensek mellett nálunk is van LangChain kifejezési nyelv (LCEL), amely deklaratív módja a modulok egyszerű összeállításának, és ez lehetővé teszi a komponensek láncolását egy univerzális Runnable interfész segítségével.
Az LCEL valahogy így néz ki –
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import BaseOutputParser # Example chain
chain = ChatPromptTemplate() | ChatOpenAI() | CustomOutputParser()
Most, hogy áttekintettük az alapokat, folytatjuk:
- Mélyebbre ásson minden Langchain modulban részletesen.
- Ismerje meg a LangChain Expression Language használatát.
- Fedezze fel a gyakori használati eseteket, és hajtsa végre azokat.
- Telepítsen egy végpontok közötti alkalmazást a LangServe segítségével.
- Nézze meg a LangSmith-t a hibakereséshez, teszteléshez és figyeléshez.
Lássunk neki!
I. modul: I/O modell
A LangChainben minden alkalmazás központi eleme a nyelvi modell körül forog. Ez a modul biztosítja az alapvető építőelemeket a hatékony interfészhez bármely nyelvi modellel, biztosítva a zökkenőmentes integrációt és kommunikációt.
A Model I/O kulcselemei
- LLM-ek és csevegési modellek (felváltva):
- LLM-ek:
- Meghatározás: Tiszta szövegkiegészítő modellek.
- Input / Output: Vegyen be egy szöveges karakterláncot bemenetként, és egy szöveges karakterláncot ad vissza kimenetként.
- Chat modellek
- LLM-ek:
- Meghatározás: Olyan modellek, amelyek egy nyelvi modellt használnak alapként, de különböznek a bemeneti és kimeneti formátumban.
- Input / Output: A csevegőüzenetek listájának elfogadása bemenetként, és csevegőüzenet küldése.
- Felszólítja: Modellbemenetek sablonozása, dinamikus kiválasztása és kezelése. Lehetővé teszi rugalmas és kontextus-specifikus promptok létrehozását, amelyek irányítják a nyelvi modell válaszait.
- Kimeneti elemzők: Információk kinyerése és formázása a modell kimeneteiből. Hasznos a nyelvi modellek nyers kimenetének strukturált adatokká vagy az alkalmazás által igényelt formátumokká alakításához.
LLM-ek
A LangChain integrációja olyan nagy nyelvi modellekkel (LLM), mint az OpenAI, a Cohere és a Hugging Face, a funkcionalitás alapvető eleme. Maga a LangChain nem üzemeltet LLM-eket, de egységes felületet kínál a különféle LLM-ekkel való interakcióhoz.
Ez a rész áttekintést nyújt az OpenAI LLM-burkoló használatáról a LangChainben, amely más LLM-típusokra is alkalmazható. Ezt már telepítettük az „Első lépések” részben. Inicializáljuk az LLM-et.
from langchain.llms import OpenAI
llm = OpenAI()
- Az LLM-ek végrehajtják a Futható felület, az alapvető építőelem a LangChain kifejezési nyelv (LCEL). Ez azt jelenti, hogy támogatják
invoke
,ainvoke
,stream
,astream
,batch
,abatch
,astream_log
felhívja. - Az LLM-ek elfogadják húrok bemenetként, vagy olyan objektumokként, amelyek karakterlánc-promptokra kényszeríthetők, beleértve
List[BaseMessage]
és aPromptValue
. (ezekről később)
Nézzünk néhány példát.
response = llm.invoke("List the seven wonders of the world.")
print(response)
Alternatív megoldásként meghívhatja a stream metódust a szöveges válasz streameléséhez.
for chunk in llm.stream("Where were the 2012 Olympics held?"): print(chunk, end="", flush=True)
Chat modellek
A LangChain csevegési modellekkel, a nyelvi modellek speciális változatával való integrációja elengedhetetlen az interaktív chat alkalmazások létrehozásához. Míg belső nyelvi modelleket használnak, a csevegési modellek külön felületet mutatnak be, amely a chat-üzenetek köré épül, mint bemenetek és kimenetek. Ez a rész részletes áttekintést nyújt az OpenAI csevegési modelljének LangChainben való használatáról.
from langchain.chat_models import ChatOpenAI
chat = ChatOpenAI()
A LangChain csevegési modelljei különböző üzenettípusokkal működnek, mint pl AIMessage
, HumanMessage
, SystemMessage
, FunctionMessage
és ChatMessage
(tetszőleges szerepparaméterrel). Általában, HumanMessage
, AIMessage
és SystemMessage
a leggyakrabban használtak.
A chat modellek elsősorban elfogadják List[BaseMessage]
bemenetekként. A karakterláncok átalakíthatók HumanMessage
és PromptValue
is támogatott.
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)
Felszólítja
A felszólítások elengedhetetlenek a nyelvi modellek irányításához a releváns és koherens kimenetek generálásához. Az egyszerű utasításoktól a bonyolult, néhány lépésből álló példákig terjedhetnek. A LangChainben a promptok kezelése nagyon egyszerű folyamat lehet, köszönhetően számos dedikált osztálynak és funkciónak.
LangChain PromptTemplate
osztály egy sokoldalú eszköz a szöveges promptok létrehozására. Pythont használ str.format
szintaxis, amely lehetővé teszi a dinamikus prompt generálást. Meghatározhat egy sablont helyőrzőkkel, és szükség szerint kitöltheti adott értékekkel.
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)
A csevegési modelleknél a felszólítások strukturáltabbak, és meghatározott szerepkörrel rendelkező üzeneteket tartalmaznak. LangChain kínál ChatPromptTemplate
erre a célra.
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)
Ez a megközelítés lehetővé teszi interaktív, vonzó chatbotok létrehozását dinamikus válaszokkal.
Mindkét PromptTemplate
és a ChatPromptTemplate
zökkenőmentesen integrálhatók a LangChain Expression Language (LCEL) nyelvvel, lehetővé téve számukra, hogy nagyobb, összetett munkafolyamatok részesei legyenek. Erről később bővebben fogunk beszélni.
Az egyéni prompt sablonok néha elengedhetetlenek az egyedi formázást vagy konkrét utasításokat igénylő feladatokhoz. Egyéni prompt sablon létrehozása magában foglalja a bemeneti változók és az egyéni formázási módszer meghatározását. Ez a rugalmasság lehetővé teszi a LangChain számára, hogy az alkalmazás-specifikus követelmények széles skáláját kielégítse. Bővebben itt.
A LangChain támogatja a néhány lépéses felszólítást is, lehetővé téve a modell számára, hogy tanuljon a példákból. Ez a funkció létfontosságú a kontextus megértését vagy meghatározott mintákat igénylő feladatokhoz. Kevés pillanatnyi prompt sablonok készíthetők példák halmazából vagy egy példaválasztó objektum használatával. Bővebben itt.
Kimeneti elemzők
A kimeneti elemzők döntő szerepet játszanak a Langchainben, lehetővé téve a felhasználók számára a nyelvi modellek által generált válaszok strukturálását. Ebben a részben megvizsgáljuk a kimeneti elemzők fogalmát, és kódpéldákat mutatunk be a Langchain PydanticOutputParser, SimpleJsonOutputParser, CommaSeparatedListOutputParser, DatetimeOutputParser és XMLOutputParser használatával.
PydanticOutputParser
A Langchain biztosítja a PydanticOutputParser-t a válaszok Pydantic adatstruktúrákba történő elemzéséhez. Az alábbiakban lépésről lépésre mutatunk be példát a használatára:
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)
A kimenet a következő lesz:
SimpleJsonOutputParser
A Langchain SimpleJsonOutputParser a JSON-szerű kimenetek elemzéséhez használatos. Íme egy példa:
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
A CommaSeparatedListOutputParser akkor hasznos, ha vesszővel tagolt listákat szeretne kivonni a modellválaszokból. Íme egy példa:
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
A Langchain DatetimeOutputParser a dátum és idő információk elemzésére szolgál. Használja a következőképpen:
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)
Ezek a példák azt mutatják be, hogy a Langchain kimeneti elemzői hogyan használhatók különféle típusú modellválaszok strukturálására, így alkalmassá téve azokat különböző alkalmazásokhoz és formátumokhoz. A kimeneti elemzők értékes eszközt jelentenek a nyelvi modell kimeneteinek használhatóságának és értelmezhetőségének javítására a Langchainben.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
II. modul: Visszakeresés
A LangChainben való visszakeresés döntő szerepet játszik az olyan alkalmazásokban, amelyek felhasználó-specifikus adatokat igényelnek, és amelyek nem szerepelnek a modell betanítókészletében. Ez a Retrieval Augmented Generation (RAG) néven ismert folyamat magában foglalja a külső adatok lekérését és integrálását a nyelvi modell létrehozási folyamatába. A LangChain eszközök és funkciók átfogó készletét kínálja ennek a folyamatnak a megkönnyítésére, mind az egyszerű, mind az összetett alkalmazásokhoz.
A LangChain egy sor komponensen keresztül éri el a visszakeresést, amelyeket egyenként tárgyalunk.
Dokumentumbetöltők
A LangChain dokumentumbetöltői lehetővé teszik az adatok kinyerését különböző forrásokból. A több mint 100 elérhető betöltővel számos dokumentumtípust, alkalmazást és forrást támogatnak (privát s3-tárolók, nyilvános webhelyek, adatbázisok).
Igényei alapján választhat dokumentumbetöltőt itt.
Mindezek a betöltők adatokat töltenek be dokumentum osztályok. Később megtanuljuk, hogyan kell használni a Dokumentum osztályokba bevitt adatokat.
Szöveges fájl betöltő: Töltsön be egy egyszerűt .txt
dokumentumba rögzíteni.
from langchain.document_loaders import TextLoader loader = TextLoader("./sample.txt")
document = loader.load()
CSV betöltő: Töltsön be egy CSV-fájlt egy dokumentumba.
from langchain.document_loaders.csv_loader import CSVLoader loader = CSVLoader(file_path='./example_data/sample.csv')
documents = loader.load()
A mezőnevek megadásával testreszabhatjuk az elemzést –
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 betöltők: A LangChain PDF-betöltői különféle módszereket kínálnak a PDF-fájlok elemzésére és tartalom kinyerésére. Minden betöltő más-más követelményeket elégít ki, és különböző mögöttes könyvtárakat használ. Az alábbiakban részletes példákat találunk az egyes rakodókra.
A PyPDFLoader az alapvető PDF-elemzéshez használható.
from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("example_data/layout-parser-paper.pdf")
pages = loader.load_and_split()
A MathPixLoader ideális matematikai tartalom és diagramok kinyerésére.
from langchain.document_loaders import MathpixPDFLoader loader = MathpixPDFLoader("example_data/math-content.pdf")
data = loader.load()
A PyMuPDFLoader gyors, és részletes metaadat-kinyerést tartalmaz.
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")
A PDFMiner Loader a szövegkivonás részletesebb szabályozására szolgál.
from langchain.document_loaders import PDFMinerLoader loader = PDFMinerLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
Az AmazonTextractPDFParser az AWS Textractot használja az OCR-hez és más fejlett PDF-elemzési funkciókhoz.
from langchain.document_loaders import AmazonTextractPDFLoader # Requires AWS account and configuration
loader = AmazonTextractPDFLoader("example_data/complex-layout.pdf")
documents = loader.load()
A PDFMinerPDFasHTMLLoader HTML-kódot generál PDF-ből szemantikai elemzéshez.
from langchain.document_loaders import PDFMinerPDFasHTMLLoader loader = PDFMinerPDFasHTMLLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
A PDFPlumberLoader részletes metaadatokat biztosít, és oldalanként egy dokumentumot támogat.
from langchain.document_loaders import PDFPlumberLoader loader = PDFPlumberLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
Integrált rakodók: A LangChain az egyéni betöltők széles választékát kínálja az adatok közvetlen betöltéséhez az alkalmazásokból (mint például a Slack, Sigma, Notion, Confluence, Google Drive és még sok más) és adatbázisokból, és felhasználhatja azokat LLM-alkalmazásokban.
A teljes lista az itt.
Az alábbiakban néhány példát mutatunk be ennek illusztrálására –
I. példa – Laza
A Slack, egy széles körben használt azonnali üzenetküldő platform, integrálható az LLM munkafolyamataiba és alkalmazásaiba.
- Nyissa meg a Slack Workspace Management oldalt.
- navigáljon
{your_slack_domain}.slack.com/services/export
. - Válassza ki a kívánt dátumtartományt, és indítsa el az exportálást.
- A Slack e-mailben és DM-ben értesíti az exportálást.
- Az export eredménye a
.zip
fájlt, amely a Letöltések mappában vagy a kijelölt letöltési útvonalon található. - Rendelje hozzá a letöltött fájl elérési útját
.zip
fájltLOCAL_ZIPFILE
. - Használja a
SlackDirectoryLoader
tóllangchain.document_loaders
csomag.
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. példa – Figma
A Figma, az interfésztervezés népszerű eszköze, REST API-t kínál az adatintegrációhoz.
- Szerezze be a Figma fájlkulcsot az URL formátumból:
https://www.figma.com/file/{filekey}/sampleFilename
. - A csomópontazonosítók az URL paraméterben találhatók
?node-id={node_id}
. - Hozzon létre egy hozzáférési tokent a következő helyen található utasítások szerint: Figma Súgó.
- A
FigmaFileLoader
osztálybóllangchain.document_loaders.figma
a Figma adatok betöltésére szolgál. - Különféle LangChain modulok, mint pl
CharacterTextSplitter
,ChatOpenAI
stb., feldolgozásra alkalmazzák.
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()
- A
generate_code
függvény a Figma adatokat használja a HTML/CSS kód létrehozásához. - Ez egy sablonos beszélgetést alkalmaz egy GPT-alapú modellel.
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)
- A
generate_code
A függvény végrehajtásakor a Figma tervezési bemenete alapján HTML/CSS kódot ad vissza.
Használjuk most tudásunkat néhány dokumentumkészlet létrehozására.
Először betöltünk egy PDF-et, a BCG éves fenntarthatósági jelentését.
Ehhez a PyPDFLoader-t használjuk.
from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("bcg-2022-annual-sustainability-report-apr-2023.pdf")
pdfpages = loader.load_and_split()
Az Airtable adatait most feldolgozzuk. Van egy Airtable, amely információkat tartalmaz a különféle OCR és adatkinyerési modellekről –
Ehhez használjuk az integrált rakodók listájában található AirtableLoader-t.
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()
Most folytassuk és tanuljuk meg ezeket a dokumentumosztályokat.
Dokumentum transzformátorok
A LangChain dokumentumtranszformátorai alapvető eszközök a dokumentumok kezeléséhez, amelyeket előző alfejezetünkben hoztunk létre.
Olyan feladatokhoz használatosak, mint például a hosszú dokumentumok kisebb darabokra bontása, kombinálása és szűrése, amelyek elengedhetetlenek a dokumentumok modell kontextusablakhoz való igazításához vagy speciális alkalmazási igények kielégítéséhez.
Az egyik ilyen eszköz a RecursiveCharacterTextSplitter, egy sokoldalú szövegelosztó, amely karakterlistát használ a felosztáshoz. Olyan paramétereket tesz lehetővé, mint a darabméret, az átfedés és a kezdőindex. Íme egy példa a Pythonban való használatára:
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])
Egy másik eszköz a CharacterTextSplitter, amely egy megadott karakter alapján osztja fel a szöveget, és vezérlőket tartalmaz a darabok méretéhez és az átfedéshez:
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])
A HTMLHeaderTextSplitter a HTML-tartalom fejléccímkék alapján történő felosztására szolgál, megtartva a szemantikai szerkezetet:
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])
Bonyolultabb manipuláció érhető el, ha a HTMLHeaderTextSplittert egy másik elosztóval kombináljuk, például a Pipelined Splitterrel:
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])
A LangChain speciális elosztókat is kínál különböző programozási nyelvekhez, például a Python kódosztóhoz és a JavaScript kódosztóhoz:
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])
A tokenszám alapján történő szövegfelosztáshoz, ami hasznos a tokenkorlátokkal rendelkező nyelvi modelleknél, a TokenTextSplitter használatos:
from langchain.text_splitter import TokenTextSplitter text_splitter = TokenTextSplitter(chunk_size=10)
texts = text_splitter.split_text(state_of_the_union)
print(texts[0])
Végül a LongContextReorder átrendezi a dokumentumokat, hogy megakadályozza a modellek teljesítményének hosszú kontextusok miatti romlását:
from langchain.document_transformers import LongContextReorder reordering = LongContextReorder()
reordered_docs = reordering.transform_documents(docs)
print(reordered_docs[0])
Ezek az eszközök különféle módokat mutatnak be a dokumentumok LangChainben történő átalakítására, az egyszerű szövegfelosztástól a bonyolult átrendezésig és a nyelvspecifikus felosztásig. A részletesebb és specifikusabb használati esetekért olvassa el a LangChain dokumentációját és integrációit.
Példáinkban a betöltők már darabolt dokumentumokat hoztak létre számunkra, és ez a rész már kezelve van.
Szövegbeágyazási modellek
A LangChain szövegbeágyazó modelljei szabványos felületet biztosítanak a különféle beágyazási modell-szolgáltatók számára, mint például az OpenAI, a Cohere és a Hugging Face. Ezek a modellek a szöveget vektoros reprezentációkká alakítják át, lehetővé téve az olyan műveleteket, mint a szemantikus keresés a vektortérbeli szöveghasonlóságon keresztül.
A szövegbeágyazási modellek használatának megkezdéséhez általában meghatározott csomagokat kell telepítenie, és be kell állítania az API-kulcsokat. Ezt már megtettük az OpenAI esetében
A LangChainben a embed_documents
metódus több szöveg beágyazására szolgál, megadva a vektoros ábrázolások listáját. Például:
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]))
Egyetlen szöveg, például keresési lekérdezés beágyazásához a embed_query
módszert alkalmazzák. Ez hasznos egy lekérdezés és egy dokumentumbeágyazás készletének összehasonlításához. Például:
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])
Ezeknek a beágyazásoknak a megértése kulcsfontosságú. Minden szövegrész vektorrá alakul, amelynek mérete a használt modelltől függ. Például az OpenAI modellek általában 1536 dimenziós vektorokat állítanak elő. Ezeket a beágyazásokat ezután a releváns információk lekérésére használják.
A LangChain beágyazási funkciója nem korlátozódik az OpenAI-ra, hanem különféle szolgáltatókkal való együttműködésre tervezték. A beállítás és a használat némileg eltérhet a szolgáltatótól függően, de a szövegek vektortérbe történő beágyazásának alapvető koncepciója változatlan marad. A részletes használathoz, beleértve a speciális konfigurációkat és a különböző beágyazási modell-szolgáltatókkal való integrációkat, az Integrációk részben található LangChain dokumentáció értékes forrás.
Vektor üzletek
A LangChain vektoráruházai támogatják a szövegbeágyazások hatékony tárolását és keresését. A LangChain több mint 50 vektortárral integrálható, szabványos felületet biztosítva a könnyű használat érdekében.
Példa: Beágyazások tárolása és keresése
A szövegek beágyazása után vektortárban tárolhatjuk, mint pl Chroma
és végezzen hasonlósági keresést:
from langchain.vectorstores import Chroma db = Chroma.from_texts(embedded_texts)
similar_texts = db.similarity_search("search query")
Alternatív megoldásként használjuk a FAISS vektortárat dokumentumaink indexeinek létrehozására.
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS pdfstore = FAISS.from_documents(pdfpages, embedding=OpenAIEmbeddings()) airtablestore = FAISS.from_documents(airtabledocs, embedding=OpenAIEmbeddings())
Retrieverek
A LangChain visszakeresői olyan interfészek, amelyek strukturálatlan lekérdezésekre válaszul dokumentumokat adnak vissza. Általánosabbak, mint a vektortárak, és a tárolás helyett a visszakeresésre összpontosítanak. Bár a vektortárak használhatók a retriever gerinceként, vannak más típusú retrieverek is.
A Chroma retriever beállításához először telepítse a segítségével pip install chromadb
. Ezután számos Python-parancs segítségével betöltheti, feloszthatja, beágyazhatja és visszakeresheti a dokumentumokat. Íme egy kódpélda egy Chroma retriever beállításához:
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)
A MultiQueryRetriever automatizálja az azonnali hangolást azáltal, hogy több lekérdezést generál egy felhasználói beviteli lekérdezéshez, és egyesíti az eredményeket. Íme egy példa az egyszerű használatára:
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))
A LangChain kontextus szerinti tömörítése a lekérdezés kontextusának használatával tömöríti a letöltött dokumentumokat, biztosítva, hogy csak a releváns információk kerüljenek visszaadásra. Ez magában foglalja a tartalom csökkentését és a kevésbé releváns dokumentumok kiszűrését. A következő kódpélda bemutatja a Contextual Compression Retriever használatát:
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)
Az EnsembleRetriever különböző visszakeresési algoritmusokat kombinál a jobb teljesítmény elérése érdekében. Példa a BM25 és a FAISS retrieverek kombinálására a következő kódban:
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)
A LangChain MultiVector Retriever funkciója lehetővé teszi a dokumentumok lekérdezését dokumentumonként több vektorral, ami hasznos a dokumentumon belüli különböző szemantikai szempontok rögzítéséhez. Több vektor létrehozásának módszerei közé tartozik a kisebb darabokra bontás, az összegzés vagy a hipotetikus kérdések generálása. A dokumentumok kisebb darabokra való felosztásához a következő Python-kód használható:
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)))
Egy másik módszer az összefoglalók generálása a jobb visszakeresés érdekében a fókuszáltabb tartalommegjelenítés miatt. Íme egy példa az összefoglalók létrehozására:
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)))
Egy másik megközelítés az egyes dokumentumokra vonatkozó hipotetikus kérdések generálása LLM segítségével. Ezt a következő kóddal lehet megtenni:
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)))
A Parent Document Retriever egy másik visszakereső, amely egyensúlyt teremt a beágyazás pontossága és a kontextus megtartása között azáltal, hogy kis darabokat tárol, és visszakeresi a nagyobb szülődokumentumait. Megvalósítása a következő:
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")
Az önlekérdező retriever természetes nyelvi bemenetekből strukturált lekérdezéseket hoz létre, és alkalmazza azokat az alapul szolgáló VectorStore-ban. Megvalósítását a következő kód mutatja:
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")
A WebResearchRetriever egy adott lekérdezés alapján végez webkutatást –
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")
Példáinkhoz használhatjuk a vektortár objektumunk részeként már megvalósított szabványos retrievert is, az alábbiak szerint:
Most már lekérdezhetjük a retrievereket. Lekérdezésünk kimenete a lekérdezés szempontjából releváns dokumentum objektumok lesz. Ezeket végül felhasználják a releváns válaszok létrehozására a további szakaszokban.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
III. modul: Ügynökök
A LangChain bemutatja az „ügynökök” nevű hatékony koncepciót, amely a láncok gondolatát egy teljesen új szintre emeli. Az ügynökök a nyelvi modellek segítségével dinamikusan határozzák meg a végrehajtandó műveletek sorozatát, így ezek hihetetlenül sokoldalúak és adaptívak. A hagyományos láncoktól eltérően, ahol a műveletek kódolva vannak, az ügynökök nyelvi modelleket alkalmaznak érvelési motorként annak eldöntésére, hogy milyen műveleteket és milyen sorrendben hajtsanak végre.
Az ügynök a döntéshozatalért felelős központi elem. Kiaknázza egy nyelvi modell erejét, és egy adott cél eléréséhez szükséges következő lépések meghatározására ösztönöz. Az ügynök bemenetei általában a következőket tartalmazzák:
- Eszközök: Az elérhető eszközök leírása (erről később).
- Felhasználói bevitel: Magas szintű cél vagy lekérdezés a felhasználótól.
- Köztes lépések: Az aktuális felhasználói bevitel eléréséhez végrehajtott (művelet, eszköz kimenet) párok előzményei.
Egy ügynök kimenete lehet a következő akció intézkedni (AgentActions) vagy a döntőt válasz küldeni a felhasználónak (AgentFinish). egy akció meghatározza a szerszám és a bemenet ahhoz az eszközhöz.
Eszközök
Az eszközök olyan interfészek, amelyek segítségével az ügynök kapcsolatba léphet a világgal. Lehetővé teszik az ügynökök számára különféle feladatok elvégzését, például keresést az interneten, shell-parancsok futtatását vagy külső API-k elérését. A LangChainben az eszközök elengedhetetlenek az ügynökök képességeinek bővítéséhez, és lehetővé teszik számukra, hogy különféle feladatokat hajtsanak végre.
A LangChain eszközeinek használatához a következő kódrészlet segítségével töltheti be őket:
from langchain.agents import load_tools tool_names = [...]
tools = load_tools(tool_names)
Egyes eszközök inicializálásához alapnyelvi modellre (LLM) lehet szükség. Ilyen esetekben átadhatja az LLM-et is:
from langchain.agents import load_tools tool_names = [...]
llm = ...
tools = load_tools(tool_names, llm=llm)
Ezzel a beállítással különféle eszközökhöz férhet hozzá, és integrálhatja azokat ügynöke munkafolyamataiba. Az eszközök teljes listája használati dokumentációval a itt.
Nézzünk néhány példát az eszközökre.
DuckDuckGo
A DuckDuckGo eszköz lehetővé teszi, hogy internetes kereséseket végezzen keresőmotorja segítségével. Használja a következőképpen:
from langchain.tools import DuckDuckGoSearchRun
search = DuckDuckGoSearchRun()
search.run("manchester united vs luton town match summary")
DataForSeo
A DataForSeo eszközkészlet lehetővé teszi, hogy a DataForSeo API használatával keresőmotor-eredményeket kapjon. Az eszközkészlet használatához be kell állítania az API hitelesítő adatait. A hitelesítő adatok konfigurálása a következőképpen történik:
import os os.environ["DATAFORSEO_LOGIN"] = "<your_api_access_username>"
os.environ["DATAFORSEO_PASSWORD"] = "<your_api_access_password>"
Miután beállította a hitelesítő adatait, létrehozhat a DataForSeoAPIWrapper
eszköz az API eléréséhez:
from langchain.utilities.dataforseo_api_search import DataForSeoAPIWrapper wrapper = DataForSeoAPIWrapper() result = wrapper.run("Weather in Los Angeles")
A DataForSeoAPIWrapper
eszköz különböző forrásokból keresi le a keresőmotorok eredményeit.
Testreszabhatja a JSON-válaszban visszaadott eredmények és mezők típusát. Megadhatja például az eredménytípusokat, mezőket, és beállíthatja a visszaadandó legjobb eredmények maximális számát:
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")
Ez a példa az eredménytípusok, mezők megadásával és az eredmények számának korlátozásával testreszabja a JSON-választ.
A keresési eredmények helyét és nyelvét is megadhatja, ha további paramétereket ad át az API burkolónak:
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")
Helyi és nyelvi paraméterek megadásával a keresési eredményeket adott régiókhoz és nyelvekhez szabhatja.
Rugalmasan választhatja ki a használni kívánt keresőmotort. Egyszerűen adja meg a kívánt keresőt:
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")
Ebben a példában a keresés testreszabott a Bing keresőmotorként való használatára.
Az API burkoló azt is lehetővé teszi, hogy megadja a végrehajtani kívánt keresés típusát. Például keresést végezhet a térképen:
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")
Ezzel testreszabhatja a keresést a térképekkel kapcsolatos információk lekéréséhez.
Shell (bash)
A Shell eszközkészlet hozzáférést biztosít az ügynökök számára a shell-környezethez, lehetővé téve számukra a shell-parancsok végrehajtását. Ez a funkció hatékony, de óvatosan kell használni, különösen sandbox környezetben. Így használhatja a Shell eszközt:
from langchain.tools import ShellTool shell_tool = ShellTool() result = shell_tool.run({"commands": ["echo 'Hello World!'", "time"]})
Ebben a példában a Shell eszköz két héjparancsot futtat: a „Hello World!” parancsot visszhangozza. és megjeleníti az aktuális időt.
A Shell eszközt az ügynökök rendelkezésére bocsáthatja összetettebb feladatok elvégzéséhez. Íme egy példa arra, hogy egy ügynök a Shell eszköz segítségével hivatkozásokat gyűjt le egy weboldalról:
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."
)
Ebben a forgatókönyvben az ügynök a Shell eszközt használja egy parancssorozat végrehajtására az URL-ek weboldalról való lekérésére, szűrésére és rendezésére.
A bemutatott példák a LangChainben elérhető néhány eszközt mutatnak be. Ezek az eszközök végső soron kibővítik az ügynökök képességeit (amelyeket a következő alfejezetben tárgyalunk), és képessé teszik őket különböző feladatok hatékony végrehajtására. Igényeitől függően kiválaszthatja azokat az eszközöket és eszközkészleteket, amelyek a legjobban megfelelnek a projekt igényeinek, és integrálhatja azokat ügynöke munkafolyamataiba.
Vissza az ügynökökhöz
Most térjünk át az ügynökökre.
Az AgentExecutor az ügynök futási környezete. Felelős az ügynök meghívásáért, az általa kiválasztott műveletek végrehajtásáért, a műveleti kimenetek visszaadásáért az ügynöknek, és a folyamat megismétléséért, amíg az ügynök be nem fejezi. A pszeudokódban az AgentExecutor valahogy így nézhet ki:
next_action = agent.get_action(...)
while next_action != AgentFinish: observation = run(next_action) next_action = agent.get_action(..., next_action, observation)
return next_action
Az AgentExecutor különféle bonyolultságokat kezel, például olyan eseteket, amikor az ügynök nem létező eszközt választ ki, az eszközhibákat, az ügynök által előállított kimeneteket, valamint a naplózást és a megfigyelhetőséget minden szinten.
Míg az AgentExecutor osztály az elsődleges ügynök futási környezet a LangChainben, más, inkább kísérleti futási környezet is támogatott, többek között:
- Tervezés és végrehajtás ügynök
- Baba AGI
- Auto GPT
Az ügynökkeretrendszer jobb megértése érdekében készítsünk egy alapügynököt a semmiből, majd folytassuk az előre elkészített ügynökök felfedezését.
Mielőtt belemerülnénk az ügynök felépítésébe, feltétlenül át kell tekintenünk néhány kulcsfontosságú terminológiát és sémát:
- AgentAction: Ez egy adatosztály, amely azt a műveletet képviseli, amelyet az ügynöknek meg kell tennie. Ez áll a
tool
tulajdonság (a meghívandó eszköz neve) és atool_input
tulajdonság (az eszköz bemenete). - AgentFinish: Ez az adatosztály azt jelzi, hogy az ügynök befejezte a feladatát, és választ kell adnia a felhasználónak. Jellemzően tartalmazza a visszatérési értékek szótárát, gyakran egy kulcs „kimenettel”, amely tartalmazza a válaszszöveget.
- Köztes lépések: Ezek a korábbi ügynökműveletek és a megfelelő kimenetek rekordjai. Kulcsfontosságúak a kontextus átadásához az ügynök jövőbeli iterációihoz.
Példánkban az OpenAI függvényhívást fogjuk használni ügynökünk létrehozásához. Ez a megközelítés megbízható ügynök létrehozásához. Kezdjük egy egyszerű eszköz létrehozásával, amely kiszámítja a szó hosszát. Ez az eszköz hasznos, mert a nyelvi modellek időnként hibákat követhetnek el a tokenizálás miatt a szóhosszak számlálása során.
Először töltsük be az ügynök vezérlésére használt nyelvi modellt:
from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
Teszteljük a modellt szóhossz-számítással:
llm.invoke("how many letters in the word educa?")
A válaszban fel kell tüntetni az „educa” szó betűinek számát.
Ezután definiálunk egy egyszerű Python-függvényt egy szó hosszának kiszámításához:
from langchain.agents import tool @tool
def get_word_length(word: str) -> int: """Returns the length of a word.""" return len(word)
Létrehoztunk egy nevű eszközt get_word_length
amely egy szót vesz bevitelként, és visszaadja a hosszát.
Most hozzuk létre a promptot az ügynök számára. A prompt utasítja az ügynököt a kimenet érvelésére és formázására. Esetünkben OpenAI Function Calling-ot használunk, amely minimális utasításokat igényel. Meghatározzuk a promptot helyőrzőkkel a felhasználói bevitelhez és az ügynök jegyzettömbjéhez:
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"), ]
)
Nos, honnan tudja az ügynök, hogy milyen eszközöket használhat? Az OpenAI függvényhívási nyelvi modellekre támaszkodunk, amelyekhez a függvényeket külön kell átadni. Ahhoz, hogy eszközeinket biztosítsuk az ügynöknek, OpenAI függvényhívásként formázzuk őket:
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])
Most létrehozhatjuk az ügynököt a bemeneti leképezések meghatározásával és a komponensek összekapcsolásával:
Ez az LCEL nyelv. Erről később részletesen beszélünk.
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()
)
Létrehoztuk ügynökünket, amely megérti a felhasználói bevitelt, használja a rendelkezésre álló eszközöket, és formázza a kimenetet. Most pedig lépjünk kapcsolatba vele:
agent.invoke({"input": "how many letters in the word educa?", "intermediate_steps": []})
Az ügynöknek egy AgentAction-vel kell válaszolnia, jelezve a következő műveletet.
Létrehoztuk az ügynököt, de most futási környezetet kell írnunk hozzá. A legegyszerűbb futási idő az, amely folyamatosan hívja az ügynököt, végrehajtja a műveleteket, és addig ismétli, amíg az ügynök be nem fejezi. Íme egy példa:
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)
Ebben a ciklusban ismételten meghívjuk az ügynököt, végrehajtjuk a műveleteket, és frissítjük a közbenső lépéseket, amíg az ügynök be nem fejeződik. A hurkon belüli szerszámkölcsönhatásokat is kezeljük.
A folyamat leegyszerűsítése érdekében a LangChain biztosítja az AgentExecutor osztályt, amely magában foglalja az ügynök végrehajtását, és hibakezelést, korai leállítást, nyomkövetést és egyéb fejlesztéseket kínál. Használjuk az AgentExecutort az ügynökkel való interakcióhoz:
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?"})
Az AgentExecutor leegyszerűsíti a végrehajtási folyamatot, és kényelmes módot biztosít az ügynökkel való kapcsolattartásra.
Az emlékezetről a későbbiekben részletesen is lesz szó.
Az általunk eddig létrehozott ügynök hontalan, vagyis nem emlékszik a korábbi interakciókra. A további kérdések és beszélgetések engedélyezéséhez memóriát kell hozzáadnunk az ügynökhöz. Ez két lépésből áll:
- Adjon hozzá egy memóriaváltozót a prompthoz a csevegési előzmények tárolásához.
- Az interakciók során kövesse nyomon a csevegési előzményeket.
Kezdjük azzal, hogy adjunk hozzá egy memóriahelyőrzőt a prompthoz:
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"), ]
)
Most hozzon létre egy listát a csevegési előzmények nyomon követéséhez:
from langchain.schema.messages import HumanMessage, AIMessage chat_history = []
Az ügynök létrehozási lépésében a memóriát is belefoglaljuk:
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()
)
Most, amikor az ügynököt futtatja, mindenképpen frissítse a csevegési előzményeket:
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})
Ez lehetővé teszi az ügynök számára, hogy beszélgetési előzményeket tartson fenn, és a korábbi interakciók alapján válaszoljon a további kérdésekre.
Gratulálunk! Sikeresen létrehozta és végrehajtotta első végpontok közötti ügynökét a LangChainben. A LangChain képességeinek mélyebb megismeréséhez fedezze fel:
- Különféle ügynöktípusok támogatottak.
- Előre elkészített ügynökök
- Hogyan kell dolgozni eszközökkel és eszközintegrációkkal.
Ügynöktípusok
A LangChain különféle ügynöktípusokat kínál, amelyek mindegyike speciális felhasználási esetekre alkalmas. Íme néhány elérhető ügynök:
- Zero-shot ReAct: Ez az ügynök a ReAct keretrendszert használja az eszközök kiválasztásához kizárólag azok leírása alapján. Minden eszköz leírását igényli, és rendkívül sokoldalú.
- ReAct strukturált bemenet: Ez az ügynök több bevitelű eszközöket kezel, és alkalmas összetett feladatokra, például a webböngészőben való navigálásra. Eszközök argumentumsémáját használja a strukturált bevitelhez.
- OpenAI funkciók: Kifejezetten a funkcióhívásra finomhangolt modellekhez készült, ez az ügynök olyan modellekkel kompatibilis, mint a gpt-3.5-turbo-0613 és a gpt-4-0613. Ezt használtuk fel az első ügynökünk létrehozásához.
- Társalgó: A párbeszédes beállításokhoz tervezett ügynök a ReAct használja az eszközök kiválasztásához, és memóriát használ a korábbi interakciók emlékezésére.
- Önkérdezés kereséssel: Ez az ügynök egyetlen eszközre, az „Intermediate Answer”-re támaszkodik, amely tényszerű válaszokat keres a kérdésekre. Ez megegyezik az eredeti önkéréssel a keresőpapírral.
- ReAct dokumentumtár: Ez az ügynök a ReAct keretrendszer használatával kölcsönhatásba lép egy dokumentumtárolóval. „Keresés” és „Keresés” eszközöket igényel, és hasonló az eredeti ReAct papír Wikipédia-példájához.
Fedezze fel ezeket az ügynöktípusokat, hogy megtalálja az igényeinek leginkább megfelelőt a LangChainben. Ezek az ügynökök lehetővé teszik, hogy eszközöket rendeljen hozzájuk a műveletek kezeléséhez és a válaszok generálásához. Tudjon meg többet erről hogyan építheti fel saját ügynökét az itteni eszközökkel.
Előre elkészített ügynökök
Folytassuk az ügynökök feltárását, összpontosítva a LangChainben elérhető előre elkészített ügynökökre.
Gmail
A LangChain egy Gmail-eszközkészletet kínál, amely lehetővé teszi a LangChain e-mailek összekapcsolását a Gmail API-val. A kezdéshez be kell állítania a hitelesítő adatait, amelyek leírása a Gmail API dokumentációjában található. Miután letöltötte a credentials.json
fájlt, folytathatja a Gmail API használatával. Ezenkívül telepítenie kell néhány szükséges könyvtárat a következő parancsokkal:
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
A Gmail eszköztárat a következőképpen hozhatja létre:
from langchain.agents.agent_toolkits import GmailToolkit toolkit = GmailToolkit()
A hitelesítést igényei szerint is testreszabhatja. A színfalak mögött egy googleapi-erőforrás jön létre a következő módszerekkel:
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)
Az eszköztár különféle eszközöket kínál, amelyek egy ügynökön belül használhatók, többek között:
GmailCreateDraft
: Hozzon létre egy e-mail piszkozatot meghatározott üzenetmezőkkel.GmailSendMessage
: E-mail üzenetek küldése.GmailSearch
: E-mail üzenetek vagy szálak keresése.GmailGetMessage
: E-mail lekérése üzenetazonosítóval.GmailGetThread
: E-mail üzenetek keresése.
Ezen eszközök ügynökön belüli használatához a következőképpen inicializálhatja az ügynököt:
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,
)
Íme néhány példa ezeknek az eszközöknek a használatára:
- Hozzon létre egy Gmail-piszkozatot szerkesztéshez:
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."
)
- A legújabb e-mail keresése a piszkozatokban:
agent.run("Could you search in my drafts for the latest email?")
Ezek a példák bemutatják a LangChain Gmail-eszközkészletének képességeit egy ügynökön belül, lehetővé téve a Gmaillel programozott interakciót.
SQL Database Agent
Ez a szakasz áttekintést nyújt az SQL-adatbázisokkal, különösen a Chinook adatbázissal való interakcióra tervezett ügynökről. Ez az ügynök válaszol az adatbázisokkal kapcsolatos általános kérdésekre, és helyreállíthatja a hibákat. Felhívjuk figyelmét, hogy még mindig aktív fejlesztés alatt áll, és nem minden válasz helyes. Legyen óvatos, amikor érzékeny adatokon futtatja, mivel DML utasításokat hajthat végre az adatbázisban.
Az ügynök használatához a következőképpen inicializálhatja:
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,
)
Ez az ügynök inicializálható a ZERO_SHOT_REACT_DESCRIPTION
ügynök típus. Úgy tervezték, hogy válaszoljon a kérdésekre és leírásokat adjon. Alternatív megoldásként inicializálhatja az ügynököt a OPENAI_FUNCTIONS
ügynöktípus az OpenAI GPT-3.5-turbo modelljével, amelyet korábbi kliensünkben használtunk.
A felelősség megtagadása
- A lekérdezési lánc beszúrási/frissítési/törlési lekérdezéseket generálhat. Legyen óvatos, és szükség esetén használjon egyéni promptot, vagy hozzon létre egy SQL-felhasználót írási engedélyek nélkül.
- Ügyeljen arra, hogy bizonyos lekérdezések futtatása, például a „lehető legnagyobb lekérdezés futtatása” túlterhelheti az SQL-adatbázist, különösen, ha az több millió sort tartalmaz.
- Az adattárház-orientált adatbázisok gyakran támogatják a felhasználói szintű kvótákat az erőforrás-felhasználás korlátozása érdekében.
Megkérheti az ügynököt, hogy írjon le egy táblázatot, például a „playlisttrack” táblát. Íme egy példa, hogyan kell csinálni:
agent_executor.run("Describe the playlisttrack table")
Az ügynök tájékoztatást ad a tábla sémájáról és a mintasorokról.
Ha tévedésből egy nem létező táblára kérdez rá, az ügynök helyreállíthatja és információt szolgáltathat a legközelebbi egyező tábláról. Például:
agent_executor.run("Describe the playlistsong table")
Az ügyintéző megkeresi a legközelebbi megfelelő táblázatot, és tájékoztatást ad róla.
Megkérheti az ügynököt is, hogy futtasson lekérdezéseket az adatbázisban. Például:
agent_executor.run("List the total sales per country. Which country's customers spent the most?")
Az ügynök végrehajtja a lekérdezést, és megadja az eredményt, például azt az országot, ahol a legmagasabb az eladások száma.
Az egyes lejátszási listákban található számok teljes számának megtekintéséhez használja a következő lekérdezést:
agent_executor.run("Show the total number of tracks in each playlist. The Playlist name should be included in the result.")
Az ügynök visszaadja a lejátszási listák nevét a megfelelő számok teljes számával együtt.
Azokban az esetekben, amikor az ügynök hibákat észlel, képes helyreállítani és pontos válaszokat adni. Például:
agent_executor.run("Who are the top 3 best selling artists?")
Az ügynök még a kezdeti hiba észlelése után is igazodik, és megadja a helyes választ, ami jelen esetben a 3 legkelendőbb művész.
Pandas DataFrame Agent
Ez a rész egy ügynököt mutat be, amelyet arra terveztek, hogy a Pandas DataFrames-szel interakcióba lépjen kérdések megválaszolása céljából. Felhívjuk figyelmét, hogy ez az ügynök a Python-ügynököt használja a nyelvi modell (LLM) által generált Python-kód végrehajtásához. Legyen körültekintő az ügynök használatakor, hogy elkerülje az LLM által generált rosszindulatú Python-kód esetleges kárait.
A Pandas DataFrame ügynököt a következőképpen inicializálhatja:
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,
# )
Megkérheti az ügynököt, hogy számolja meg a sorok számát a DataFrame-ben:
agent.run("how many rows are there?")
Az ügynök végrehajtja a kódot df.shape[0]
és adja meg a választ, például „891 sor van az adatkeretben”.
Arra is kérheti az ügynököt, hogy bizonyos kritériumok alapján szűrje le a sorokat, például a 3-nál több testvérrel rendelkező személyek számát:
agent.run("how many people have more than 3 siblings")
Az ügynök végrehajtja a kódot df[df['SibSp'] > 3].shape[0]
és adja meg a választ, például „30 embernek 3-nál több testvére van”.
Ha az átlagéletkor négyzetgyökét szeretné kiszámítani, kérdezze meg az ügynököt:
agent.run("whats the square root of the average age?")
Az ügynök a segítségével kiszámítja az átlagos életkort df['Age'].mean()
majd kiszámítja a négyzetgyököt a segítségével math.sqrt()
. Ez megadja a választ, például: „Az átlagéletkor négyzetgyöke 5.449689683556195.”
Hozzuk létre a DataFrame másolatát, és a hiányzó életkor értékeket az átlagéletkor tölti ki:
df1 = df.copy()
df1["Age"] = df1["Age"].fillna(df1["Age"].mean())
Ezután inicializálhatja az ügynököt mindkét DataFrame-mel, és feltehet neki egy kérdést:
agent = create_pandas_dataframe_agent(OpenAI(temperature=0), [df, df1], verbose=True)
agent.run("how many rows in the age column are different?")
Az ügynök összehasonlítja a koroszlopokat mindkét DataFrame-ben, és megadja a választ, például „177 sor az életkor oszlopban különbözik egymástól”.
Jira Toolkit
Ez a rész elmagyarázza, hogyan kell használni a Jira eszközkészletet, amely lehetővé teszi az ügynökök számára a Jira-példányokkal való interakciót. Ezzel az eszköztárral különféle műveleteket hajthat végre, például problémákat kereshet és problémákat hozhat létre. Az atlassian-python-api könyvtárat használja. Az eszközkészlet használatához környezeti változókat kell beállítania a Jira-példányhoz, beleértve a JIRA_API_TOKEN, JIRA_USERNAME és JIRA_INSTANCE_URL értéket. Ezenkívül előfordulhat, hogy be kell állítania az OpenAI API-kulcsot környezeti változóként.
A kezdéshez telepítse az atlassian-python-api könyvtárat, és állítsa be a szükséges környezeti változókat:
%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
)
Utasíthatja az ügynököt, hogy hozzon létre egy új problémát egy adott projektben összefoglalással és leírással:
agent.run("make a new issue in project PW to remind me to make more fried rice")
Az ügynök végrehajtja a szükséges műveleteket a probléma létrehozásához és a válaszadáshoz, például „Új kiadást hoztak létre a PW projektben a „Készíts több sült rizst” összefoglalóval és „Emlékeztető, hogy több sült rizst” leírással.
Ez lehetővé teszi, hogy a természetes nyelvi utasítások és a Jira eszközkészlet segítségével kommunikáljon a Jira példányával.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
IV. modul: Láncok
A LangChain egy olyan eszköz, amelyet a nagy nyelvi modellek (LLM) komplex alkalmazásokban történő felhasználására terveztek. Keretrendszereket biztosít az összetevők láncainak létrehozásához, beleértve az LLM-eket és más típusú összetevőket. Két elsődleges keretrendszer
- A LangChain kifejezési nyelv (LCEL)
- Legacy Chain interfész
A LangChain Expression Language (LCEL) egy szintaxis, amely lehetővé teszi a láncok intuitív összeállítását. Támogatja az olyan fejlett funkciókat, mint a streaming, az aszinkron hívások, a kötegelés, a párhuzamosítás, az újrapróbálkozások, a tartalékok és a nyomkövetés. Például összeállíthat egy promptot, modellt és kimeneti elemzőt az LCEL-ben, ahogy az a következő kódban látható:
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)
Alternatív megoldásként az LLMChain az LCEL-hez hasonló opció az összetevők összeállításához. Az LLMChain példa a következő:
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")
A LangChain láncai egy memóriaobjektum beépítésével állapottartók is lehetnek. Ez lehetővé teszi az adatok fennmaradását a hívások között, amint az az alábbi példában látható:
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?")
A LangChain támogatja az OpenAI függvényhívó API-kkal való integrációt is, ami hasznos a strukturált kimenetek megszerzéséhez és a láncon belüli funkciók végrehajtásához. A strukturált kimenetek megszerzéséhez megadhatja őket Pydantic osztályok vagy JsonSchema segítségével, az alábbiak szerint:
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"})
Strukturált kimenetek esetén az LLMChain-t használó örökölt megközelítés is elérhető:
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")
A LangChain az OpenAI funkciókat használja fel, hogy különféle speciális láncokat hozzon létre különböző célokra. Ide tartoznak a kivonatoláshoz, címkézéshez, OpenAPI-hoz és a QA-hoz kapcsolódó láncok hivatkozásokkal.
A kinyeréssel összefüggésben a folyamat hasonló a strukturált kimeneti lánchoz, de az információ- vagy entitáskinyerésre összpontosít. A címkézéshez az az ötlet, hogy egy dokumentumot olyan osztályokkal jelöljenek meg, mint a hangulat, a nyelv, a stílus, a tárgyalt témák vagy a politikai irányzat.
A címkézés működésére a LangChainben egy példa Python kóddal mutatható be. A folyamat a szükséges csomagok telepítésével és a környezet beállításával kezdődik:
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
Meg van határozva a címkézési séma, megadva a tulajdonságokat és azok várható típusait:
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)
Példák a címkézési lánc különböző bemenetekkel történő futtatására mutatják be a modell azon képességét, hogy értelmezze az érzelmeket, a nyelveket és az agresszivitást:
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'}
A pontosabb vezérlés érdekében a séma pontosabban definiálható, beleértve a lehetséges értékeket, leírásokat és a szükséges tulajdonságokat. Az alábbiakban látható egy példa erre a továbbfejlesztett vezérlésre:
schema = { "properties": { # Schema definitions here }, "required": ["language", "sentiment", "aggressiveness"],
} chain = create_tagging_chain(schema, llm)
A Pydantic sémák címkézési feltételek meghatározására is használhatók, így Pythonic módot biztosítanak a szükséges tulajdonságok és típusok meghatározására:
from enum import Enum
from pydantic import BaseModel, Field class Tags(BaseModel): # Class fields here chain = create_tagging_chain_pydantic(Tags, llm)
Ezenkívül a LangChain metaadat-címkéző dokumentumtranszformátora használható metaadatok kinyerésére a LangChain dokumentumokból, amely hasonló funkciókat kínál, mint a címkézési lánc, de alkalmazható LangChain dokumentumokra.
A visszakereső források idézése a LangChain másik funkciója, amely OpenAI függvényeket használ az idézetek szövegből való kinyerésére. Ezt a következő kód mutatja:
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
A LangChainben a Large Language Model (LLM) alkalmazásokban a láncolás általában magában foglalja a prompt sablonok LLM-mel és opcionálisan egy kimeneti elemzővel való kombinálását. Ennek javasolt módja a LangChain Expression Language (LCEL), bár az örökölt LLMChain megközelítés is támogatott.
Az LCEL használatával a BasePromptTemplate, a BaseLanguageModel és a BaseOutputParser mind megvalósítják a Runnable felületet, és könnyen egymásba illeszthetők. Íme egy példa, amely ezt demonstrálja:
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'
Az útválasztás a LangChainben lehetővé teszi nem determinisztikus láncok létrehozását, ahol az előző lépés kimenete határozza meg a következő lépést. Ez segít az LLM-ekkel való interakciók strukturálásában és konzisztenciájának fenntartásában. Például, ha két különböző típusú kérdésekre optimalizált sablonja van, kiválaszthatja a sablont a felhasználói bevitel alapján.
A következőképpen érheti el ezt az LCEL használatával egy RunnableBranch-al, amely (feltétel, futtatható) párok listájával és egy alapértelmezett futtatható elemmel van inicializálva:
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
A végső láncot ezután különféle összetevők, például témaosztályozó, prompt ág és kimeneti elemző segítségével állítják össze, hogy meghatározzák az áramlást a bemenet témája alapján:
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
Ez a megközelítés jól példázza a LangChain rugalmasságát és erejét az összetett lekérdezések kezelésében és a bemenet alapján történő megfelelő útválasztásban.
A nyelvi modellek birodalmában bevett gyakorlat az, hogy egy kezdeti hívást egy sor következő hívás követ, az egyik hívás kimenetét használva bemenetként a következőhöz. Ez a szekvenciális megközelítés különösen előnyös, ha a korábbi interakciók során keletkezett információkra kíván építeni. Míg a LangChain Expression Language (LCEL) az ajánlott módszer ezeknek a szekvenciáknak a létrehozásához, a SequentialChain módszer visszamenőleges kompatibilitása továbbra is dokumentált.
Ennek illusztrálására nézzünk meg egy olyan forgatókönyvet, amelyben először készítünk egy színdarab-összefoglalót, majd a szinopszis alapján egy áttekintést. Python használata langchain.prompts
, létrehozunk kettőt PromptTemplate
példányok: egy a szinopszishoz, egy másik pedig az áttekintéshez. Íme a kód a sablonok beállításához:
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:"
)
Az LCEL megközelítésben ezeket a promptokat a következővel láncoljuk ChatOpenAI
és a StrOutputParser
olyan sorozat létrehozásához, amely először egy összefoglalót, majd egy áttekintést generál. A kódrészlet a következő:
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"})
Ha szükségünk van a szinopszisra és az áttekintésre is, használhatjuk RunnablePassthrough
hogy mindegyikhez külön láncot hozzon létre, majd egyesítse őket:
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"})
Az összetettebb sorozatokat tartalmazó forgatókönyvek esetében a SequentialChain
módszer lép működésbe. Ez több bemenetet és kimenetet tesz lehetővé. Vegyünk egy olyan esetet, amikor szükségünk van egy szinopszisra egy darab címe és korszaka alapján. Így állíthatjuk be:
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"})
Olyan helyzetekben, amikor a kontextust szeretné fenntartani a lánc egészében vagy a lánc későbbi részében, SimpleMemory
használható. Ez különösen hasznos összetett bemeneti/kimeneti kapcsolatok kezelésére. Például egy olyan forgatókönyvben, amikor közösségi médiában szeretnénk bejegyzéseket generálni egy darab címe, korszaka, szinopszisa és ismertetője alapján, SimpleMemory
segíthet a következő változók kezelésében:
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"})
A szekvenciális láncokon kívül léteznek speciális láncok a dokumentumokkal való munkavégzéshez. Ezen láncok mindegyike más-más célt szolgál, a dokumentumok kombinálásától az iteratív dokumentumelemzésen alapuló válaszok finomításáig, a dokumentumok tartalmának feltérképezéséig és csökkentéséig az összegzés vagy a pontozott válaszok alapján történő átsorolás céljából. Ezek a láncok újra létrehozhatók az LCEL-lel a további rugalmasság és testreszabás érdekében.
-
StuffDocumentsChain
egyesíti a dokumentumok listáját egyetlen promptban, amelyet egy LLM-nek továbbítanak. -
RefineDocumentsChain
iteratívan frissíti a választ minden dokumentumhoz, olyan feladatokhoz, ahol a dokumentumok meghaladják a modell környezeti kapacitását. -
MapReduceDocumentsChain
egy láncot alkalmaz minden egyes dokumentumra, majd egyesíti az eredményeket. -
MapRerankDocumentsChain
pontoz minden dokumentum alapú választ, és kiválasztja a legmagasabb pontszámot.
Íme egy példa arra, hogyan állíthatja be a MapReduceDocumentsChain
LCEL használatával:
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")
Ez a konfiguráció lehetővé teszi a dokumentumtartalom részletes és átfogó elemzését, kihasználva az LCEL és az alapul szolgáló nyelvi modell erősségeit.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
V. modul: Memória
A LangChainben a memória a társalgási interfészek alapvető eleme, lehetővé téve a rendszereknek, hogy hivatkozzanak múltbeli interakciókra. Ez az információk tárolásával és lekérdezésével érhető el, két fő művelettel: olvasás és írás. A memóriarendszer kétszer lép kölcsönhatásba egy lánccal egy futás során, kiegészítve a felhasználói bemeneteket, és eltárolja a bemeneteket és kimeneteket későbbi felhasználás céljából.
Memória beépítése rendszerbe
- Chat üzenetek tárolása: A LangChain memóriamodul különféle módszereket integrál a chat-üzenetek tárolására, a memórián belüli listáktól az adatbázisokig. Ez biztosítja, hogy minden csevegési interakció rögzítésre kerüljön későbbi hivatkozás céljából.
- Chat üzenetek lekérdezése: A csevegési üzenetek tárolásán túl a LangChain adatstruktúrákat és algoritmusokat is alkalmaz, hogy hasznos képet adjon ezekről az üzenetekről. Az egyszerű memóriarendszerek visszaadhatják a legutóbbi üzeneteket, míg a fejlettebb rendszerek összefoglalhatják a múltbeli interakciókat, vagy az aktuális interakcióban említett entitásokra összpontosíthatnak.
A LangChain memóriahasználatának bemutatásához vegye figyelembe a ConversationBufferMemory
osztály, egy egyszerű memóriaűrlap, amely a chat üzeneteket egy pufferben tárolja. Íme egy példa:
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?")
Amikor a memóriát egy láncba integrálja, döntő fontosságú, hogy megértsük a memóriából visszaadott változókat, és hogyan használják őket a láncban. Például a load_memory_variables
A módszer segít a memóriából kiolvasott változóknak a lánc elvárásaihoz igazításában.
Végponttól végpontig példa a LangChain segítségével
Fontolja meg a ConversationBufferMemory
egy LLMChain
. A lánc a megfelelő prompt sablonnal és a memóriával kombinálva zökkenőmentes beszélgetési élményt biztosít. Íme egy egyszerűsített példa:
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?"})
Ez a példa azt szemlélteti, hogy a LangChain memóriarendszere hogyan integrálódik láncaival, hogy koherens és kontextuálisan tudatos társalgási élményt nyújtson.
Memóriatípusok a Langchainben
A Langchain különféle memóriatípusokat kínál, amelyek felhasználhatók az AI modellekkel való interakció javítására. Minden memóriatípusnak megvannak a saját paraméterei és visszatérési típusai, így különböző forgatókönyvekhez alkalmasak. Vizsgáljuk meg a Langchainben elérhető memóriatípusokat a kódpéldákkal együtt.
1. Beszélgetési puffermemória
Ez a memóriatípus lehetővé teszi az üzenetek tárolását és kibontását a beszélgetésekből. Az előzményeket karakterláncként vagy üzenetlistaként bonthatja ki.
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={})]}
A beszélgetési puffermemóriát láncban is használhatja csevegésszerű interakciókhoz.
2. Beszélgetési puffer ablakmemória
Ez a memóriatípus listát vezet a legutóbbi interakciókról, és az utolsó K interakciót használja, megakadályozva, hogy a puffer túl nagy legyen.
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'}
A beszélgetési puffermemóriához hasonlóan ezt a memóriatípust is használhatja láncban csevegésszerű interakciókhoz.
3. Beszélgetési entitás memóriája
Ez a memóriatípus megjegyzi a beszélgetések konkrét entitásaira vonatkozó tényeket, és LLM segítségével kinyeri az információkat.
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. Beszélgetési tudásgráf memória
Ez a memóriatípus tudásgráfot használ a memória újbóli létrehozásához. Az üzenetekből kinyerheti az aktuális entitásokat és tudáshármasokat.
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.'}
Ezt a memóriatípust láncban is használhatja beszélgetés alapú tudás-visszakereséshez.
5. Beszélgetés összefoglaló memóriája
Ez a memóriatípus összefoglalja a beszélgetést az idő múlásával, ami hasznos a hosszabb beszélgetésekből származó információk sűrítéséhez.
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. Beszélgetés összegzése Puffer memória
Ez a memóriatípus egyesíti a beszélgetés összegzését és a puffert, fenntartva az egyensúlyt a legutóbbi interakciók és az összegzés között. A token hosszát használja annak meghatározására, hogy mikor kell kiüríteni az interakciókat.
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'}
Ezeket a memóriatípusokat használhatja a Langchain AI modelljeivel való interakció javítására. Mindegyik memóriatípus meghatározott célt szolgál, és az Ön igényei szerint választható ki.
7. Beszélgetési token puffermemória
A ConversationTokenBufferMemory egy másik memóriatípus, amely a legutóbbi interakciók pufferét tárolja a memóriában. A korábbi memóriatípusokkal ellentétben, amelyek az interakciók számára összpontosítanak, ez a token hosszát használja annak meghatározására, hogy mikor kell kiüríteni az interakciókat.
Memória használata LLM-mel:
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'}
Ebben a példában a memória úgy van beállítva, hogy az interakciókat a jogkivonat hossza, nem pedig az interakciók száma alapján korlátozza.
Ennek a memóriatípusnak a használatakor az előzményeket üzenetlistaként is lekérheti.
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"})
Használat láncban:
A ConversationTokenBufferMemory láncban használható az AI-modellel való interakció javítására.
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?")
Ebben a példában a ConversationTokenBufferMemory a ConversationChainben használatos a beszélgetés kezelésére és az interakciók korlátozására a token hossza alapján.
8. VectorStoreRetrieverMemory
A VectorStoreRetrieverMemory egy vektortárban tárolja az emlékeket, és minden meghívásakor lekérdezi a K-k közül a legkiemelkedőbb dokumentumot. Ez a memóriatípus nem követi kifejezetten az interakciók sorrendjét, hanem vektoros visszakeresést használ a releváns emlékek lekéréséhez.
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"])
Ebben a példában a VectorStoreRetrieverMemory a vektoros visszakeresésen alapuló beszélgetésből származó releváns információk tárolására és lekérésére szolgál.
A VectorStoreRetrieverMemory-t láncban is használhatja beszélgetés alapú tudás-visszakereséshez, amint az az előző példákban látható.
A Langchain különböző memóriatípusai különféle módokat kínálnak a beszélgetésekből származó információk kezelésére és lekérésére, javítva az AI-modellek képességeit a felhasználói lekérdezések és kontextus megértésében és megválaszolásában. Mindegyik memóriatípus kiválasztható az alkalmazás speciális követelményei alapján.
Most megtanuljuk, hogyan kell használni a memóriát egy LLMChainnel. Az LLMC-láncban lévő memória lehetővé teszi a modell számára, hogy emlékezzen a korábbi interakciókra és kontextusra, hogy koherensebb és kontextustudatosabb válaszokat adjon.
A memória beállításához egy LLMChainben létre kell hoznia egy memóriaosztályt, például a ConversationBufferMemory-t. A következőképpen állíthatja be:
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")
Ebben a példában a ConversationBufferMemory a beszélgetési előzmények tárolására szolgál. A memory_key
paraméter adja meg a beszélgetési előzmények tárolására használt kulcsot.
Ha csevegési modellt használ a befejezés stílusú modell helyett, a memória jobb kihasználása érdekében másképp strukturálhatja az üzeneteket. Íme egy példa a csevegési modell alapú, memóriával rendelkező LLMChain beállítására:
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")
Ebben a példában a ChatPromptTemplate a prompt strukturálására szolgál, a ConversationBufferMemory pedig a beszélgetési előzmények tárolására és lekérésére. Ez a megközelítés különösen hasznos a chat-jellegű beszélgetéseknél, ahol a kontextus és a történelem döntő szerepet játszik.
A memória több bemenettel rendelkező lánchoz is hozzáadható, például kérdés/válasz lánchoz. Íme egy példa a memória beállítására egy kérdés/válasz láncban:
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)
Ebben a példában egy kérdésre egy kisebb részekre bontott dokumentum segítségével válaszolunk. A ConversationBufferMemory a beszélgetési előzmények tárolására és lekérésére szolgál, lehetővé téve a modell számára, hogy környezettudatos válaszokat adjon.
A memória hozzáadása az ügynökhöz lehetővé teszi, hogy emlékezzen és felhasználja a korábbi interakciókat kérdések megválaszolására és környezettudatos válaszok biztosítására. A következőképpen állíthat be memóriát egy ügynökben:
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)
Ebben a példában a memória hozzáadásra kerül egy ügynökhöz, lehetővé téve számára, hogy emlékezzen az előző beszélgetési előzményekre, és környezettudatos válaszokat adjon. Ez lehetővé teszi az ügynök számára, hogy a memóriában tárolt információk alapján pontosan megválaszolja a további kérdéseket.
LangChain kifejezési nyelv
A természetes nyelvi feldolgozás és a gépi tanulás világában a bonyolult műveleti láncok összeállítása ijesztő feladat lehet. Szerencsére a LangChain Expression Language (LCEL) segít, amely deklaratív és hatékony módot biztosít a kifinomult nyelvi feldolgozó folyamatok létrehozására és telepítésére. Az LCEL-t úgy tervezték, hogy leegyszerűsítse a láncok összeállításának folyamatát, lehetővé téve a prototípus-készítéstől a gyártásig való könnyű eljutást. Ebben a blogban megvizsgáljuk, mi az LCEL, és miért érdemes használni, valamint gyakorlati kódpéldákkal illusztráljuk a képességeit.
Az LCEL vagy LangChain Expression Language egy hatékony eszköz a nyelvi feldolgozási láncok összeállításához. Arra tervezték, hogy zökkenőmentesen támogassa a prototípus-készítésről a gyártásra való átmenetet anélkül, hogy kiterjedt kódmódosításra lenne szükség. Akár egyszerű „prompt + LLM” láncot épít, akár több száz lépésből álló összetett folyamatot, az LCEL mindent megtesz.
Íme néhány ok, amiért érdemes az LCEL-t nyelvfeldolgozási projektjeiben használni:
- Gyors Token Streaming: Az LCEL valós időben szállít tokeneket a nyelvi modellből a kimeneti elemzőbe, javítva a válaszkészséget és a hatékonyságot.
- Sokoldalú API-k: Az LCEL mind a szinkron, mind az aszinkron API-kat támogatja prototípus-készítéshez és termelési felhasználáshoz, így több kérést is hatékonyan kezel.
- Automatikus párhuzamosítás: Az LCEL lehetőség szerint optimalizálja a párhuzamos végrehajtást, csökkentve a késleltetést mind a szinkron, mind az aszinkron interfészeken.
- Megbízható konfigurációk: Konfigurálja az újrapróbálkozásokat és a tartalékokat a nagyobb láncmegbízhatóság érdekében a fejlesztés során a streaming támogatással.
- Köztes eredmények streamelése: Hozzáférés a közbenső eredményekhez a feldolgozás során felhasználói frissítések vagy hibakeresés céljából.
- Sémagenerálás: Az LCEL Pydantic és JSONSchema sémákat állít elő a bemeneti és kimeneti ellenőrzéshez.
- Átfogó nyomkövetés: A LangSmith automatikusan nyomon követi az összes lépést összetett láncokban a megfigyelhetőség és a hibakeresés érdekében.
- Egyszerű telepítés: Az LCEL által létrehozott láncokat könnyedén telepítheti a LangServe segítségével.
Most pedig vessünk egy pillantást gyakorlati kódpéldákra, amelyek bemutatják az LCEL erejét. Megvizsgáljuk azokat a gyakori feladatokat és forgatókönyveket, amelyekben az LCEL világít.
Prompt + LLM
A legalapvetőbb összetétel egy prompt és egy nyelvi modell kombinálásával hoz létre egy láncot, amely fogadja a felhasználói bevitelt, hozzáadja azt egy prompthoz, átadja egy modellnek, és visszaadja a nyers modell kimenetét. Íme egy példa:
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)
Ebben a példában a lánc viccet generál a medvékről.
Leállítási sorozatokat csatolhat a lánchoz, hogy szabályozza, hogyan dolgozza fel a szöveget. Például:
chain = prompt | model.bind(stop=["n"])
result = chain.invoke({"foo": "bears"})
print(result)
Ez a konfiguráció leállítja a szöveggenerálást, ha újsor karaktert talál.
Az LCEL támogatja a függvényhívási információk csatolását a lánchoz. Íme egy példa:
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)
Ez a példa függvényhívási információkat csatol a vicc generálásához.
Prompt + LLM + OutputParser
Hozzáadhat egy kimeneti elemzőt, hogy a nyers modell kimenetét egy működőbb formátumba alakítsa át. A következőképpen teheti meg:
from langchain.schema.output_parser import StrOutputParser chain = prompt | model | StrOutputParser()
result = chain.invoke({"foo": "bears"})
print(result)
A kimenet most karakterlánc formátumú, ami kényelmesebb a későbbi feladatokhoz.
Amikor megad egy visszaadandó függvényt, közvetlenül elemezheti az LCEL használatával. Például:
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)
Ez a példa közvetlenül elemzi a „joke” függvény kimenetét.
Ez csak néhány példa arra, hogy az LCEL hogyan egyszerűsíti le az összetett nyelvi feldolgozási feladatokat. Akár chatbotokat épít, akár tartalmat generál, akár összetett szövegátalakításokat hajt végre, az LCEL leegyszerűsítheti a munkafolyamatot, és karbantarthatóbbá teheti a kódot.
RAG (Retrieval-augmented Generation)
Az LCEL segítségével lekéréssel kiegészített generációs láncok hozhatók létre, amelyek a visszakeresési és a nyelvgenerálási lépéseket kombinálják. Íme egy példa:
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)
Ebben a példában a lánc releváns információkat kér le a kontextusból, és választ generál a kérdésre.
Beszélgetési visszakeresési lánc
Könnyedén hozzáadhatja a beszélgetési előzményeket a láncokhoz. Íme egy példa a párbeszédes visszakeresési láncra:
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)
Ebben a példában a lánc egy utólagos kérdést kezel beszélgetési kontextusban.
Memóriával és visszatérő forrásdokumentumokkal
Az LCEL támogatja a memóriát és a forrásdokumentumok visszaküldését is. Így használhatja a memóriát egy láncban:
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)
Ebben a példában a memória a beszélgetési előzmények és a forrásdokumentumok tárolására és lekérésére szolgál.
Több lánc
A Runnables segítségével több láncot is összefűzhet. Íme egy példa:
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)
Ebben a példában két láncot kombinálunk, hogy egy városról és országáról információkat hozzon létre egy megadott nyelven.
Elágazás és összevonás
Az LCEL lehetővé teszi a láncok felosztását és egyesítését a RunnableMaps segítségével. Íme egy példa az elágazásra és egyesítésre:
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)
Ebben a példában egy elágazó és összevonó láncot használunk érv generálására, és annak előnyeinek és hátrányainak értékelésére a végső válasz generálása előtt.
Python kód írása LCEL-lel
A LangChain Expression Language (LCEL) egyik hatékony alkalmazása Python-kód írása a felhasználói problémák megoldására. Az alábbiakban egy példa látható arra, hogyan kell LCEL-t használni Python-kód írására:
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)
Ebben a példában a felhasználó megadja a bevitelt, az LCEL pedig Python-kódot állít elő a probléma megoldására. A kód ezután Python REPL használatával fut le, és az eredményül kapott Python-kód Markdown formátumban kerül visszaadásra.
Kérjük, vegye figyelembe, hogy a Python REPL használata tetszőleges kódot hajthat végre, ezért óvatosan használja.
Memória hozzáadása a lánchoz
A memória elengedhetetlen számos társalgási AI alkalmazásban. A következőképpen adhat hozzá memóriát egy tetszőleges lánchoz:
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({})
Ebben a példában a memória a beszélgetési előzmények tárolására és lekérésére szolgál, lehetővé téve a chatbot számára, hogy fenntartsa a kontextust és megfelelően reagáljon.
Külső eszközök használata futtatható fájlokkal
Az LCEL lehetővé teszi a külső eszközök és a Runnables zökkenőmentes integrálását. Íme egy példa a DuckDuckGo keresőeszköz használatára:
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)
Ebben a példában az LCEL integrálja a DuckDuckGo Search eszközt a láncba, lehetővé téve számára, hogy keresési lekérdezést generáljon a felhasználói bevitelből, és lekérje a keresési eredményeket.
Az LCEL rugalmassága megkönnyíti a különféle külső eszközök és szolgáltatások beépítését a nyelvi feldolgozási folyamatokba, javítva azok képességeit és funkcionalitását.
Moderálás hozzáadása LLM-alkalmazáshoz
Annak biztosítására, hogy LLM-alkalmazása megfeleljen a tartalomszabályzatnak, és moderálási biztosítékokat tartalmazzon, a moderálási ellenőrzéseket integrálhatja a láncba. A következőképpen adhat hozzá moderálást a LangChain használatával:
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)
Ebben a példában a OpenAIModerationChain
Az LLM által generált válasz moderálására szolgál. A moderációs lánc ellenőrzi a választ az OpenAI tartalomszabályzatát sértő tartalom után. Ha bármilyen szabálysértést talál, ennek megfelelően jelzi a választ.
Útválasztás szemantikai hasonlóság alapján
Az LCEL lehetővé teszi az egyéni útválasztási logika megvalósítását a felhasználói bevitel szemantikai hasonlósága alapján. Íme egy példa arra, hogyan lehet dinamikusan meghatározni a lánc logikáját a felhasználói bevitel alapján:
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"}))
Ebben a példában a prompt_router
A függvény kiszámítja a koszinusz hasonlóságot a felhasználói bevitel és a fizikai és matematikai kérdések előre meghatározott prompt sablonjai között. A hasonlósági pontszám alapján a lánc dinamikusan kiválasztja a legrelevánsabb prompt sablont, biztosítva, hogy a chatbot megfelelően válaszoljon a felhasználó kérdésére.
Ügynökök és futtatható programok használata
A LangChain lehetővé teszi ügynökök létrehozását futtatható elemek, promptok, modellek és eszközök kombinálásával. Íme egy példa egy ügynök létrehozására és használatára:
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)
Ebben a példában egy ügynök egy modell, eszközök, prompt és egyéni logika kombinálásával jön létre a közbenső lépésekhez és az eszközátalakításhoz. Az ügynök ezután végrehajtódik, és választ ad a felhasználó lekérdezésére.
SQL-adatbázis lekérdezése
A LangChain segítségével lekérdezhet SQL-adatbázist, és felhasználói kérdések alapján SQL-lekérdezéseket generálhat. Íme egy példa:
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)
Ebben a példában a LangChain segítségével SQL-lekérdezéseket generálnak felhasználói kérdések alapján, és válaszokat kérnek le egy SQL-adatbázisból. A promptok és válaszok úgy vannak formázva, hogy természetes nyelvi interakciókat biztosítsanak az adatbázissal.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
LangServe és LangSmith
A LangServe segít a fejlesztőknek a LangChain futtatható fájlok és láncok REST API-ként történő üzembe helyezésében. Ez a könyvtár integrálva van a FastAPI-val, és pydantic-ot használ az adatok ellenőrzéséhez. Ezenkívül egy klienst is biztosít, amellyel a kiszolgálón telepített futtatható fájlokat lehet meghívni, és egy JavaScript-ügyfél is elérhető a LangChainJS-ben.
Jellemzők
- A bemeneti és kimeneti sémák automatikusan következtetnek a LangChain objektumból, és minden API-hívásnál érvényesülnek, gazdag hibaüzenetekkel.
- Elérhető egy API-dokumentumoldal a JSONSchemával és a Swaggerrel.
- Hatékony /invoke, /batch és /stream végpontok számos párhuzamos kérés támogatásával egyetlen kiszolgálón.
- /stream_log végpont az összes (vagy néhány) közbenső lépés streameléséhez a láncból/ügynökből.
- Játszótér oldal a /playground címen streaming kimenettel és közbenső lépésekkel.
- Beépített (opcionális) nyomkövetés a LangSmith-hez; csak adja hozzá az API-kulcsot (lásd az utasításokat).
- Mindegyik harcban tesztelt nyílt forráskódú Python könyvtárakkal készült, mint például a FastAPI, Pydantic, uvloop és asyncio.
korlátozások
- Az ügyfél-visszahívások még nem támogatottak a szerverről származó események esetében.
- A Pydantic V2 használatakor nem jön létre OpenAPI-dokumentum. A FastAPI nem támogatja a pydantic v1 és v2 névterek keverését. További részletekért lásd az alábbi részt.
Használja a LangChain CLI-t a LangServe projekt gyors indításához. A langchain CLI használatához győződjön meg arról, hogy a langchain-cli legújabb verziója telepítve van. A pip install -U langchain-cli paranccsal telepítheti.
langchain app new ../path/to/directory
Gyorsan elindíthatja LangServe példányát a LangChain Templates segítségével. További példákért tekintse meg a sablonok indexét vagy a példák könyvtárát.
Itt van egy szerver, amely OpenAI chat-modellt, Anthropic chat-modellt és egy láncot alkalmaz, amely az Anthropic modellt használja egy témával kapcsolatos vicc elmesélésére.
#!/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)
Miután telepítette a fenti szervert, megtekintheti a generált OpenAPI-dokumentumokat a következő módon:
curl localhost:8000/docs
Ügyeljen arra, hogy hozzáadja a /docs utótagot.
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" }])
TypeScriptben (a LangChain.js 0.0.166-os vagy újabb verziója szükséges):
import { RemoteRunnable } from "langchain/runnables/remote"; const chain = new RemoteRunnable({ url: `http://localhost:8000/chain/invoke/`,
});
const result = await chain.invoke({ topic: "cats",
});
Python kéréseket használ:
import requests
response = requests.post( "http://localhost:8000/chain/invoke/", json={'input': {'topic': 'cats'}}
)
response.json()
Használhatja a göndörítést is:
curl --location --request POST 'http://localhost:8000/chain/invoke/' --header 'Content-Type: application/json' --data-raw '{ "input": { "topic": "cats" } }'
A következő kód:
...
add_routes( app, runnable, path="/my_runnable",
)
ezeket a végpontokat hozzáadja a szerverhez:
- POST /my_runnable/invoke – a futtatható fájl meghívása egyetlen bemeneten
- POST /my_runnable/batch – a futtatható kód meghívása egy köteg bemeneten
- POST /my_runnable/stream – egyetlen bemeneten történő meghívás és a kimenet streamelése
- POST /my_runnable/stream_log – egyetlen bemeneten hívja meg, és streameli a kimenetet, beleértve a közbenső lépések kimenetét is generáláskor
- GET /my_runnable/input_schema – json séma a futtatható fájl beviteléhez
- GET /my_runnable/output_schema – json séma a futtatható kimenethez
- GET /my_runnable/config_schema – json séma a futtatható fájl konfigurációjához
A /my_runnable/playground címen találsz egy játszóteret a futtathatóhoz. Ez egy egyszerű felhasználói felületet tesz elérhetővé a futtatható fájl konfigurálásához és meghívásához streaming kimenettel és közbenső lépésekkel.
Mind kliens, mind szerver esetén:
pip install "langserve[all]"
vagy pip install „langserve[kliens]” a klienskódhoz, és pip install „langserve[server]” szerverkódhoz.
Ha hitelesítést kell hozzáadnia a kiszolgálóhoz, kérjük, tekintse meg a FastAPI biztonsági dokumentációját és a köztes szoftver dokumentációját.
A következő paranccsal telepítheti a GCP Cloud Run szolgáltatást:
gcloud run deploy [your-service-name] --source . --port 8001 --allow-unauthenticated --region us-central1 --set-env-vars=OPENAI_API_KEY=your_key
A LangServe bizonyos korlátozásokkal támogatja a Pydantic 2-t. Az OpenAPI-dokumentumok nem jönnek létre az invoke/batch/stream/stream_log fájlhoz Pydantic V2 használata esetén. A Fast API nem támogatja a pydantic v1 és v2 névterek keverését. A LangChain a v1 névteret használja a Pydantic v2-ben. Kérjük, olvassa el az alábbi irányelveket a LangChain-nel való kompatibilitás biztosítása érdekében. E korlátozások kivételével azt várjuk, hogy az API-végpontok, a játszótér és minden más szolgáltatás a várt módon működjön.
Az LLM alkalmazások gyakran foglalkoznak fájlokkal. Különféle architektúrák készíthetők a fájlfeldolgozás megvalósítására; magas szinten:
- A fájl feltölthető a szerverre egy dedikált végponton keresztül, és egy külön végponton keresztül feldolgozható.
- A fájl feltölthető érték (fájl bájt) vagy hivatkozás (pl. s3 url a fájltartalomhoz) alapján.
- A feldolgozási végpont lehet blokkoló vagy nem blokkoló.
- Ha jelentős feldolgozásra van szükség, a feldolgozást át lehet tölteni egy dedikált folyamatkészletbe.
Meg kell határoznia, hogy mi a megfelelő architektúra az alkalmazáshoz. Jelenleg a fájlok érték szerinti feltöltéséhez használjon base64-es kódolást a fájlhoz (a többrészes/form-adat még nem támogatott).
Itt van egy példa amely bemutatja, hogyan kell base64 kódolást használni a fájl távoli futtatására való küldéséhez. Ne feledje, hogy bármikor feltölthet fájlokat hivatkozással (pl. s3 url), vagy többrészes/form-adatként egy dedikált végpontra.
A bemeneti és kimeneti típusok minden futtatható fájlnál meg vannak határozva. Ezeket az input_schema és output_schema tulajdonságokon keresztül érheti el. A LangServe ezeket a típusokat használja az érvényesítéshez és a dokumentációhoz. Ha felül szeretné bírálni az alapértelmezett kikövetkeztetett típusokat, használhatja a with_types metódust.
Íme egy játékpélda az ötlet illusztrálására:
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)
Ha azt szeretné, hogy az adatok pydantikus modellben deserializálódjanak, nem pedig az ezzel egyenértékű diktált reprezentációval, örökölje meg a CustomUserType típust. Jelenleg ez a típus csak szerveroldalon működik, és a kívánt dekódolási viselkedés meghatározására szolgál. Ha ettől a típustól örököl, a szerver a dekódolt típust pydantikus modellként tartja meg, ahelyett, hogy diktátummá alakítaná.
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")
A játszótér lehetővé teszi, hogy egyéni widgeteket definiáljon a futtatható eszközhöz a háttérből. Egy widget mezőszinten van megadva, és a bemeneti típusú JSON-séma részeként kerül szállításra. A widgetnek tartalmaznia kell egy típus nevű kulcsot, amelynek értéke a widgetek jól ismert listájának egyike. Más eszközprimitív kulcsok olyan értékekhez lesznek társítva, amelyek leírják a JSON-objektumban lévő útvonalakat.
Általános séma:
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;
};
Lehetővé teszi fájlfeltöltési bemenet létrehozását a felhasználói felületen a base64 kódolású karakterláncként feltöltött fájlokhoz. Íme a teljes példa.
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
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
LangSmith bemutatása
A LangChain megkönnyíti az LLM alkalmazások és ügynökök prototípusát. Az LLM-alkalmazások termelésbe való eljuttatása azonban megtévesztően nehéz lehet. Valószínűleg erősen testre kell szabnia és ismételnie kell az utasításokat, láncokat és egyéb összetevőket, hogy kiváló minőségű terméket hozzon létre.
A folyamat elősegítése érdekében bevezették a LangSmith-et, egy egységes platformot az LLM-alkalmazások hibakereséséhez, teszteléséhez és figyeléséhez.
Mikor jöhet ez jól? Hasznos lehet, ha gyorsan szeretne hibakeresni egy új láncot, ügynököt vagy eszközkészletet, megjeleníteni az összetevők (láncok, llms-ek, retrieverek stb.) kapcsolatát és felhasználását, kiértékelni a különböző promptokat és LLM-eket egyetlen komponenshez, Futtasson le egy adott láncot többször egy adathalmazon, hogy az folyamatosan megfeleljen a minőségi sávnak, vagy rögzítse a használati nyomokat, és használjon LLM-eket vagy elemzési folyamatokat a betekintések generálására.
Előfeltételek:
- Hozzon létre egy LangSmith-fiókot, és hozzon létre egy API-kulcsot (lásd a bal alsó sarkot).
- Ismerkedjen meg a platformmal a dokumentumok áttekintésével.
Most kezdjük!
Először állítsa be a környezeti változókat úgy, hogy a LangChain naplózza a nyomkövetéseket. Ez úgy történik, hogy a LANGCHAIN_TRACING_V2 környezeti változót igaz értékre állítja. A LANGCHAIN_PROJECT környezeti változó beállításával megadhatja a LangChainnek, hogy melyik projektbe jelentkezzen be (ha ez nincs beállítva, a futások az alapértelmezett projekthez lesznek naplózva). Ez automatikusan létrehozza a projektet, ha nem létezik. Ezenkívül be kell állítania a LANGCHAIN_ENDPOINT és a LANGCHAIN_API_KEY környezeti változókat.
MEGJEGYZÉS: A pythonban kontextuskezelőt is használhat a nyomkövetések naplózására a következő használatával:
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?")
Ebben a példában azonban környezeti változókat fogunk használni.
%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>"
Az API-val való interakcióhoz hozza létre a LangSmith klienst:
from langsmith import Client client = Client()
Hozzon létre egy LangChain összetevőt, és a napló fut a platformon. Ebben a példában egy ReAct-stílusú ügynököt fogunk létrehozni, amely hozzáfér egy általános keresőeszközhöz (DuckDuckGo). Az ügynök felszólítása itt tekinthető meg a Hubban:
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
)
Az ügynököt egyidejűleg több bemeneten futtatjuk a késleltetés csökkentése érdekében. A futtatások a háttérben naplózódnak a LangSmith-be, így a végrehajtási késleltetés nem változik:
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]
Feltéve, hogy sikeresen beállította a környezetet, az ügynöknyomoknak meg kell jelenniük az alkalmazás Projektek szakaszában. Gratula!
Úgy tűnik azonban, hogy az ügynök nem használja hatékonyan az eszközöket. Értékeljük ezt, hogy legyen egy alapállapotunk.
A naplózási futtatások mellett a LangSmith lehetővé teszi az LLM-alkalmazások tesztelését és értékelését is.
Ebben a részben a LangSmith segítségével hozzon létre egy benchmark adatkészletet, és futtasson mesterséges intelligencia által támogatott kiértékelőket egy ügynökön. Ezt néhány lépésben megteheti:
- Hozzon létre egy LangSmith adatkészletet:
Az alábbiakban a LangSmith kliens segítségével adatkészletet hozunk létre a fenti bemeneti kérdésekből és egy listacímkékből. Ezeket később egy új ügynök teljesítményének mérésére fogja használni. Az adatkészlet példák gyűjteménye, amelyek nem mások, mint bemenet-kimenet párok, amelyeket tesztesetekként használhat az alkalmazáshoz:
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 )
- Új ügynök inicializálása az összehasonlításhoz:
A LangSmith lehetővé teszi bármely LLM, lánc, ügynök vagy akár egyéni függvény értékelését. A beszélgető ágensek állapottartók (memóriájuk van); annak biztosítására, hogy ez az állapot ne legyen megosztva az adatkészlet-futtatások között, a chain_factory (
más néven konstruktor) függvény az egyes hívások inicializálásához:
# 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)
- Kiértékelés konfigurálása:
A láncok eredményeinek manuális összehasonlítása a felhasználói felületen hatékony, de időigényes lehet. Hasznos lehet automatizált mutatók és mesterséges intelligencia által támogatott visszajelzések használata az összetevő teljesítményének értékeléséhez:
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=[],
)
- Futtassa az ügynököt és az értékelőket:
Használja a run_on_dataset (vagy aszinkron arun_on_dataset) függvényt a modell kiértékeléséhez. Ez:
- Példasorok lekérése a megadott adatkészletből.
- Futtassa az ügynököt (vagy bármely egyéni függvényt) minden egyes példán.
- Alkalmazzon kiértékelőket az eredményül kapott futási nyomokra és a megfelelő referenciapéldákra az automatikus visszacsatolás generálásához.
Az eredmények a LangSmith alkalmazásban lesznek láthatók:
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", ],
)
Most, hogy megvannak a tesztfutás eredményei, módosíthatjuk ügynökünket, és összehasonlíthatjuk őket. Próbáljuk meg újra egy másik prompttal, és nézzük meg az eredményeket:
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", ],
)
A LangSmith lehetővé teszi az adatok exportálását általános formátumokba, például CSV- vagy JSONL-formátumba közvetlenül a webalkalmazásban. A klienst arra is használhatja, hogy lekérje a futtatásokat további elemzéshez, saját adatbázisban való tároláshoz vagy másokkal való megosztáshoz. Nézzük le a futási nyomokat az értékelő futásból:
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
Ez egy gyors útmutató volt az induláshoz, de a LangSmith használatával sokkal több módja van a fejlesztői folyamat felgyorsítására és jobb eredmények elérésére.
Ha többet szeretne tudni arról, hogyan hozhatja ki a legtöbbet a LangSmith-ből, tekintse meg a LangSmith dokumentációját.
Lépjen magasabb szintre a Nanonetekkel
Noha a LangChain értékes eszköz a nyelvi modellek (LLM) alkalmazásaival való integrálásához, a vállalati felhasználási esetek tekintetében korlátokba ütközhet. Vizsgáljuk meg, hogy a Nanonets miként lépi túl a LangChain-t az alábbi kihívások kezelésében:
1. Átfogó adatkapcsolat:
A LangChain kínál csatlakozókat, de előfordulhat, hogy nem fedi le az összes olyan munkaterület-alkalmazást és adatformátumot, amelyre a vállalkozások támaszkodnak. A Nanonets adatcsatlakozókat biztosít több mint 100 széles körben használt munkaterület-alkalmazáshoz, beleértve a Slack, Notion, Google Suite, Salesforce, Zendesk és sok más alkalmazást. Támogat továbbá minden strukturálatlan adattípust, például PDF-eket, TXT-ket, képeket, hangfájlokat és videofájlokat, valamint olyan strukturált adattípusokat, mint a CSV-k, táblázatok, MongoDB és SQL-adatbázisok.
2. Feladatautomatizálás munkaterület-alkalmazásokhoz:
Míg a szöveg/válasz generálása remekül működik, a LangChain képességei korlátozottak, ha természetes nyelvet kell használni különféle alkalmazásokban. A Nanonets trigger/action ügynököket kínál a legnépszerűbb munkaterület-alkalmazásokhoz, lehetővé téve olyan munkafolyamatok beállítását, amelyek figyelik az eseményeket és műveleteket hajtanak végre. Például automatizálhatja az e-mail válaszokat, a CRM-bejegyzéseket, az SQL-lekérdezéseket és még sok mást, mindezt természetes nyelvi parancsokkal.
3. Valós idejű adatszinkronizálás:
A LangChain adatösszekötőkkel tölti le a statikus adatokat, amelyek esetleg nem követik a forrásadatbázis adatváltozásait. Ezzel szemben a Nanonets valós idejű szinkronizálást biztosít az adatforrásokkal, így mindig a legfrissebb információkkal dolgozik.
3. Egyszerűsített konfiguráció:
A LangChain folyamat elemeinek, például a retrieverek és szintetizátorok konfigurálása összetett és időigényes folyamat lehet. A Nanonets ezt egyszerűsíti azáltal, hogy optimalizált adatfeldolgozást és indexelést biztosít minden adattípushoz, és mindezt a háttérben az AI-asszisztens kezeli. Ez csökkenti a finomhangolás terhét, és megkönnyíti a beállítást és a használatot.
4. Egységes megoldás:
A LangChain-nel ellentétben, amely minden egyes feladathoz egyedi megvalósítást igényelhet, a Nanonets egyablakos megoldásként szolgál az adatok és az LLM-ekkel való összekapcsolására. Akár LLM-alkalmazásokat, akár mesterséges intelligencia munkafolyamatokat kell létrehoznia, a Nanonets egységes platformot kínál különféle igényeihez.
Nanonets AI munkafolyamatok
A Nanonets Workflows egy biztonságos, többcélú AI-asszisztens, amely leegyszerűsíti tudásának és adatainak integrálását az LLM-ekkel, és megkönnyíti a kód nélküli alkalmazások és munkafolyamatok létrehozását. Könnyen használható felhasználói felületet kínál, így magánszemélyek és szervezetek számára egyaránt elérhető.
A kezdéshez egyeztethet egy hívást az egyik AI-szakértőnkkel, aki személyre szabott bemutatót és próbaverziót biztosít a Nanonets munkafolyamatokról az Ön konkrét használati esetére szabva.
A beállítást követően természetes nyelven tervezhet és hajthat végre összetett alkalmazásokat és munkafolyamatokat, amelyeket LLM-ek hajtanak végre, és zökkenőmentesen integrálhatók az alkalmazásaival és adataival.
Töltsd fel csapataidat a Nanonets AI-val, hogy alkalmazásokat hozzanak létre, adatait pedig mesterséges intelligencia által vezérelt alkalmazásokkal és munkafolyamatokkal integrálhassák, így a csapatok arra összpontosíthatnak, ami igazán számít.
Automatizálja a kézi feladatokat és munkafolyamatokat mesterséges intelligencia által vezérelt munkafolyamat-készítőnkkel, amelyet a Nanonets tervezett Önnek és csapatainak.
- SEO által támogatott tartalom és PR terjesztés. Erősödjön még ma.
- PlatoData.Network Vertical Generative Ai. Erősítse meg magát. Hozzáférés itt.
- PlatoAiStream. Web3 Intelligence. Felerősített tudás. Hozzáférés itt.
- PlatoESG. Carbon, CleanTech, Energia, Környezet, Nap, Hulladékgazdálkodás. Hozzáférés itt.
- PlatoHealth. Biotechnológiai és klinikai vizsgálatok intelligencia. Hozzáférés itt.
- Forrás: https://nanonets.com/blog/langchain/
- :van
- :is
- :nem
- :ahol
- $ UP
- 1
- 10
- 100
- 114
- 13
- 15%
- 2000
- 2012
- 2023
- 25
- 30
- 32
- 36
- 40
- 400
- 408
- 50
- 500
- 7
- 8
- a
- ABC
- képesség
- Képes
- Rólunk
- erről
- felett
- Elfogad!
- elfogadja
- hozzáférés
- hozzáférhető
- Hozzáférés
- elérni
- Eszerint
- Fiók
- pontosság
- pontos
- pontosan
- Elérése
- elért
- ér
- át
- törvény
- Akció
- cselekvések
- aktív
- alkalmazkodás
- adaptív
- hozzá
- hozzáadott
- hozzáadásával
- mellett
- További
- Ezen kívül
- cím
- Hozzáteszi
- beismerni
- fejlett
- Kaland
- Után
- újra
- kor
- Ügynök
- szerek
- AI
- AI asszisztens
- AI modellek
- Támogatás
- Célzás
- algoritmusok
- összehangolása
- Igazítás
- Minden termék
- lehetővé
- lehetővé téve
- lehetővé teszi, hogy
- kizárólag
- mentén
- mellett
- már
- Is
- Bár
- mindig
- an
- elemzés
- Analitikai
- analitika
- és a
- Angeles
- bejelent
- évi
- Másik
- válasz
- válaszok
- himnusz
- Antropikus
- bármilyen
- bármi
- api
- API KULCSOK
- API-k
- app
- alkalmazható
- Alkalmazás
- Application Development
- alkalmazások
- alkalmazott
- alkalmazandó
- megközelítés
- megközelít
- megfelelő
- megfelelő
- alkalmazások
- építészet
- VANNAK
- érv
- érvek
- Armstrong
- körül
- Sor
- Előadók
- AS
- kérdez
- megjelenés
- szempontok
- segít
- Helyettes
- társult
- At
- csatolja
- figyelem
- hang-
- bővített
- Hitelesítés
- automatizált
- Automatizált
- automaták
- automatikusan
- Automatizálás
- elérhető
- átlagos
- várják
- tudatában van
- AWS
- vissza
- Hátgerinc
- háttér
- háttér
- rosszul
- Egyenleg
- bár
- bázis
- alapján
- kiindulási
- horpadás
- alapvető
- Alapjai
- BCG
- BE
- strand
- Medvék
- mert
- óta
- előtt
- kezdődik
- viselkedés
- mögött
- a színfalak mögött
- hogy
- lent
- benchmark
- előnyös
- BEST
- Jobb
- között
- Túl
- Legnagyobb
- Számla
- Bill Gates
- kötődik
- Bing
- Bit
- Fekete
- Black Hole
- Blokk
- blokkoló
- Blocks
- Blog
- gabona
- Bootstrap
- született
- Bot
- mindkét
- Alsó
- Ág
- szünet
- szellő
- tömören
- tágabb
- barna
- böngésző
- ütköző
- épít
- építész
- Épület
- épült
- teher
- vállalkozások
- de
- by
- számít
- kiszámítja
- kiszámítása
- számítás
- hívás
- visszahívások
- hívott
- hívás
- kéri
- TUD
- Kaphat
- Kanada
- képességek
- képes
- Kapacitás
- elfog
- Rögzítése
- eset
- esetek
- CAT
- ellát
- ellátás
- kiszolgál
- Macskák
- óvatosság
- óvatos
- központú
- bizonyos
- lánc
- láncok
- kihívások
- Változások
- karakter
- chatbot
- chatbots
- ellenőrizze
- Ellenőrzések
- A pop-art design, négy időzóna kijelzése egyszerre és méretének arányai azok az érvek, amelyek a NeXtime Time Zones-t kiváló választássá teszik. Válassza a
- választott
- körülmények
- Város
- osztály
- osztályok
- vásárló
- felhő
- kód
- Kódolás
- Kávé
- ÖSSZEFÜGGŐ
- kohéziós
- együttműködik
- Összeomlás
- gyűjtemény
- színes
- Oszlop
- Oszlopok
- COM
- össze
- kombinált
- kombájnok
- kombinálása
- hogyan
- jön
- kényelmes
- Közös
- közlés
- vállalat
- összehasonlítani
- összehasonlítva
- kompatibilitás
- összeegyeztethető
- teljes
- teljesen
- befejezés
- bonyolult
- bonyodalmak
- összetevő
- alkatrészek
- áll
- összetétel
- átfogó
- azzal jellemezve,
- koncepció
- tömör
- egyidejű
- feltétel
- Configuration
- összefolyás
- Csatlakozás
- Csatlakozó
- Connectivity
- Hátrányok
- Fontolja
- következetesen
- áll
- Konzol
- állandóan
- konstrukciókat
- tartalmaz
- tartalmaz
- tartalom
- kontextus
- kontextusok
- szövegre vonatkozó
- folytatódik
- folyamatosan
- kontraszt
- ellenőrzés
- ellenőrzések
- Kényelmes
- Beszélgetés
- társalgó
- társalgási AI
- beszélgetések
- Átalakítás
- átalakított
- konvertáló
- Mag
- Sarok
- kijavítására
- Megfelelő
- tudott
- számolás
- ország
- Pár
- terjed
- fedett
- teremt
- készítette
- teremt
- létrehozása
- teremtés
- Hitelesítő adatok
- kritériumok
- Kritikus
- CRM
- kritikus
- Jelenlegi
- Jelenleg
- szokás
- Ügyfelek
- testreszabás
- testre
- szabott
- élvonalbeli
- dátum
- Adatszerkezet
- adatbázis
- adatbázisok
- találka
- dátum idő
- üzlet
- foglalkozó
- december
- dönt
- Döntés
- Döntéshozatal
- Dekódolás
- elszánt
- mélyebb
- alapértelmezett
- meghatározott
- meghatározott
- meghatározó
- definíciók
- átadó
- szállít
- ás
- demó
- bizonyítani
- igazolták
- bemutatását,
- függ
- attól
- függ
- telepíteni
- telepített
- bevezetéséhez
- bevetés
- bevet
- leírni
- leírás
- Design
- kijelölt
- tervezett
- kívánatos
- részlet
- részletes
- részletek
- Határozzuk meg
- meghatározza
- Fejleszt
- Fejlesztő
- fejlesztők
- fejlesztése
- Fejlesztés
- diagramok
- DICT
- DID
- különbözik
- különböző
- eltérően
- nehéz
- Dimenzió
- méretek
- irányelvek
- közvetlenül
- megvitatni
- tárgyalt
- megjelenítő
- különböző
- merülés
- számos
- DM
- do
- dokumentum
- dokumentáció
- dokumentumok
- nem
- nem
- Ennek
- Don
- csinált
- kétszeresére
- le-
- letöltés
- letöltések
- vázlat
- hajtás
- két
- alatt
- dinamikus
- dinamikusan
- e
- minden
- Korábban
- Korai
- könnyű
- egyszerű használat
- könnyebb
- könnyen
- könnyű
- könnyen használható
- visszhang
- ökoszisztéma
- Hatékony
- hatékonyan
- hatékonyság
- hatékony
- eredményesen
- erőfeszítés nélkül
- bármelyik
- elem
- elemek
- Elon
- Elon Musk
- más
- Beágyaz
- beágyazott
- beágyazás
- munkavállaló
- alkalmazottak
- alkalmaz
- képessé
- lehetővé
- lehetővé teszi
- lehetővé téve
- bekapszulázza
- találkozás
- végtől végig
- Endpoint
- vonzó
- Motor
- Motorok
- Anglia
- Angol
- Angol Premier League
- növelése
- fokozott
- fokozása
- biztosítására
- biztosítja
- biztosítása
- Vállalkozás
- Szervezetek
- egység
- Környezet
- környezetek
- Egyenértékű
- Ez volt
- hiba
- hibák
- különösen
- alapvető
- elidegenedett
- stb.
- értékelni
- értékelés
- Még
- események
- Minden
- példa
- példák
- haladja meg
- Kivéve
- kivégez
- végrehajtott
- végrehajtja
- végrehajtó
- végrehajtás
- példázza
- Gyakorol
- létezik
- vár
- várakozások
- várható
- elvárja
- tapasztalat
- kísérleti
- szakértők
- magyarázható
- Elmagyarázza
- kifejezetten
- kutatás
- feltárása
- feltárt
- export
- kifejezés
- terjed
- kiterjedő
- kiterjedt
- külső
- külön-
- kivonat
- kitermelés
- kivonatok
- Arc
- megkönnyítése
- megkönnyíti
- gyár
- tények
- messze
- GYORS
- Kedvenc
- Funkció
- Jellemzők
- Visszacsatolás
- kevés
- mező
- Fields
- figma
- Ábra
- filé
- Fájlok
- kitöltése
- megtöltött
- töltő
- szűrő
- szűrő
- utolsó
- Végül
- Találjon
- megtalálása
- vezetéknév
- öt
- Rugalmasság
- rugalmas
- áramlási
- Összpontosít
- összpontosított
- koncentrál
- összpontosítás
- következik
- következő
- következik
- élelmiszer
- A
- forma
- formátum
- alakult
- szerencsére
- talált
- Keretrendszer
- keretek
- gyakran
- barát
- barátok
- ból ből
- Tele
- teljes értékű
- funkció
- funkciós
- funkcionalitás
- funkciók
- alapvető
- vicces
- további
- jövő
- Nyereség
- Games
- Gates
- általános
- általában
- generál
- generált
- generál
- generáló
- generáció
- fajta
- Németország
- kap
- szerzés
- gif
- GitHub
- adott
- GMT
- Go
- Goes
- megy
- jó
- szemcsés
- grafikon
- nagy
- nagyobb
- útmutatást
- útmutató
- irányelvek
- hackathon
- fogantyú
- Fogantyúk
- Kezelés
- ügyes
- Kemény
- kárt
- hevederek
- Legyen
- tekintettel
- súlyosan
- hős
- segít
- hasznos
- segít
- neki
- itt
- hi
- Magas
- magas szinten
- jó minőségű
- legnagyobb
- nagyon
- történeti
- történelem
- Lyuk
- motorháztető
- vendéglátó
- Hogyan
- How To
- azonban
- HTML
- http
- HTTPS
- Kerékagy
- emberi
- Több száz
- i
- ID
- ötlet
- ideális
- ids
- if
- ii
- III
- ábrázol
- illusztrálja
- képek
- azonnali
- végre
- végrehajtás
- megvalósítások
- végre
- importál
- fejlesztések
- javuló
- in
- mélyreható
- tartalmaz
- beleértve
- magában foglalja a
- Beleértve
- bele
- amely magában foglalja
- hihetetlenül
- index
- indexek
- jelez
- jelzi
- Egyénileg
- egyének
- információ
- kezdetben
- kezdeményez
- újító
- bemenet
- bemenet
- meglátások
- telepíteni
- telepítve
- telepítése
- példa
- azonnali
- helyette
- utasítás
- szerves
- integrálni
- integrált
- integrál
- integrálása
- integráció
- integrációk
- Intelligens
- szándékolt
- kölcsönhatásba
- kölcsönhatás
- kölcsönhatások
- interaktív
- kölcsönhatásba lép
- Felület
- interfészek
- belsőleg
- Internet
- bele
- Bevezetett
- Bemutatja
- intuitív
- bevonásával
- Hát
- kérdés
- kérdések
- IT
- tételek
- iterációk
- ITS
- maga
- Jackson
- JavaScript
- Munka
- Jordánia
- utazás
- json
- július
- éppen
- Igazság
- Tart
- tartja
- Kulcs
- kulcsok
- Kedves
- Ismer
- tudás
- Tudás Graph
- ismert
- Címke
- Címkék
- Telek
- nyelv
- Nyelvek
- nagy
- nagyobb
- keresztnév
- Késleltetés
- a későbbiekben
- legutolsó
- Liga
- TANUL
- tanulás
- balra
- Örökség
- Hossz
- kevesebb
- hadd
- Lets
- levél
- szint
- szintek
- Tőkeáttétel
- kihasználja
- erőfölény
- könyvtárak
- könyvtár
- mint
- Valószínű
- LIMIT
- korlátozások
- Korlátozott
- korlátozó
- határértékek
- linkek
- Lista
- hallgat
- listák
- él
- ll
- LLM
- kiszámításának
- rakodó
- található
- elhelyezkedés
- log
- bejelentkezve
- fakitermelés
- logika
- Hosszú
- hosszabb
- néz
- keres
- MEGJELENÉS
- lookup
- az
- Los Angeles
- Elő/Utó
- gép
- gépi tanulás
- készült
- fenntartása
- Karbantartható
- fenntartása
- fenntartja
- csinál
- KÉSZÍT
- Gyártás
- kezelése
- vezetés
- menedzser
- kezelése
- Manchester
- Manchester United
- Manipuláció
- mód
- kézikönyv
- Gyártó
- sok
- sok ember
- térkép
- térképészet
- Térképek
- Mérkőzés
- egyező
- matematikai
- matematikai
- számít
- maximális
- Lehet..
- me
- jelent
- jelenti
- eszközök
- intézkedés
- Média
- találkozó
- Megfelel
- Memories
- Memory design
- említett
- megy
- egyesülő
- üzenet
- üzenetek
- üzenetküldés
- Metaadatok
- módszer
- mód
- Metrics
- esetleg
- Több millió
- minimális
- kisebb
- hiányzó
- hibákat
- Keverés
- MLB
- Mobil
- modell
- modellek
- mérséklet
- Modulok
- Modulok
- pillanat
- MongoDB
- monitor
- ellenőrzés
- Hold
- több
- a legtöbb
- Legnepszerubb
- mozog
- film
- sok
- többszörös
- több lánc
- Pézsma
- kell
- my
- név
- Nevezett
- nevek
- nemzeti
- Természetes
- Természetes nyelvi feldolgozás
- Keresse
- navigálás
- Közel
- elengedhetetlen
- Szükség
- szükséges
- igények
- negatív
- Új
- New York
- New York Times
- következő
- nem
- Egyik sem
- semmi
- fogalom
- Most
- szám
- Obama
- tárgy
- célkitűzés
- objektumok
- megfigyelés
- szerez
- megszerzése
- OCR
- of
- ajánlat
- felajánlás
- Ajánlatok
- gyakran
- oh
- Rendben
- olympics
- on
- egyszer
- ONE
- csak
- nyílt forráskódú
- OpenAI
- Művelet
- operátor
- optimalizált
- Optimalizálja
- opció
- or
- érdekében
- organikus
- szervezetek
- eredeti
- OS
- Más
- Egyéb
- másképp
- mi
- ki
- teljesítmény
- kimenetek
- felett
- felülírás
- áttekintés
- saját
- csomag
- csomagok
- oldal
- oldalak
- párok
- pandák
- Papír
- Párhuzamos
- paraméter
- paraméterek
- Park
- rész
- különösen
- alkatrészek
- elhalad
- Elmúlt
- bérletek
- Múló
- múlt
- ösvény
- utak
- minták
- Payroll
- Emberek (People)
- mert
- tökéletes
- tökéletesen
- Teljesít
- teljesítmény
- előadó
- Előadja
- engedélyek
- kitartás
- person
- Személyre
- perspektíva
- Fizika
- darab
- csővezeték
- Pizza
- placeholder
- emelvény
- Plató
- Platón adatintelligencia
- PlatoData
- játszani
- játszótér
- játszik
- kérem
- plusz
- pont
- Politikák
- politika
- politikai
- medence
- Népszerű
- benépesített
- pozitív
- lehetséges
- állás
- Hozzászólások
- potenciális
- hatalom
- powered
- erős
- Gyakorlati
- gyakorlat
- jobban szeret
- miniszterelnök
- be
- elnök
- megakadályozása
- megakadályozása
- előző
- elsősorban
- elsődleges
- Első
- magán
- Probléma
- problémák
- folytassa
- folyamat
- Feldolgozott
- Folyamatok
- feldolgozás
- gyárt
- Termékek
- Termelés
- Egyetemi tanár
- Programozás
- programozási nyelvek
- program
- projektek
- ingatlanait
- ingatlan
- PROS
- prototípus
- prototípus
- ad
- feltéve,
- ellátó
- szolgáltatók
- biztosít
- amely
- nyilvános
- cél
- célokra
- tesz
- Piton
- Kérdések és válaszok
- világítás
- lekérdezések
- kérdés
- Kérdések
- Quick
- gyorsan
- idézetek
- R
- emel
- hatótávolság
- kezdve
- Inkább
- értékelés
- Nyers
- RE
- el
- Reagál
- Olvass
- Olvasás
- kész
- igazi
- real-time
- valós idejű adatok
- birodalom
- ok
- miatt
- új
- ajánlott
- feljegyzett
- nyilvántartások
- Meggyógyul
- csökkenteni
- csökkenti
- csökkentő
- csökkentés
- referencia
- referenciái
- finomítani
- finomítás
- régiók
- Kapcsolatok
- felszabaduló
- relevancia
- megbízhatóság
- megbízható
- támaszkodnak
- támaszkodva
- maradványok
- eszébe jut
- emlékeztető
- távoli
- hozam
- ismétlés
- TÖBBSZÖR
- átfogalmazva
- cserélni
- jelentést
- raktár
- képviselet
- képviselő
- jelentése
- kérni
- kéri
- szükség
- kötelező
- követelmények
- megköveteli,
- mentés
- kutatás
- megoldása
- forrás
- Reagálni
- válaszol
- válasz
- válaszok
- felelős
- fogékony
- REST
- eredményez
- kapott
- Eredmények
- visszatartó
- visszatartás
- visszatérés
- visszatérő
- Visszatér
- újrahasználható
- Kritika
- forog
- Rizs
- Gazdag
- robotok
- Szerep
- szerepek
- gyökér
- routing
- SOR
- futás
- futás
- fut
- futásidejű
- s
- biztosítékok
- értékesítés
- értékesítési erő
- Sam
- azonos
- Megtakarítás
- azt mondják
- azt mondja,
- skálázható
- Skála
- forgatókönyv
- forgatókönyvek
- jelenetek
- menetrend
- pontszám
- kaparni
- zökkenőmentes
- zökkenőmentesen
- Keresés
- kereső
- keresések
- keres
- Rész
- szakaszok
- biztonság
- biztonság
- lát
- kiválasztott
- kiválasztás
- Eladási
- küld
- érzékeny
- érzés
- érzések
- különálló
- szeptember
- Sorozat
- Series of
- szolgál
- szerver
- szolgálja
- Szolgáltatások
- készlet
- Szettek
- beállítás
- beállítások
- felépítés
- hét
- számos
- Megosztás
- megosztott
- Héj
- ragyog
- szállított
- kellene
- előadás
- kirakat
- mutatott
- Műsorok
- Sigma
- jelentős
- hasonló
- Egyszerű
- egyszerűsített
- egyszerűsítése
- egyszerűsítése
- egyszerűen
- óta
- egyetlen
- Méret
- laza
- kicsi
- kisebb
- okos
- töredék
- So
- eddig
- Futball
- Közösség
- Közösségi média
- Közösségi média bejegyzések
- Kizárólag
- szilárd
- megoldások
- SOLVE
- néhány
- valami
- néha
- kifinomult
- hangok
- forrás
- Források
- Hely
- spanyol
- specializált
- különleges
- kifejezetten
- sajátosságait
- meghatározott
- sebesség
- költött
- osztott
- szakadások
- Sport
- négyzet
- állvány
- önálló
- standard
- kezdet
- kezdődött
- Kezdve
- Állami
- nyilatkozatok
- statikus
- Lépés
- Lépései
- Még mindig
- megáll
- megállítás
- Leállítja
- tárolás
- tárolni
- memorizált
- árnyékolók
- tárolása
- Történet
- egyértelmű
- folyam
- folyó
- áramvonal
- áramvonalas
- erősségek
- Strikes
- Húr
- struktúra
- szerkesztett
- struktúrák
- strukturálása
- stílus
- tárgy
- későbbi
- sikeresen
- ilyen
- Öltöny
- megfelelő
- kíséret
- összegez
- ÖSSZEFOGLALÓ
- napnyugta
- támogatás
- Támogatott
- Támogatja
- biztos
- Fenntarthatóság
- összehangolás
- szinopszis
- szintaxis
- rendszer
- Systems
- táblázat
- Szabó
- szabott
- Vesz
- tart
- célok
- Feladat
- feladatok
- csapat
- csapat
- mondd
- sablon
- sablonok
- terminál
- terminológia
- feltételek
- teszt
- Tesztelés
- szöveg
- mint
- Kösz
- hogy
- A
- Az alapok
- az agy
- az információ
- A New York Times
- A projektek
- The Source
- a világ
- azok
- Őket
- akkor
- Ott.
- Ezek
- ők
- dolgok
- ezt
- azok
- bár?
- Keresztül
- egész
- idő
- időigényes
- alkalommal
- Cím
- nak nek
- együtt
- jelképes
- tokenizálás
- tokenek
- is
- szerszám
- eszköztár
- szerszámok
- felső
- téma
- Témakörök
- Végösszeg
- város
- nyomkövetés
- vágány
- hagyományos
- Képzések
- Átalakítás
- transzformációk
- transzformátor
- transzformerek
- átmenet
- próba
- igaz
- valóban
- megpróbál
- hangolás
- FORDULAT
- Turning
- oktatói
- Kétszer
- kettő
- típus
- típusok
- Gépelt
- jellemzően
- ui
- Végül
- érzéketlen
- alatt
- mögöttes
- megért
- megértés
- megérti
- egységes
- egyedi
- Egyesült
- Egyetemes
- nem úgy mint
- -ig
- Frissítések
- Frissítés
- feltöltve
- URL
- us
- használhatóság
- Használat
- használ
- használati eset
- használt
- használó
- felhasználói felület
- Felhasználók
- használ
- segítségével
- segédprogramok
- hasznosít
- hasznosított
- hasznosítja
- kihasználva
- v1
- érvényesítés
- érvényesítő
- Értékes
- érték
- Értékek
- változó
- fajta
- különféle
- Ve
- sokoldalú
- változat
- nagyon
- keresztül
- videó
- Megnézem
- jogsértések
- látható
- Képzeld
- fontos
- vs
- séta
- végigjátszás
- akar
- volt
- Nézz
- Út..
- módon
- we
- időjárás
- háló
- webböngésző
- webes szolgáltatások
- honlapok
- JÓL
- jól ismert
- voltak
- Mit
- Mi
- Mi
- amikor
- vajon
- ami
- míg
- WHO
- egész
- miért
- széles
- széles körben
- modul
- Wikipedia
- lesz
- ablak
- Győzelem
- val vel
- belül
- nélkül
- szó
- Munka
- dolgozott
- munkafolyamat
- munkafolyamatok
- dolgozó
- művek
- világ
- lenne
- ír
- írás
- X
- még
- york
- te
- A te
- magad
- youtube
- Zendesk
- zephyrnet
- Postai irányítószám