반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

LC-Modules-Agents Quickstart

2024. 2. 14. 12:41 | Posted by 솔웅


반응형

https://python.langchain.com/docs/modules/agents/quick_start

 

Quickstart | 🦜️🔗 Langchain

quickstart}

python.langchain.com

 

 

 

Quickstart

To best understand the agent framework, let’s build an agent that has two tools: one to look things up online, and one to look up specific data that we’ve loaded into a index.

 

에이전트 프레임워크를 가장 잘 이해하기 위해 두 가지 도구가 있는 에이전트를 구축해 보겠습니다. 하나는 온라인으로 항목을 조회하는 도구이고 다른 하나는 인덱스에 로드한 특정 데이터를 조회하는 도구입니다.

 

This will assume knowledge of LLMs and retrieval so if you haven’t already explored those sections, it is recommended you do so.

 

이는 LLM 및 검색에 대한 지식을 가정하므로 해당 섹션을 아직 탐색하지 않았다면 탐색하는 것이 좋습니다.

 

Setup: LangSmith

By definition, agents take a self-determined, input-dependent sequence of steps before returning a user-facing output. This makes debugging these systems particularly tricky, and observability particularly important. LangSmith is especially useful for such cases.

 

정의에 따르면 에이전트는 사용자에게 표시되는 출력을 반환하기 전에 입력에 따라 자체 결정된 일련의 단계를 수행합니다. 이로 인해 이러한 시스템을 디버깅하는 것이 특히 까다로워지고 관찰 가능성이 특히 중요해집니다. LangSmith는 이러한 경우에 특히 유용합니다.

 

When building with LangChain, all steps will automatically be traced in LangSmith. To set up LangSmith we just need set the following environment variables:

 

LangChain으로 구축할 때 모든 단계는 LangSmith에서 자동으로 추적됩니다. LangSmith를 설정하려면 다음 환경 변수만 설정하면 됩니다.

 

export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="<your-api-key>"

 

 

Define tools

We first need to create the tools we want to use. We will use two tools: Tavily (to search online) and then a retriever over a local index we will create

 

먼저 사용하려는 도구를 만들어야 합니다. 우리는 두 가지 도구를 사용할 것입니다: Tavily(온라인 검색용)와 우리가 생성할 로컬 인덱스에 대한 검색기

 

Tavily

We have a built-in tool in LangChain to easily use Tavily search engine as tool. Note that this requires an API key - they have a free tier, but if you don’t have one or don’t want to create one, you can always ignore this step.

 

우리는 Tavily 검색 엔진을 도구로 쉽게 사용할 수 있도록 LangChain에 내장된 도구를 가지고 있습니다. 이를 위해서는 API 키가 필요합니다. 무료 등급이 있지만 API 키가 없거나 생성하고 싶지 않은 경우 언제든지 이 단계를 무시할 수 있습니다.

 

Once you create your API key, you will need to export that as:

 

API 키를 생성한 후에는 이를 다음과 같이 내보내야 합니다.

 

export TAVILY_API_KEY="..."
from langchain_community.tools.tavily_search import TavilySearchResults
search = TavilySearchResults()
search.invoke("what is the weather in SF")
[{'url': 'https://www.metoffice.gov.uk/weather/forecast/9q8yym8kr',
  'content': 'Thu 11 Jan Thu 11 Jan Seven day forecast for San Francisco  San Francisco (United States of America) weather Find a forecast  Sat 6 Jan Sat 6 Jan Sun 7 Jan Sun 7 Jan Mon 8 Jan Mon 8 Jan Tue 9 Jan Tue 9 Jan Wed 10 Jan Wed 10 Jan Thu 11 Jan  Find a forecast Please choose your location from the nearest places to : Forecast days Today Today Sat 6 Jan Sat 6 JanSan Francisco 7 day weather forecast including weather warnings, temperature, rain, wind, visibility, humidity and UV ... (11 January 2024) Time 00:00 01:00 02:00 03:00 04:00 05:00 06:00 07:00 08:00 09:00 10:00 11:00 12:00 ... Oakland Int. 11.5 miles; San Francisco International 11.5 miles; Corte Madera 12.3 miles; Redwood City 23.4 miles;'},
 {'url': 'https://www.latimes.com/travel/story/2024-01-11/east-brother-light-station-lighthouse-california',
  'content': "May 18, 2023  Jan. 4, 2024 Subscribe for unlimited accessSite Map Follow Us MORE FROM THE L.A. TIMES  Jan. 8, 2024 Travel & Experiences This must be Elysian Valley (a.k.a. Frogtown) Jan. 5, 2024 Food  June 30, 2023The East Brother Light Station in the San Francisco Bay is not a destination for everyone. ... Jan. 11, 2024 3 AM PT ... Champagne and hors d'oeuvres are served in late afternoon — outdoors if ..."}]

 

Retriever

We will also create a retriever over some data of our own. For a deeper explanation of each step here, see this section.

 

우리는 또한 우리 자신의 일부 데이터에 대한 검색기를 만들 것입니다. 각 단계에 대한 자세한 설명은 이 섹션을 참조하세요.

 

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

loader = WebBaseLoader("https://docs.smith.langchain.com/overview")
docs = loader.load()
documents = RecursiveCharacterTextSplitter(
    chunk_size=1000, chunk_overlap=200
).split_documents(docs)
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
retriever = vector.as_retriever()
retriever.get_relevant_documents("how to upload a dataset")[0]
Document(page_content="dataset uploading.Once we have a dataset, how can we use it to test changes to a prompt or chain? The most basic approach is to run the chain over the data points and visualize the outputs. Despite technological advancements, there still is no substitute for looking at outputs by eye. Currently, running the chain over the data points needs to be done client-side. The LangSmith client makes it easy to pull down a dataset and then run a chain over them, logging the results to a new project associated with the dataset. From there, you can review them. We've made it easy to assign feedback to runs and mark them as correct or incorrect directly in the web app, displaying aggregate statistics for each test project.We also make it easier to evaluate these runs. To that end, we've added a set of evaluators to the open-source LangChain library. These evaluators can be specified when initiating a test run and will evaluate the results once the test run completes. If we’re being honest, most of", metadata={'source': 'https://docs.smith.langchain.com/overview', 'title': 'LangSmith Overview and User Guide | 🦜️🛠️ LangSmith', 'description': 'Building reliable LLM applications can be challenging. LangChain simplifies the initial setup, but there is still work needed to bring the performance of prompts, chains and agents up the level where they are reliable enough to be used in production.', 'language': 'en'})

 

Now that we have populated our index that we will do doing retrieval over, we can easily turn it into a tool (the format needed for an agent to properly use it)

 

이제 검색을 수행할 인덱스를 채웠으므로 이를 도구(에이전트가 올바르게 사용하는 데 필요한 형식)로 쉽게 전환할 수 있습니다.

 

from langchain.tools.retriever import create_retriever_tool
retriever_tool = create_retriever_tool(
    retriever,
    "langsmith_search",
    "Search for information about LangSmith. For any questions about LangSmith, you must use this tool!",
)

 

 

Tools

Now that we have created both, we can create a list of tools that we will use downstream.

 

이제 두 가지를 모두 만들었으므로 다운스트림에서 사용할 도구 목록을 만들 수 있습니다.

 

tools = [search, retriever_tool]

 

 

Create the agent

Now that we have defined the tools, we can create the agent. We will be using an OpenAI Functions agent - for more information on this type of agent, as well as other options, see this guide

 

Agent Types | 🦜️🔗 Langchain

This categorizes all the available agents along a few dimensions.

python.langchain.com

 

이제 도구를 정의했으므로 에이전트를 만들 수 있습니다. OpenAI Functions 에이전트를 사용할 것입니다. 이러한 유형의 에이전트와 기타 옵션에 대한 자세한 내용은 이 가이드를 참조하세요.

 

First, we choose the LLM we want to be guiding the agent.

 

먼저 에이전트를 안내할 LLM을 선택합니다.

 

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

 

Next, we choose the prompt we want to use to guide the agent.

 

다음으로 상담원을 안내하는 데 사용할 프롬프트를 선택합니다.

 

 

If you want to see the contents of this prompt and have access to LangSmith, you can go to:

 

이 프롬프트의 내용을 보고 LangSmith에 액세스하려면 다음으로 이동하세요.

 

https://smith.langchain.com/hub/hwchase17/openai-functions-agent

 

LangSmith

 

smith.langchain.com

 

from langchain import hub

# Get the prompt to use - you can modify this!
prompt = hub.pull("hwchase17/openai-functions-agent")
prompt.messages

 

[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')),
 MessagesPlaceholder(variable_name='chat_history', optional=True),
 HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')),
 MessagesPlaceholder(variable_name='agent_scratchpad')]

 

Now, we can initalize the agent with the LLM, the prompt, and the tools. The agent is responsible for taking in input and deciding what actions to take. Crucially, the Agent does not execute those actions - that is done by the AgentExecutor (next step). For more information about how to think about these components, see our conceptual guide

 

Concepts | 🦜️🔗 Langchain

The core idea of agents is to use a language model to choose a sequence of actions to take.

python.langchain.com

 

 

이제 LLM, 프롬프트 및 도구를 사용하여 에이전트를 초기화할 수 있습니다. 에이전트는 입력을 받아들이고 어떤 조치를 취할지 결정하는 역할을 담당합니다. 결정적으로 에이전트는 이러한 작업을 실행하지 않습니다. 이는 AgentExecutor(다음 단계)에 의해 수행됩니다. 이러한 구성 요소에 대해 생각하는 방법에 대한 자세한 내용은 개념 가이드를 참조하세요.

 

from langchain.agents import create_openai_functions_agent

agent = create_openai_functions_agent(llm, tools, prompt)

 

Finally, we combine the agent (the brains) with the tools inside the AgentExecutor (which will repeatedly call the agent and execute tools). For more information about how to think about these components, see our conceptual guide

 

Concepts | 🦜️🔗 Langchain

The core idea of agents is to use a language model to choose a sequence of actions to take.

python.langchain.com

 

마지막으로 에이전트(브레인)를 AgentExecutor 내부 도구(반복적으로 에이전트를 호출하고 도구를 실행함)와 결합합니다. 이러한 구성 요소에 대해 생각하는 방법에 대한 자세한 내용은 개념 가이드를 참조하세요.

 

from langchain.agents import AgentExecutor

agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

 

Run the agent

We can now run the agent on a few queries! Note that for now, these are all stateless queries (it won’t remember previous interactions).

 

이제 몇 가지 쿼리에 대해 에이전트를 실행할 수 있습니다! 현재로서는 이는 모두 상태 비저장 쿼리입니다(이전 상호 작용을 기억하지 않음).

 

agent_executor.invoke({"input": "hi!"})

 


> Entering new AgentExecutor chain...
Hello! How can I assist you today?

> Finished chain.

 

{'input': 'hi!', 'output': 'Hello! How can I assist you today?'}

 

agent_executor.invoke({"input": "how can langsmith help with testing?"})

 


> Entering new AgentExecutor chain...

Invoking: `langsmith_search` with `{'query': 'LangSmith testing'}`


[Document(page_content='LangSmith Overview and User Guide | 🦜️🛠️ LangSmith', metadata={'source': 'https://docs.smith.langchain.com/overview', 'title': 'LangSmith Overview and User Guide | 🦜️🛠️ LangSmith', 'description': 'Building reliable LLM applications can be challenging. LangChain simplifies the initial setup, but there is still work needed to bring the performance of prompts, chains and agents up the level where they are reliable enough to be used in production.', 'language': 'en'}), Document(page_content='Skip to main content🦜️🛠️ LangSmith DocsPython DocsJS/TS DocsSearchGo to AppLangSmithOverviewTracingTesting & EvaluationOrganizationsHubLangSmith CookbookOverviewOn this pageLangSmith Overview and User GuideBuilding reliable LLM applications can be challenging. LangChain simplifies the initial setup, but there is still work needed to bring the performance of prompts, chains and agents up the level where they are reliable enough to be used in production.Over the past two months, we at LangChain have been building and using LangSmith with the goal of bridging this gap. This is our tactical user guide to outline effective ways to use LangSmith and maximize its benefits.On by default\u200bAt LangChain, all of us have LangSmith’s tracing running in the background by default. On the Python side, this is achieved by setting environment variables, which we establish whenever we launch a virtual environment or open our bash shell and leave them set. The same principle applies to most JavaScript', metadata={'source': 'https://docs.smith.langchain.com/overview', 'title': 'LangSmith Overview and User Guide | 🦜️🛠️ LangSmith', 'description': 'Building reliable LLM applications can be challenging. LangChain simplifies the initial setup, but there is still work needed to bring the performance of prompts, chains and agents up the level where they are reliable enough to be used in production.', 'language': 'en'}), Document(page_content='You can also quickly edit examples and add them to datasets to expand the surface area of your evaluation sets or to fine-tune a model for improved quality or reduced costs.Monitoring\u200bAfter all this, your app might finally ready to go in production. LangSmith can also be used to monitor your application in much the same way that you used for debugging. You can log all traces, visualize latency and token usage statistics, and troubleshoot specific issues as they arise. Each run can also be assigned string tags or key-value metadata, allowing you to attach correlation ids or AB test variants, and filter runs accordingly.We’ve also made it possible to associate feedback programmatically with runs. This means that if your application has a thumbs up/down button on it, you can use that to log feedback back to LangSmith. This can be used to track performance over time and pinpoint under performing data points, which you can subsequently add to a dataset for future testing — mirroring the', metadata={'source': 'https://docs.smith.langchain.com/overview', 'title': 'LangSmith Overview and User Guide | 🦜️🛠️ LangSmith', 'description': 'Building reliable LLM applications can be challenging. LangChain simplifies the initial setup, but there is still work needed to bring the performance of prompts, chains and agents up the level where they are reliable enough to be used in production.', 'language': 'en'}), Document(page_content='inputs, and see what happens. At some point though, our application is performing\nwell and we want to be more rigorous about testing changes. We can use a dataset\nthat we’ve constructed along the way (see above). Alternatively, we could spend some\ntime constructing a small dataset by hand. For these situations, LangSmith simplifies', metadata={'source': 'https://docs.smith.langchain.com/overview', 'title': 'LangSmith Overview and User Guide | 🦜️🛠️ LangSmith', 'description': 'Building reliable LLM applications can be challenging. LangChain simplifies the initial setup, but there is still work needed to bring the performance of prompts, chains and agents up the level where they are reliable enough to be used in production.', 'language': 'en'})]LangSmith can help with testing in several ways. Here are some ways LangSmith can assist with testing:

1. Tracing: LangSmith provides tracing capabilities that can be used to monitor and debug your application during testing. You can log all traces, visualize latency and token usage statistics, and troubleshoot specific issues as they arise.

2. Evaluation: LangSmith allows you to quickly edit examples and add them to datasets to expand the surface area of your evaluation sets. This can help you test and fine-tune your models for improved quality or reduced costs.

3. Monitoring: Once your application is ready for production, LangSmith can be used to monitor your application. You can log feedback programmatically with runs, track performance over time, and pinpoint underperforming data points. This information can be used to improve your application and add to datasets for future testing.

4. Rigorous Testing: When your application is performing well and you want to be more rigorous about testing changes, LangSmith can simplify the process. You can use existing datasets or construct small datasets by hand to test different scenarios and evaluate the performance of your application.

For more detailed information on how to use LangSmith for testing, you can refer to the [LangSmith Overview and User Guide](https://docs.smith.langchain.com/overview).

> Finished chain.

 

{'input': 'how can langsmith help with testing?',
 'output': 'LangSmith can help with testing in several ways. Here are some ways LangSmith can assist with testing:\n\n1. Tracing: LangSmith provides tracing capabilities that can be used to monitor and debug your application during testing. You can log all traces, visualize latency and token usage statistics, and troubleshoot specific issues as they arise.\n\n2. Evaluation: LangSmith allows you to quickly edit examples and add them to datasets to expand the surface area of your evaluation sets. This can help you test and fine-tune your models for improved quality or reduced costs.\n\n3. Monitoring: Once your application is ready for production, LangSmith can be used to monitor your application. You can log feedback programmatically with runs, track performance over time, and pinpoint underperforming data points. This information can be used to improve your application and add to datasets for future testing.\n\n4. Rigorous Testing: When your application is performing well and you want to be more rigorous about testing changes, LangSmith can simplify the process. You can use existing datasets or construct small datasets by hand to test different scenarios and evaluate the performance of your application.\n\nFor more detailed information on how to use LangSmith for testing, you can refer to the [LangSmith Overview and User Guide](https://docs.smith.langchain.com/overview).'}

 

 

Adding in memory

 

As mentioned earlier, this agent is stateless. This means it does not remember previous interactions. To give it memory we need to pass in previous chat_history. Note: it needs to be called chat_history because of the prompt we are using. If we use a different prompt, we could change the variable name

 

앞서 언급했듯이 이 에이전트는 Stateless입니다. 이는 이전 상호작용을 기억하지 못한다는 것을 의미합니다. 메모리를 제공하려면 이전 chat_history를 전달해야 합니다. 참고: 우리가 사용하는 프롬프트 때문에 chat_history라고 불러야 합니다. 다른 프롬프트를 사용하면 변수 이름을 변경할 수 있습니다.

 

# Here we pass in an empty list of messages for chat_history because it is the first message in the chat
agent_executor.invoke({"input": "hi! my name is bob", "chat_history": []})

> Entering new AgentExecutor chain...
Hello Bob! How can I assist you today?

> Finished chain.
{'input': 'hi! my name is bob',
 'chat_history': [],
 'output': 'Hello Bob! How can I assist you today?'}
from langchain_core.messages import AIMessage, HumanMessage
agent_executor.invoke(
    {
        "chat_history": [
            HumanMessage(content="hi! my name is bob"),
            AIMessage(content="Hello Bob! How can I assist you today?"),
        ],
        "input": "what's my name?",
    }
)

 


> Entering new AgentExecutor chain...
Your name is Bob.

> Finished chain.
{'chat_history': [HumanMessage(content='hi! my name is bob'),
  AIMessage(content='Hello Bob! How can I assist you today?')],
 'input': "what's my name?",
 'output': 'Your name is Bob.'}

 

 

If we want to keep track of these messages automatically, we can wrap this in a RunnableWithMessageHistory. For more information on how to use this, see this guide

 

Add message history (memory) | 🦜️🔗 Langchain

The RunnableWithMessageHistory let us add message history to certain

python.langchain.com

 

이러한 메시지를 자동으로 추적하려면 이를 RunnableWithMessageHistory로 래핑할 수 있습니다. 이를 사용하는 방법에 대한 자세한 내용은 이 가이드를 참조하세요.

 

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
message_history = ChatMessageHistory()
agent_with_chat_history = RunnableWithMessageHistory(
    agent_executor,
    # This is needed because in most real world scenarios, a session id is needed
    # It isn't really used here because we are using a simple in memory ChatMessageHistory
    lambda session_id: message_history,
    input_messages_key="input",
    history_messages_key="chat_history",
)
agent_with_chat_history.invoke(
    {"input": "hi! I'm bob"},
    # This is needed because in most real world scenarios, a session id is needed
    # It isn't really used here because we are using a simple in memory ChatMessageHistory
    config={"configurable": {"session_id": "<foo>"}},
)

> Entering new AgentExecutor chain...
Hello Bob! How can I assist you today?

> Finished chain.
{'input': "hi! I'm bob",
 'chat_history': [],
 'output': 'Hello Bob! How can I assist you today?'}
agent_with_chat_history.invoke(
    {"input": "what's my name?"},
    # This is needed because in most real world scenarios, a session id is needed
    # It isn't really used here because we are using a simple in memory ChatMessageHistory
    config={"configurable": {"session_id": "<foo>"}},
)

> Entering new AgentExecutor chain...
Your name is Bob.

> Finished chain.
{'input': "what's my name?",
 'chat_history': [HumanMessage(content="hi! I'm bob"),
  AIMessage(content='Hello Bob! How can I assist you today?')],
 'output': 'Your name is Bob.'}

 

Conclusion

That’s a wrap! In this quick start we covered how to create a simple agent. Agents are a complex topic, and there’s lot to learn! Head back to the main agent page to find more resources on conceptual guides, different types of agents, how to create custom tools, and more!

 

마무리입니다! 이 빠른 시작에서는 간단한 에이전트를 만드는 방법을 다루었습니다. 에이전트는 복잡한 주제이며 배울 것이 많습니다! 기본 에이전트 페이지로 돌아가서 개념 가이드, 다양한 유형의 에이전트, 사용자 정의 도구를 만드는 방법 등에 대한 추가 리소스를 찾아보세요!

반응형


반응형

https://python.langchain.com/docs/expression_language/why

 

Why use LCEL? | 🦜️🔗 Langchain

The LangChain Expression Language was designed from day 1 to support putting prototypes in production, with no code changes, from the simplest “prompt + LLM” chain to the most complex chains (we’ve seen folks successfully running in production LCEL c

python.langchain.com

 

Why use LCEL?

 

The LangChain Expression Language was designed from day 1 to support putting prototypes in production, with no code changes, from the simplest “prompt + LLM” chain to the most complex chains (we’ve seen folks successfully running in production LCEL chains with 100s of steps). To highlight a few of the reasons you might want to use LCEL:

 

LangChain 표현 언어는 가장 단순한 "프롬프트 + LLM" 체인부터 가장 복잡한 체인까지 코드 변경 없이 프로토타입을 프로덕션에 투입할 수 있도록 첫날부터 설계되었습니다. 단계). LCEL을 사용하려는 몇 가지 이유를 강조하려면 다음을 수행하십시오.

 

 

  • first-class support for streaming: when you build your chains with LCEL you get the best possible time-to-first-token (time elapsed until the first chunk of output comes out). For some chains this means eg. we stream tokens straight from an LLM to a streaming output parser, and you get back parsed, incremental chunks of output at the same rate as the LLM provider outputs the raw tokens. We’re constantly improving streaming support, recently we added a streaming JSON parser, and more is in the works.

  • 스트리밍에 대한 최고 수준의 지원: LCEL로 체인을 구축하면 첫 번째 토큰까지의 시간(첫 번째 출력 덩어리가 나올 때까지 경과된 시간)을 최대한 얻을 수 있습니다. 일부 체인의 경우 이는 예를 들어 다음을 의미합니다. 우리는 LLM에서 스트리밍 출력 파서로 토큰을 직접 스트리밍하고 LLM 공급자가 원시 토큰을 출력하는 것과 동일한 속도로 구문 분석된 증분 출력 청크를 다시 얻습니다. 우리는 스트리밍 지원을 지속적으로 개선하고 있으며 최근에는 스트리밍 JSON 파서를 추가하는 등 더 많은 작업이 진행 중입니다.

  • first-class async support: any chain built with LCEL can be called both with the synchronous API (eg. in your Jupyter notebook while prototyping) as well as with the asynchronous API (eg. in a LangServe server). This enables using the same code for prototypes and in production, with great performance, and the ability to handle many concurrent requests in the same server.

  • 최고 수준의 비동기 지원: LCEL로 구축된 모든 체인은 동기 API(예: 프로토타입 작성 중 Jupyter 노트북에서)와 비동기 API(예: LangServe 서버에서)를 통해 호출할 수 있습니다. 이를 통해 프로토타입과 프로덕션에서 동일한 코드를 사용할 수 있으며 뛰어난 성능을 발휘하고 동일한 서버에서 많은 동시 요청을 처리할 수 있습니다.

  • optimized parallel execution: whenever your LCEL chains have steps that can be executed in parallel (eg if you fetch documents from multiple retrievers) we automatically do it, both in the sync and the async interfaces, for the smallest possible latency.

  • 최적화된 병렬 실행: LCEL 체인에 병렬로 실행될 수 있는 단계가 있을 때마다(예: 여러 검색기에서 문서를 가져오는 경우) 가능한 가장 짧은 대기 시간을 위해 동기화 및 비동기 인터페이스 모두에서 자동으로 이를 수행합니다.

  • support for retries and fallbacks: more recently we’ve added support for configuring retries and fallbacks for any part of your LCEL chain. This is a great way to make your chains more reliable at scale. We’re currently working on adding streaming support for retries/fallbacks, so you can get the added reliability without any latency cost.

  • 재시도 및 대체 지원: 최근에는 LCEL 체인의 모든 부분에 대한 재시도 및 대체 구성에 대한 지원을 추가했습니다. 이는 대규모로 체인을 더욱 안정적으로 만들 수 있는 좋은 방법입니다. 현재 재시도/대체에 대한 스트리밍 지원을 추가하기 위해 노력하고 있으므로 지연 시간 비용 없이 추가된 안정성을 얻을 수 있습니다.

  • accessing intermediate results: for more complex chains it’s often very useful to access the results of intermediate steps even before the final output is produced. This can be used let end-users know something is happening, or even just to debug your chain. We’ve added support for streaming intermediate results, and it’s available on every LangServe server.

  • 중간 결과에 액세스: 보다 복잡한 체인의 경우 최종 출력이 생성되기 전에도 중간 단계의 결과에 액세스하는 것이 매우 유용한 경우가 많습니다. 이는 최종 사용자에게 무슨 일이 일어나고 있는지 알리거나 체인을 디버깅하는 데 사용할 수 있습니다. 중간 결과 스트리밍에 대한 지원이 추가되었으며 모든 LangServe 서버에서 사용할 수 있습니다.

  • input and output schemas: input and output schemas give every LCEL chain Pydantic and JSONSchema schemas inferred from the structure of your chain. This can be used for validation of inputs and outputs, and is an integral part of LangServe.

  • 입력 및 출력 스키마: 입력 및 출력 스키마는 모든 LCEL 체인에 체인 구조에서 유추된 Pydantic 및 JSONSchema 스키마를 제공합니다. 이는 입력과 출력의 검증에 사용될 수 있으며 LangServe의 필수적인 부분입니다.

  • tracing with LangSmith: all chains built with LCEL have first-class tracing support, which can be used to debug your chains, or to understand what’s happening in production. To enable this all you have to do is add your LangSmith API key as an environment variable.

  • LangSmith를 사용한 추적: LCEL로 구축된 모든 체인은 체인을 디버깅하거나 프로덕션에서 무슨 일이 일어나고 있는지 이해하는 데 사용할 수 있는 최고 수준의 추적 지원을 제공합니다. 이를 활성화하려면 LangSmith API 키를 환경 변수로 추가하기만 하면 됩니다.

 

 

 

 

 

 

 

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/tools

 

Using tools | 🦜️🔗 Langchain

You can use any Tools with Runnables easily.

python.langchain.com

 

Using tools

 

You can use any Tools with Runnables easily.

 

Runnables와 함께 모든 도구를 쉽게 사용할 수 있습니다.

 

pip install duckduckgo-search

 

from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.tools import 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

 

chain.invoke({"input": "I'd like to figure out what games are tonight"})

 

    'What sports games are on TV today & tonight? Watch and stream live sports on TV today, tonight, tomorrow. Today\'s 2023 sports TV schedule includes football, basketball, baseball, hockey, motorsports, soccer and more. Watch on TV or stream online on ESPN, FOX, FS1, CBS, NBC, ABC, Peacock, Paramount+, fuboTV, local channels and many other networks. MLB Games Tonight: How to Watch on TV, Streaming & Odds - Thursday, September 7. Seattle Mariners\' Julio Rodriguez greets teammates in the dugout after scoring against the Oakland Athletics in a ... Circle - Country Music and Lifestyle. Live coverage of all the MLB action today is available to you, with the information provided below. The Brewers will look to pick up a road win at PNC Park against the Pirates on Wednesday at 12:35 PM ET. Check out the latest odds and with BetMGM Sportsbook. Use bonus code "GNPLAY" for special offers! MLB Games Tonight: How to Watch on TV, Streaming & Odds - Tuesday, September 5. Houston Astros\' Kyle Tucker runs after hitting a double during the fourth inning of a baseball game against the Los Angeles Angels, Sunday, Aug. 13, 2023, in Houston. (AP Photo/Eric Christian Smith) (APMedia) The Houston Astros versus the Texas Rangers is one of ... The second half of tonight\'s college football schedule still has some good games remaining to watch on your television.. We\'ve already seen an exciting one when Colorado upset TCU. And we saw some ...'

 

 

이 코드는 LangChain을 사용하여 DuckDuckGo 검색 엔진을 활용해 사용자 입력을 검색 쿼리로 변환하고 검색 결과를 반환하는 과정을 수행합니다. 아래는 코드의 주요 부분에 대한 설명입니다:

  1. pip install duckduckgo-search: 우선 duckduckgo-search 패키지를 설치합니다. 이 패키지는 DuckDuckGo 검색 엔진을 사용할 수 있게 해줍니다.
  2. from langchain.chat_models import ChatOpenAI: OpenAI의 언어 모델을 사용하기 위한 모듈을 가져옵니다.
  3. from langchain.prompts import ChatPromptTemplate: 대화식 프롬프트를 작성하기 위한 모듈을 가져옵니다.
  4. from langchain.schema.output_parser import StrOutputParser: 모델의 출력을 파싱하고 문자열로 반환하는 데 사용할 출력 파서를 가져옵니다.
  5. from langchain.tools import DuckDuckGoSearchRun: DuckDuckGo 검색을 수행하기 위한 모듈을 가져옵니다.
  6. template = """turn the following user input into a search query for a search engine: ... """: 대화 프롬프트의 템플릿을 정의합니다. 사용자 입력을 검색 엔진 쿼리로 변환할 것이며, 이 템플릿을 사용하여 프롬프트를 생성합니다.
  7. prompt = ChatPromptTemplate.from_template(template): 정의한 템플릿을 사용하여 대화 프롬프트를 생성합니다.
  8. model = ChatOpenAI(): ChatOpenAI 모델을 초기화합니다. 이 모델은 사용자 입력을 검색 쿼리로 변환하는 역할을 수행합니다.
  9. chain = prompt | model | StrOutputParser() | search: 체인을 구성합니다. prompt 객체를 사용자 입력과 함께 모델 model에 전달한 후, 출력을 문자열로 파싱하고 최종적으로 search 객체를 사용하여 DuckDuckGo 검색을 수행합니다.
  10. chain.invoke({"input": "I'd like to figure out what games are tonight"}): "I'd like to figure out what games are tonight"와 같은 사용자 입력을 포함한 입력 딕셔너리를 체인에 전달하여 실행합니다. 결과적으로, 이 입력 문장이 DuckDuckGo 검색 쿼리로 변환되고, 검색 결과가 반환됩니다.

이를 통해 사용자의 입력이 검색 쿼리로 변환되어 DuckDuckGo에서 관련 정보를 검색하는 과정이 자동화됩니다.

 

 

이 예제를 로컬에서 돌렸더니 답을 얻지를 못했습니다.

어쨌던 다른 외부의 tool을 사용하는 방법은 chain에 그것을 넣어주면 되는군요.

 

 

 

 

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/moderation

 

Adding moderation | 🦜️🔗 Langchain

This shows how to add in moderation (or other safeguards) around your LLM application.

python.langchain.com

 

 

Adding moderation

 

This shows how to add in moderation (or other safeguards) around your LLM application.

 

이는 LLM 지원서에 중재(또는 기타 보호 장치)를 추가하는 방법을 보여줍니다.

 

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

 

chain.invoke({"input": "you are stupid"})

 

    '\n\nYou are stupid.'

 

이 코드는 OpenAI 모델을 사용하여 입력 문장을 반복 출력하는 간단한 작업을 수행하는 LangChain 스크립트를 설명합니다. 아래는 코드의 주요 부분에 대한 설명입니다:

  1. from langchain.chains import OpenAIModerationChain: OpenAIModerationChain은 입력된 텍스트를 OpenAI의 모더레이션 API를 사용하여 검사하고 부적절한 내용을 차단하려는 목적으로 사용됩니다.
  2. from langchain.llms import OpenAI: OpenAI 클래스는 LangChain 내에서 OpenAI GPT-3 모델을 사용하기 위한 클래스입니다.
  3. from langchain.prompts import ChatPromptTemplate: ChatPromptTemplate은 사용자와 시스템 간의 대화 템플릿을 정의하는 데 사용됩니다. 여기서 시스템은 사용자로부터 입력을 다시 출력하도록 지시하는 템플릿을 정의합니다.
  4. moderate = OpenAIModerationChain(): OpenAIModerationChain 객체를 만듭니다. 이 객체는 OpenAI의 모더레이션 API를 사용하여 입력된 텍스트를 검사하는 역할을 합니다.
  5. model = OpenAI(): LangChain을 통해 OpenAI의 모델을 사용하기 위한 OpenAI 객체를 만듭니다.
  6. prompt = ChatPromptTemplate.from_messages([("system", "repeat after me: {input}")]): 사용자에게 입력된 텍스트를 다시 반복하는 템플릿을 정의합니다.
  7. chain = prompt | model: 정의한 템플릿과 모델을 연결하여 대화 체인을 생성합니다.
  8. chain.invoke({"input": "you are stupid"}): 대화 체인을 사용하여 입력으로 "you are stupid"를 전달하고, 모델은 이 입력을 다시 출력하는 작업을 수행합니다.

 

moderated_chain = chain | moderate

 

moderated_chain.invoke({"input": "you are stupid"})

 

    {'input': '\n\nYou are stupid',
     'output': "Text was found that violates OpenAI's content policy."}

 

이 코드는 LangChain을 사용하여 OpenAI 모델을 통해 입력 문장을 반복 출력하는 작업에서 입력 문장을 OpenAI 모더레이션 API를 통해 검사하는 과정을 추가한 것입니다. 아래는 코드의 주요 부분에 대한 설명입니다:

  1. moderated_chain = chain | moderate: moderated_chain은 먼저 정의한 chain (OpenAI 모델을 사용하여 입력 문장을 반복 출력하는 체인)을 가져와, 이 체인에 moderate 객체를 추가합니다. | 연산자를 사용하여 체인을 연결합니다. moderate 객체는 OpenAI의 모더레이션 API를 통해 텍스트를 검사하는 역할을 합니다.
  2. moderated_chain.invoke({"input": "you are stupid"}): moderated_chain을 사용하여 입력으로 "you are stupid"를 전달합니다. 이때, 입력 문장은 moderate 객체를 거치게 되어 OpenAI 모더레이션 API를 통해 부적절한 내용을 확인합니다. 그런 다음 모델인 chain에서 처리되어 출력을 생성합니다. 만약 OpenAI 모더레이션 API에서 문제가 없는 것으로 확인되면, chain이 해당 입력 문장을 반복 출력할 것입니다.

 

ChatGPT의 Moderation API는 욕설 등 부적절한 내용이 있는지 여부를 판단하는 기능이 있습니다.

이번 예제는 이 Moderation API를 이용해서 부적절한 내용을 거르는 방법을 다루었습니다.

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/memory

 

Adding memory | 🦜️🔗 Langchain

This shows how to add memory to an arbitrary chain. Right now, you can use the memory classes but need to hook it up manually

python.langchain.com

 

This shows how to add memory to an arbitrary chain. Right now, you can use the memory classes but need to hook it up manually

 

임의의 체인에 메모리를 추가하는 방법을 보여줍니다. 지금은 메모리 클래스를 사용할 수 있지만 수동으로 연결해야 합니다.

 

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)

 

memory.load_memory_variables({})

 

    {'history': []}

 

이 코드는 LangChain에서 대화 기억 (memory)을 활용하는 방법을 설명합니다.

  1. ChatOpenAI 모델과 대화 기억 (memory) 객체 memory를 생성합니다. 이 모델과 대화 기억은 사용자와 상호 작용하고 대화 기록을 저장하고 검색하는 데 사용됩니다.
  2. ChatPromptTemplate을 사용하여 모델에 대한 프롬프트를 정의합니다. 여기에는 "system" 메시지와 사용자 입력을 나타내는 "human" 메시지가 포함됩니다. 중간에 MessagesPlaceholder가 있는데, 이것은 대화 기록 (history)를 삽입할 위치를 나타냅니다.
  3. 대화 기억 memory 객체를 초기화합니다. 이렇게 하면 대화 기록을 저장하고 검색할 수 있습니다.

대화 기억은 사용자와 모델 간의 상호 작용에서 발생하는 대화 기록을 저장하고 관리하는 데 사용됩니다. 이를 통해 모델은 이전 대화의 컨텍스트를 이해하고 이에 기반하여 응답을 생성할 수 있습니다.

 

 

chain = (
    RunnablePassthrough.assign(
        history=RunnableLambda(memory.load_memory_variables) | itemgetter("history")
    )
    | prompt
    | model
)

 

inputs = {"input": "hi im bob"}
response = chain.invoke(inputs)
response

 

    AIMessage(content='Hello Bob! How can I assist you today?', additional_kwargs={}, example=False)

 

이 코드는 LangChain에서 대화 기억 (memory)을 활용하여 모델에 입력을 전달하고 응답을 얻는 과정을 설명합니다.

  1. RunnablePassthrough.assign 함수를 사용하여 history 변수를 설정합니다. 이 변수는 대화 기억에서 이전 대화 기록을 로드하고 저장합니다. RunnableLambda(memory.load_memory_variables)를 사용하여 대화 기억을 로드하고 itemgetter("history")로 해당 기억에서 "history"를 추출합니다.
  2. 대화 기록을 이전 대화와 함께 모델에 전달하는 chain을 설정합니다. prompt는 사용자 입력을 받아들이는 템플릿입니다. model은 모델로, 이전 단계에서 설정한 history와 사용자 입력을 모델에 전달하는 역할을 합니다.
  3. inputs 딕셔너리를 생성하고 사용자 입력으로 "hi im bob"을 설정합니다.
  4. chain.invoke(inputs)를 호출하여 모델에 입력을 전달하고 응답을 얻습니다.

이렇게하면 대화 기록과 사용자 입력이 모델에 전달되고, 모델은 이전 대화 내용을 고려하여 적절한 응답을 생성합니다. 결과인 response는 모델의 응답을 나타냅니다.

 

 

memory.save_context(inputs, {"output": response.content})

 

memory.load_memory_variables({})

 

    {'history': [HumanMessage(content='hi im bob', additional_kwargs={}, example=False),
      AIMessage(content='Hello Bob! How can I assist you today?', additional_kwargs={}, example=False)]}

 

이 코드는 LangChain에서 대화 기억 (memory)을 저장하고 다시 로드하는 과정을 설명합니다.

  1. memory.save_context(inputs, {"output": response.content}): 이 코드는 memory 객체를 사용하여 대화 기억에 입력과 응답을 저장합니다. inputs는 사용자 입력을 포함하는 딕셔너리이며, response.content는 모델의 응답 내용을 나타냅니다. 따라서 이전 대화 기록에 현재 대화 내용을 추가로 저장하는 것입니다.
  2. memory.load_memory_variables({}): 이 코드는 이전에 저장된 대화 기억을 로드합니다. 빈 딕셔너리 {}를 사용하여 현재 대화와 관련된 모든 이전 기억을 로드합니다.

이렇게하면 대화 기록이 지속적으로 누적되고 관리되며, 다음 대화에서 이전 대화 내용을 활용할 수 있습니다.

 

 

inputs = {"input": "whats my name"}
response = chain.invoke(inputs)
response

 

    AIMessage(content='Your name is Bob.', additional_kwargs={}, example=False)

 

이 코드는 LangChain을 사용하여 모델에 질문을 제출하고 모델의 응답을 얻는 과정을 설명합니다.

  1. inputs 딕셔너리에 "input" 키를 사용하여 사용자의 입력을 정의합니다. 여기서 사용자는 "whats my name"이라는 질문을 입력했습니다.
  2. chain.invoke(inputs): chain은 ChatOpenAI 모델과 이전 대화 내용을 포함한 대화 prompt를 정의한 파트입니다. 이 코드는 inputs 딕셔너리를 사용하여 모델에 질문을 전달하고, 모델은 질문에 대한 응답을 생성합니다.
  3. response는 모델의 응답을 나타내는 객체입니다. 따라서 response 객체에는 모델의 응답 내용과 관련된 정보가 포함되어 있습니다.

이 코드를 실행하면 모델은 "whats my name"이라는 질문에 대한 응답을 생성하고, response 객체에 저장되어 반환됩니다. 이렇게 LangChain을 사용하여 모델에 대화를 제출하고 응답을 처리할 수 있습니다.

 

 

챗봇의 기능인 대화는 대화의 맥락이 유지 되어야 합니다. 즉 이전에 대화 했던 내용이 무엇인지 알아야 자연스럽게 대화기 이어 질 수 있습니다. 그러기 위해서는 이전의 질문과 대답을 ChatGPT가 알아야 합니다. ChatGPT가 기억하고 있지는 못합니다. API를 통해서 질문을 던질 때에는 현재의 질문에 이전에 했던 질문과 대답을 모두 같이 전달해 주어야 합니다.

LangChain의 Memory 기능은 이러한 작업을 간편하게 할 수 있도록 도와주는 것이네요.

 

 

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/embedding_router

 

Routing by semantic similarity | 🦜️🔗 Langchain

With LCEL you can easily add custom routing logic to your chain to dynamically determine the chain logic based on user input. All you need to do is define a function that given an input returns a Runnable.

python.langchain.com

 

 

Routing by semantic similarity

 

With LCEL you can easily add custom routing logic to your chain to dynamically determine the chain logic based on user input. All you need to do is define a function that given an input returns a Runnable.

 

LCEL을 사용하면 사용자 정의 라우팅 논리를 체인에 쉽게 추가하여 사용자 입력을 기반으로 체인 논리를 동적으로 결정할 수 있습니다. 당신이 해야 할 일은 주어진 입력이 Runnable을 반환하는 함수를 정의하는 것뿐입니다.

 

One especially useful technique is to use embeddings to route a query to the most relevant prompt. Here's a very simple example.

 

특히 유용한 기술 중 하나는 임베딩을 사용하여 쿼리를 가장 관련성이 높은 프롬프트로 라우팅하는 것입니다. 다음은 매우 간단한 예입니다.

 

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()
)

 

 

이 코드는 LangChain에서 사용자의 질문을 처리하고 적절한 모델 및 프롬프트를 선택하는 프로세스를 구현합니다.

  1. physics_template 및 math_template은 각각 물리학 교수와 수학자 역할을 하는 모델의 프롬프트 템플릿입니다. 이러한 템플릿은 해당 주제에 대한 역할과 동작 방식을 정의합니다.
  2. embeddings 객체는 OpenAIEmbeddings를 사용하여 프롬프트 템플릿을 텍스트 임베딩으로 변환합니다. 이러한 임베딩을 사용하여 사용자의 질문과 프롬프트 템플릿 간의 유사성을 계산할 수 있습니다.
  3. prompt_router 함수는 사용자의 입력 질문과 프롬프트 템플릿 간의 유사성을 계산하여 가장 유사한 템플릿을 선택합니다. 유사성은 코사인 유사도를 기반으로 계산됩니다. 그런 다음, 가장 유사한 프롬프트를 선택하고 해당 프롬프트를 반환합니다.
  4. chain은 모델 선택 및 프롬프트 라우팅을 처리하는 체인입니다. 사용자의 질문이 체인을 통과하면 prompt_router 함수를 사용하여 가장 유사한 프롬프트를 선택하고 해당 프롬프트를 사용하여 ChatOpenAI 모델을 호출합니다. 마지막으로, StrOutputParser를 사용하여 모델의 출력을 처리하고 반환합니다.

이 프로세스를 통해 사용자의 질문에 대해 물리학 또는 수학과 관련된 가장 적절한 역할 및 프롬프트를 선택하고, 해당 주제에 대한 답변을 생성합니다.

 

print(chain.invoke("What's a black hole"))

 

    Using PHYSICS
    A black hole is a region in space where gravity is extremely strong, so strong that nothing, not even light, can escape its gravitational pull. It is formed when a massive star collapses under its own gravity during a supernova explosion. The collapse causes an incredibly dense mass to be concentrated in a small volume, creating a gravitational field that is so intense that it warps space and time. Black holes have a boundary called the event horizon, which marks the point of no return for anything that gets too close. Beyond the event horizon, the gravitational pull is so strong that even light cannot escape, hence the name "black hole." While we have a good understanding of black holes, there is still much to learn, especially about what happens inside them.

 

print(chain.invoke("What's a path integral"))

 

    Using MATH
    Thank you for your kind words! I will do my best to break down the concept of a path integral for you.
    
    In mathematics and physics, a path integral is a mathematical tool used to calculate the probability amplitude or wave function of a particle or system of particles. It was introduced by Richard Feynman and is an integral over all possible paths that a particle can take to go from an initial state to a final state.
    
    To understand the concept better, let's consider an example. Suppose we have a particle moving from point A to point B in space. Classically, we would describe this particle's motion using a definite trajectory, but in quantum mechanics, particles can simultaneously take multiple paths from A to B.
    
    The path integral formalism considers all possible paths that the particle could take and assigns a probability amplitude to each path. These probability amplitudes are then added up, taking into account the interference effects between different paths.
    
    To calculate a path integral, we need to define an action, which is a mathematical function that describes the behavior of the system. The action is usually expressed in terms of the particle's position, velocity, and time.
    
    Once we have the action, we can write down the path integral as an integral over all possible paths. Each path is weighted by a factor determined by the action and the principle of least action, which states that a particle takes a path that minimizes the action.
    
    Mathematically, the path integral is expressed as:
    
    ∫ e^(iS/ħ) D[x(t)]
    
    Here, S is the action, ħ is the reduced Planck's constant, and D[x(t)] represents the integration over all possible paths x(t) of the particle.
    
    By evaluating this integral, we can obtain the probability amplitude for the particle to go from the initial state to the final state. The absolute square of this amplitude gives us the probability of finding the particle in a particular state.
    
    Path integrals have proven to be a powerful tool in various areas of physics, including quantum mechanics, quantum field theory, and statistical mechanics. They allow us to study complex systems and calculate probabilities that are difficult to obtain using other methods.
    
    I hope this explanation helps you understand the concept of a path integral. If you have any further questions, feel free to ask!

 

이 예제는 사전에 물리학자와 수학자 둘을 각각 설정해 놓고 질문을 그것을 OpenAI embedding을 통해서 임베딩 값을 받아 놓는 일 부터 시작합니다. 그 다음 질문을 던지면 그 질문도 임베딩 값을 받아서 이 질문이 수학과 관련이 있는지 아니면 물리학과 관련이 있는지를 판단하고 좀 더 가까운 쪽 설정을 가져와서 OpenAI에 던질 프롬프트를 만들어서 전달하고 거기에 대한 답을 받는 일을 합니다.

 

질문에 어떤 설정들을 세팅해서 프롬프트를 만들어야 할 때 유용하게 사용할 수 있는 기능인 것 같습니다.

로컬에서 따로 실행한 결과는 아래와 같습니다.

 

 

 

 

 

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/code_writing

 

Code writing | 🦜️🔗 Langchain

Example of how to use LCEL to write Python code.

python.langchain.com

 

 

Code writing

 

Example of how to use LCEL to write Python code.

 

LCEL을 사용하여 Python 코드를 작성하는 방법의 예입니다.

 

LCEL ( LangChain Expression Language )이란?

 

LCEL(LangChain Expression Language)은 체인을 쉽게 구성하는 선언적 방법입니다. 비동기, 일괄 처리 및 스트리밍 지원, 폴백, 병렬 처리 및 원활한 LangSmith 추적 통합과 같은 여러 가지 이점을 제공합니다. LCEL은 핵심 구성 요소 등과 상호 작용하는 데 사용됩니다.

from langchain.chat_models import ChatOpenAI
from langchain.prompts import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
)
from langchain.schema.output_parser import StrOutputParser
from langchain_experimental.utilities import PythonREPL

 

langchainlangchain_experimental 라이브러리에서 모듈을 가져오고 설정하는 부분입니다.

 

  1. langchain.chat_models에서 ChatOpenAI를 가져옵니다. 이 모듈은 OpenAI의 언어 모델과 상호 작용하는 기능을 제공합니다.
  2. langchain.prompts에서 ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate을 가져옵니다. 이러한 템플릿은 모델에 전달되는 프롬프트를 만들고 조작하는 데 사용됩니다.
  3. langchain.schema.output_parser에서 StrOutputParser를 가져옵니다. 이것은 모델의 출력을 텍스트 형식으로 파싱하는데 사용됩니다.
  4. langchain_experimental.utilities에서 PythonREPL을 가져옵니다. PythonREPL은 Python REPL(Read-Eval-Print Loop)과 상호 작용하고 실행하는데 사용될 수 있는 도구입니다.

이 코드 조각은 LangChain 및 관련 라이브러리에서 필요한 모듈을 가져와 설정하는 부분으로 보입니다.

 

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()

 

  1. template 변수에는 사용자의 문제를 해결하는 Python 코드를 생성하기 위한 템플릿이 정의되어 있습니다. 이 템플릿은 Python 코드 블록을 Markdown 형식으로 반환하도록 요청합니다.
  2. prompt 변수에는 ChatPromptTemplate.from_messages를 사용하여 시스템 메시지와 사용자의 입력 메시지를 결합하는 프롬프트가 설정됩니다. 시스템 메시지에는 사용자에게 어떤 종류의 응답을 제공해야 하는지에 대한 지침이 포함되어 있습니다. 사용자 메시지는 {input}으로 표시되며 사용자가 제공한 입력을 나타냅니다.
  3. model 변수에는 ChatOpenAI()가 설정됩니다. 이 모델은 LangChain 환경에서 OpenAI의 언어 모델과 상호 작용하는 데 사용됩니다.

이 코드는 사용자의 질문 또는 문제에 대한 Python 솔루션을 생성하는 일반적인 프롬프트 및 모델 설정을 제공합니다.

 

 

def _sanitize_output(text: str):
    _, after = text.split("```python")
    return after.split("```")[0]

 

_sanitize_output 함수는 주어진 텍스트에서 Python 코드 블록을 추출하고 반환하는 함수입니다.

 

  1. text 매개변수는 Python 코드 블록을 포함하고 있는 전체 텍스트를 나타냅니다.
  2. text.split("```python")은 text를 "```python" 문자열을 기준으로 분할하며, 결과적으로 분할된 텍스트를 두 부분으로 나눕니다. 첫 번째 부분은 Python 코드 블록 이전의 모든 내용을 포함하고, 두 번째 부분은 Python 코드 블록 이후의 내용을 포함합니다.
  3. after.Split("```")[0]은 두 번째 부분인 after를 "```" 문자열을 기준으로 다시 분할하며, 결과적으로 Python 코드 블록만 추출합니다. 이것이 함수가 반환하는 값이며, Python 코드 블록만 남게 됩니다.

이 _sanitize_output 함수는 Python 코드 블록을 추출하고 그것을 반환하는 데 사용될 수 있습니다.

 

chain = prompt | model | StrOutputParser() | _sanitize_output | PythonREPL().run

 

LangChain 환경에서 Python 코드를 실행하는 일련의 단계를 나타냅니다.

 

  1. prompt는 사용자의 입력 및 요청에 대한 템플릿을 정의하는 부분입니다. 사용자가 제공한 정보를 포함한 템플릿을 만들기 위해 사용됩니다.
  2. model은 ChatOpenAI 모델로, 사용자 입력과 템플릿을 기반으로 답변을 생성하는 역할을 합니다.
  3. StrOutputParser()는 모델의 출력을 문자열로 변환하는 역할을 합니다. 모델이 생성한 응답을 텍스트로 추출합니다.
  4. _sanitize_output 함수는 모델의 출력에서 Python 코드 블록을 추출하는데 사용됩니다. 이렇게 추출한 코드 블록은 나중에 실행할 수 있게 준비됩니다.
  5. PythonREPL().run은 추출한 Python 코드 블록을 실행합니다. 이것은 Python 코드를 실행할 수 있는 Python 환경을 만들고, 그 안에서 코드 블록을 실행합니다. 이를 통해 모델의 출력으로부터 추출된 Python 코드가 실행되며, 원하는 작업을 수행합니다.

따라서 이 코드는 사용자의 요청에 따라 모델이 생성한 Python 코드 블록을 실행하여 사용자에게 원하는 결과를 반환하는 프로세스를 나타냅니다.

 

chain.invoke({"input": "whats 2 plus 2"})
    Python REPL can execute arbitrary code. Use with caution.





    '4\n'

이 코드는 LangChain에서 사용자 입력을 처리하고 Python 코드를 실행하는 프로세스를 시작합니다. invoke 함수는 모델 체인을 호출하여 사용자의 입력을 처리하고 결과를 생성하는 역할을 합니다. 코드에서 {"input": "whats 2 plus 2"}는 사용자의 입력을 나타냅니다.

모델이 prompt에 따라 사용자 입력을 처리하고 Python 코드를 생성한 다음, 이 코드가 PythonREPL().run에 의해 실행됩니다. 이 프로세스를 통해 사용자 입력("whats 2 plus 2")에 대한 Python 코드가 실행되어 해당 Python 코드의 결과가 반환될 것입니다.

결과는 Python 코드 실행 결과이며, 이것은 사용자에게 반환되고 나중에 사용자가 요청한 작업과 관련된 정보를 포함할 수 있습니다.

 

 

로컬에서 실행할 때는 _sanitize_output() 안에 print() 문을 넣어서 파이썬 코드도 출력하도록 했습니다.

실행 결과를 보면 파이썬 코드가 나오거 그 다음에 정답이 나옵니다.

 

 

 

반응형

LC - Cookbook - Agents

2023. 11. 6. 11:46 | Posted by 솔웅


반응형

https://python.langchain.com/docs/expression_language/cookbook/agent

 

Agents | 🦜️🔗 Langchain

You can pass a Runnable into an agent.

python.langchain.com

 

Agents

 

You can pass a Runnable into an agent.

 

Runnable을 에이전트에 전달할 수 있습니다.

 

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 model
# This is pretty tied to the prompt
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 string to go in prompt
def convert_tools(tools):
    return "\n".join([f"{tool.name}: {tool.description}" for tool in tools])

 

 

이 코드는 LangChain 및 관련 모듈을 사용하여 구성된 작업 체인을 실행하는 데 사용되는 스크립트입니다. 주요 컴포넌트와 동작에 대한 설명은 다음과 같습니다:

  1. from langchain.agents import XMLAgent, tool, AgentExecutor, ChatAnthropic: XMLAgent와 ChatAnthropic을 포함한 LangChain 모듈과 관련 모듈을 가져옵니다.
  2. model = ChatAnthropic(model="claude-2"): ChatAnthropic 모델을 초기화하고 "claude-2" 모델을 사용하도록 설정합니다.
  3. @tool: 데코레이터를 사용하여 search 함수를 도구로 정의합니다. 이 도구는 query 매개변수를 입력으로 받아 "32 degrees"를 반환합니다. 도구는 현재 이벤트에 대한 정보를 검색하는 데 사용될 수 있습니다.
  4. tool_list = [search]: 도구 목록을 작성하고 search 도구를 포함합니다.
  5. prompt = XMLAgent.get_default_prompt(): XMLAgent 모듈에서 기본 프롬프트를 가져옵니다.
  6. convert_intermediate_steps(intermediate_steps): 중간 단계를 모델에 전달할 수 있는 문자열로 변환하는 함수를 정의합니다. 이 함수는 도구 작업 및 관찰을 로그로 결합한 문자열을 반환합니다.
  7. convert_tools(tools): 도구 목록을 문자열로 변환하는 함수를 정의합니다. 이 함수는 도구 이름과 설명을 포함하는 문자열을 반환합니다.

이 코드의 주요 목적은 도구를 사용하여 중간 작업을 수행하고, 그 결과를 로그로 저장한 후, 이 로그와 프롬프트를 사용하여 모델에 전달하여 최종 결과를 생성하는 것입니다. 이를 통해 ChatAnthropic 모델을 활용하여 다양한 작업을 수행하고 결과를 생성할 수 있습니다.

 

Building an agent from a runnable usually involves a few things:

 

실행 가능 파일에서 에이전트를 구축하려면 일반적으로 다음과 같은 몇 가지 사항이 필요합니다.

 

  1. Data processing for the intermediate steps. These need to represented in a way that the language model can recognize them. This should be pretty tightly coupled to the instructions in the prompt

    중간 단계를 위한 데이터 처리. 이는 언어 모델이 인식할 수 있는 방식으로 표현되어야 합니다. 이는 프롬프트의 지침과 매우 긴밀하게 연결되어야 합니다.

  2. The prompt itself  프롬프트 자체
  3. The model, complete with stop tokens if needed  필요한 경우 중지 토큰이 포함된 모델
  4. The output parser - should be in sync with how the prompt specifies things to be formatted.
    출력 파서 - 프롬프트가 형식화할 항목을 지정하는 방식과 동기화되어야 합니다.

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)
agent_executor.invoke({"question": "whats the weather in New york?"})
    
    
    > Entering new AgentExecutor chain...
     <tool>search</tool>
    <tool_input>weather in new york32 degrees
    
    <final_answer>The weather in New York is 32 degrees
    
    > Finished chain.





    {'question': 'whats the weather in New york?',
     'output': 'The weather in New York is 32 degrees'}

 

이 코드는 LangChain을 사용하여 에이전트를 생성하고 실행하는 일련의 단계를 나타냅니다. 코드의 주요 부분을 다음과 같이 설명합니다:

  1. agent 정의:
    • 에이전트를 구성하기 위해 두 개의 입력을 가집니다. 하나는 "question"이고 다른 하나는 "intermediate_steps"입니다.
    • "question" 입력은 질문을 추출하고, "intermediate_steps" 입력은 중간 작업 로그를 문자열로 변환합니다.
    • prompt.partial() 메서드를 사용하여 도구 목록을 문자열로 변환하고 프롬프트에 연결합니다. 이때 tools 매개변수에 도구 목록을 문자열로 변환한 결과를 전달합니다.
    • model.bind() 메서드를 사용하여 모델과 상호작용 중지 토큰을 정의하고, 종료 토큰이 "</tool_input>" 또는 "</final_answer>"인 경우 상호작용을 종료합니다.
    • 마지막으로 XMLAgent.get_default_output_parser()를 사용하여 출력 파서를 가져와 모델의 출력을 파싱합니다.
  2. agent_executor 생성:
    • agent와 tool_list를 사용하여 AgentExecutor를 초기화합니다. verbose 매개변수는 상세한 로깅을 활성화합니다.
  3. agent_executor.invoke() 호출:
    • agent_executor를 사용하여 실행할 입력을 제공합니다. 이 경우, "question" 키를 가진 입력을 전달하고, 모델에 의해 생성된 중간 작업 로그와 최종 응답을 반환합니다.

이 코드의 목적은 지정된 질문에 대한 응답을 생성하기 위해 에이전트 및 도구를 활용하는 것입니다. 중간 작업 로그와 최종 응답은 XML 형식으로 정의되며, XMLAgent를 사용하여 상호작용하는 중요한 구성 요소입니다.

 

 

 

 

 

 

 

 

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/sql_db

 

Querying a SQL DB | 🦜️🔗 Langchain

We can replicate our SQLDatabaseChain with Runnables.

python.langchain.com

 

Querying a SQL DB

 

We can replicate our SQLDatabaseChain with Runnables.

 

Runnables를 사용하여 SQLDatabaseChain을 복제할 수 있습니다.

 

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)

 

이 코드는 Langchain의 ChatPromptTemplate를 사용하여 SQL 쿼리 생성을 위한 템플릿을 정의하는 부분입니다. 이 템플릿은 다음과 같은 정보로 구성되어 있습니다:

  1. {schema}: 이 부분에는 테이블 스키마(schema)에 대한 정보가 들어가게 됩니다. 테이블 스키마는 데이터베이스 테이블의 구조를 설명하며, 사용자의 질문에 대한 SQL 쿼리를 작성하는 데 필요한 테이블 및 열(컬럼)의 정보를 포함합니다.
  2. {question}: 이 부분에는 사용자가 묻는 질문이 들어가게 됩니다. 사용자의 질문은 테이블 스키마에 대한 정보를 기반으로한 SQL 쿼리를 생성하기 위한 출발점 역할을 합니다.

이러한 템플릿을 사용하여 사용자가 제공한 질문과 관련된 SQL 쿼리를 생성하는 프로세스를 단순화할 수 있습니다.

 

from langchain.utilities import SQLDatabase

 

이 코드는 langchain 라이브러리에서 제공하는 SQLDatabase 클래스를 가져오는 부분입니다. SQLDatabase 클래스는 SQL 데이터베이스와 상호 작용하는 데 사용됩니다. 이 클래스를 사용하면 SQL 쿼리를 실행하고 데이터베이스에서 결과를 가져오는 등의 데이터베이스 작업을 쉽게 수행할 수 있습니다. 이것은 SQL 데이터베이스와의 연결 및 데이터 검색과 같은 작업을 수행하는 데 도움이 되는 유틸리티 클래스입니다.

 

We'll need the Chinook sample DB for this example. There's many places to download it from, e.g. https://database.guide/2-sample-databases-sqlite/

 

이 예에서는 Chinook 샘플 DB가 필요합니다. 다운로드할 수 있는 곳은 많습니다. https://database.guide/2-sample-databases-sqlite/

 

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()
)

 

이 코드는 SQL 데이터베이스와 상호 작용하고 사용자의 SQL 쿼리를 처리하는 일련의 작업을 수행하는 부분입니다.

  1. 먼저 SQLDatabase 클래스를 사용하여 SQLite 데이터베이스에 연결하는 db 객체를 생성합니다. 이 데이터베이스에는 Chinook.db라는 이름의 데이터베이스가 사용됩니다.
  2. get_schema 함수는 데이터베이스에서 테이블 스키마 정보를 가져오는 역할을 합니다. 이 함수는 입력으로 어떤 값도 받을 수 있지만 사용하지 않으며 데이터베이스의 테이블 정보를 반환합니다.
  3. run_query 함수는 SQL 쿼리를 실행하고 결과를 반환하는 역할을 합니다. 이 함수는 입력으로 SQL 쿼리를 받아 실행하고 실행 결과를 반환합니다.
  4. sql_response 변수는 SQL 데이터베이스와 모델을 연결하는 체인을 설정합니다. 이 체인은 다음과 같이 구성됩니다:
    • RunnablePassthrough.assign(schema=get_schema): 이 부분에서 get_schema 함수를 실행하여 데이터베이스의 테이블 스키마 정보를 schema 변수에 할당합니다.
    • prompt: SQL 쿼리 작성을 유도하는 프롬프트를 생성합니다.
    • model.bind(stop=["\nSQLResult:"]): ChatOpenAI 모델을 사용하며, 이 모델의 출력에서 SQL 결과를 구분하기 위한 정지 문자열("\nSQLResult:")을 설정합니다.
    • StrOutputParser(): 모델의 출력을 문자열로 파싱하여 반환합니다.

이로써, sql_response 체인은 사용자로부터 SQL 쿼리를 입력받아 데이터베이스에서 실행하고 결과를 출력하는 작업을 수행합니다.

 

sql_response.invoke({"question": "How many employees are there?"})

 

    'SELECT COUNT(*) FROM Employee'

 

이 코드는 sql_response 체인을 사용하여 SQL 쿼리를 실행하고 결과를 얻는 예시를 보여줍니다.

sql_response.invoke({"question": "How many employees are there?"})는 사용자의 질문을 포함하는 딕셔너리를 입력으로 전달합니다. "question" 키에는 사용자가 묻는 SQL 질문이 포함되어 있습니다. 이 경우, 사용자가 "How many employees are there?"라는 SQL 질문을 던졌다고 가정합니다.

체인은 다음과 같이 동작합니다:

  1. RunnablePassthrough.assign(schema=get_schema): get_schema 함수를 호출하여 데이터베이스의 테이블 스키마 정보를 가져옵니다. 이 정보는 schema 변수에 저장됩니다.
  2. prompt: SQL 질문 작성을 유도하는 프롬프트를 사용자에게 보여줍니다.
  3. 사용자가 SQL 질문을 작성하고 제출하면 이 질문은 모델에 전달되어 실행됩니다.
  4. model.bind(stop=["\nSQLResult:"]): 모델의 실행 결과를 반환하고, 결과 문자열에서 "\nSQLResult:" 문자열 이후의 내용은 무시됩니다. 따라서 SQL 결과만 추출됩니다.
  5. StrOutputParser(): 모델의 출력을 문자열로 파싱하여 반환합니다.

따라서 sql_response.invoke는 사용자의 SQL 질문에 대한 실행 결과를 반환하며, 해당 SQL 질문은 데이터베이스에서 실행된 결과를 포함합니다. 결과에는 "How many employees are there?" SQL 질문에 대한 답변이 포함되어 있을 것입니다.

 

 

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)

 

위의 소스 코드는 SQL 스키마, 질문, SQL 쿼리 및 SQL 응답을 기반으로 자연어 응답을 작성하는 데 사용되는 템플릿을 정의하고 있습니다.

템플릿은 다음과 같은 정보를 기반으로 작성됩니다:

  • {schema}: SQL 스키마 정보를 표시할 위치입니다.
  • {question}: 사용자의 질문을 표시할 위치입니다.
  • {query}: SQL 쿼리를 표시할 위치입니다.
  • {response}: SQL 응답 내용을 표시할 위치입니다.

따라서 이 템플릿은 주어진 SQL 스키마, 사용자의 질문, SQL 쿼리 및 SQL 응답을 바탕으로 자연어 응답을 작성하는 데 사용됩니다. 예를 들어, SQL 데이터베이스의 스키마와 사용자의 질문을 받아들이고, 해당 질문과 SQL 쿼리, 그리고 SQL 응답을 채워서 사용자에게 응답을 제공하는 데 활용될 수 있습니다.

 

full_chain = (
    RunnablePassthrough.assign(query=sql_response)
    | RunnablePassthrough.assign(
        schema=get_schema,
        response=lambda x: db.run(x["query"]),
    )
    | prompt_response
    | model
)

 

이 코드는 SQL 데이터베이스와 상호 작용하여 SQL 쿼리를 실행하고 결과를 기반으로 한 자연어 응답을 생성하기 위한 작업 체인을 설정하는 데 사용됩니다.

  1. RunnablePassthrough.assign(query=sql_response): 이 부분에서, 사용자로부터 SQL 쿼리를 생성하는 데 사용할 sql_response 템플릿을 가져오고, 이를 query라는 이름으로 할당합니다.
  2. RunnablePassthrough.assign(schema=get_schema, response=lambda x: db.run(x["query"])): 여기서는 SQL 스키마 정보를 가져오는 get_schema 함수를 설정하고, SQL 쿼리를 실행하고 그 결과를 가져오는 db.run(x["query"]) 함수를 설정합니다. 이러한 정보는 후속 단계에서 사용됩니다.
  3. prompt_response: 이 템플릿은 SQL 스키마, 사용자의 질문, SQL 쿼리 및 SQL 응답을 기반으로 자연어 응답을 생성하기 위해 사용됩니다. 이러한 정보를 채우고 사용자에게 반환할 자연어 응답을 작성합니다.
  4. model: 이 부분에서는 ChatOpenAI 모델을 사용하여 자연어 응답을 생성하고 반환합니다.

이런 식으로 전체 체인은 SQL 쿼리를 실행하고 SQL 스키마와 사용자의 질문, SQL 응답 정보와 함께 ChatOpenAI 모델을 사용하여 자연어 응답을 생성합니다.

 

full_chain.invoke({"question": "How many employees are there?"})

 

    AIMessage(content='There are 8 employees.', additional_kwargs={}, example=False)

 

 

 

 

반응형


반응형

https://python.langchain.com/docs/expression_language/cookbook/multiple_chains

 

Multiple chains | 🦜️🔗 Langchain

Runnables can easily be used to string together multiple Chains

python.langchain.com

 

Multiple chains

 

Runnables can easily be used to string together multiple Chains

 

Runnable은 여러 체인을 함께 묶는 데 쉽게 사용할 수 있습니다.

 

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()
)

chain2.invoke({"person": "obama", "language": "spanish"})

 

    'El país donde se encuentra la ciudad de Honolulu, donde nació Barack Obama, el 44º Presidente de los Estados Unidos, es Estados Unidos. Honolulu se encuentra en la isla de Oahu, en el estado de Hawái.'

 

이 코드는 LangChain에서 두 개의 프롬프트를 사용하여 정보를 검색하고, 이를 조합하여 원하는 질문에 대한 답변을 생성하는 방법을 보여줍니다.

  1. prompt1 및 chain1:
    • "what is the city {person} is from?"이라는 템플릿을 사용하여 prompt1을 생성합니다.
    • chain1은 prompt1을 사용하여 입력 데이터를 처리하고 모델을 사용하여 결과를 생성합니다.
  2. prompt2 및 chain2:
    • "what country is the city {city} in? respond in {language}"이라는 템플릿을 사용하여 prompt2를 생성합니다.
    • chain2는 prompt2와 chain1에서 생성된 chain1의 결과 (city)를 조합합니다.
    • chain2의 입력에는 "person"과 "language"가 있으며, "person"에 "obama" 및 "language"에 "Spanish" 값을 설정합니다.
    • 이렇게 조합된 입력을 사용하여 chain2는 모델을 통해 결과를 생성합니다.
  3. 결과:
    • chain2를 통해 생성된 결과에는 원하는 질문에 대한 답변이 포함되어 있습니다. "obama"라는 사람이 어떤 도시에서 왔는지에 대한 답변이 Spanish로 생성되었습니다.

이 코드는 여러 개의 프롬프트 및 연결된 체인을 사용하여 여러 단계를 거쳐 복잡한 질문에 대한 답변을 생성하는 방법을 보여줍니다.

 

 

language korean으로 했는데 제대로 잘 대답을 하네요.

 

from langchain.schema.runnable import RunnableMap, RunnablePassthrough

prompt1 = ChatPromptTemplate.from_template(
    "generate a {attribute} color. Return the name of the color and nothing else:"
)
prompt2 = ChatPromptTemplate.from_template(
    "what is a fruit of color: {color}. Return the name of the fruit and nothing else:"
)
prompt3 = ChatPromptTemplate.from_template(
    "what is a country with a flag that has the color: {color}. Return the name of the country and nothing else:"
)
prompt4 = ChatPromptTemplate.from_template(
    "What is the color of {fruit} and the flag of {country}?"
)

model_parser = model | StrOutputParser()

color_generator = (
    {"attribute": RunnablePassthrough()} | prompt1 | {"color": model_parser}
)
color_to_fruit = prompt2 | model_parser
color_to_country = prompt3 | model_parser
question_generator = (
    color_generator | {"fruit": color_to_fruit, "country": color_to_country} | prompt4
)

 

이 코드는 LangChain을 사용하여 색상, 과일, 나라 및 질문을 생성하는 방법을 보여줍니다.

  1. prompt1, prompt2, prompt3 및 prompt4:
    • 각각의 ChatPromptTemplate은 다양한 유형의 정보를 생성하기 위한 프롬프트를 정의합니다.
    • prompt1은 주어진 attribute에 해당하는 색상을 생성하도록 요청하며, 그 결과에서 색상의 이름을 반환합니다.
    • prompt2는 주어진 color에 해당하는 과일을 찾아서 과일의 이름을 반환합니다.
    • prompt3는 주어진 color와 일치하는 국기 색상을 가진 국가를 찾아 국가의 이름을 반환합니다.
    • prompt4는 주어진 과일 및 국가에 해당하는 색상 및 국기를 찾아 반환합니다.
  2. color_generator, color_to_fruit, color_to_country 및 question_generator:
    • color_generator은 "attribute" 값을 사용하여 prompt1을 호출하여 색상을 생성하고 결과를 "color"로 저장합니다.
    • color_to_fruit은 "color" 값을 사용하여 prompt2를 호출하여 해당 색상과 일치하는 과일을 찾아 반환합니다.
    • color_to_country은 "color" 값을 사용하여 prompt3를 호출하여 해당 색상과 일치하는 국가를 찾아 반환합니다.
    • question_generator는 color_generator, color_to_fruit, color_to_country의 결과를 사용하여 prompt4를 호출하여 원하는 질문을 생성합니다.

이 코드를 통해 서로 다른 프롬프트 및 정보를 조합하여 복잡한 정보를 생성하고, 그 결과를 단일 체인에서 관리할 수 있습니다.

 

question_generator.invoke("warm")

 

    ChatPromptValue(messages=[HumanMessage(content='What is the color of strawberry and the flag of China?', additional_kwargs={}, example=False)])

 

prompt = question_generator.invoke("warm")
model.invoke(prompt)

 

    AIMessage(content='The color of an apple is typically red or green. The flag of China is predominantly red with a large yellow star in the upper left corner and four smaller yellow stars surrounding it.', additional_kwargs={}, example=False)

 

이 코드는 question_generator를 사용하여 특정 정보에 대한 질문을 생성하고, 그 결과를 두 번 호출하는 예시입니다.

  1. question_generator.invoke("warm"):
    • question_generator를 사용하여 "warm"이라는 attribute를 사용한 색상에 대한 질문을 생성합니다.
    • 이 질문의 결과는 "prompt" 변수에 저장되지만 출력은 주어지지 않습니다.
  2. model.invoke(prompt):
    • model을 사용하여 "prompt"에 저장된 질문을 호출합니다.
    • 이 모델은 질문을 받고 적절한 응답을 반환합니다. 이 경우, "warm"에 해당하는 색상의 이름을 반환할 것입니다.

따라서 먼저 question_generator로 질문을 생성하고, 그 다음 model을 사용하여 해당 질문에 답을 얻게 됩니다.

 

 

로컬 jupyterlab에서 실행한 결과는 아래와 같습니다.

 

 

한국의 태극기를 대답으로 이끌어 내려고 white, black, red, blue를 입력값으로 집어 넣었는데 잘 안되네요. 

체코의 국기에는 하얀색, 파란색, 빨간색이 있고 검은색이 없는데 이게 답으로 나오기도 하네요.

 

분명히 해당 질문에는 태극기가 더 정답데 가까운데 ... ChatGPT가 아직 태극기는 잘 모르나 봅니다.

 

Branching and Merging

You may want the output of one component to be processed by 2 or more other components. RunnableMaps let you split or fork the chain so multiple components can process the input in parallel. Later, other components can join or merge the results to synthesize a final response. This type of chain creates a computation graph that looks like the following:

 

한 구성요소의 출력을 2개 이상의 다른 구성요소에서 처리하도록 할 수 있습니다. RunnableMaps를 사용하면 여러 구성 요소가 입력을 병렬로 처리할 수 있도록 체인을 분할하거나 분기할 수 있습니다. 나중에 다른 구성요소가 결과를 결합하거나 병합하여 최종 응답을 종합할 수 있습니다. 이 유형의 체인은 다음과 같은 계산 그래프를 생성합니다.

 

 

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}\n\nCons:\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
)

 

 

이 코드는 "planner"에서 argument를 생성하고, 해당 argument에 대한 "pros" 및 "cons"를 나열한 후, 최종 응답을 생성하는 프로세스를 구성하는 Langchain 체인을 나타냅니다.

  1. "planner":
    • "Generate an argument about: {input}"와 같은 템플릿을 사용하여 주어진 입력 "{input}"을 기반으로 인수(argument)를 생성합니다.
    • 그러면 이 결과는 "base_response" 변수에 저장됩니다.
  2. "arguments_for":
    • "{base_response}"에 대한 긍정적인 측면(positive aspects)을 나열하기 위한 질문을 생성하고 호출합니다.
  3. "arguments_against":
    • "{base_response}"에 대한 부정적인 측면(negative aspects)을 나열하기 위한 질문을 생성하고 호출합니다.
  4. "final_responder":
    • 여러 메시지로 구성된 템플릿을 사용하여 최종 응답을 생성합니다.
    • "original_response"는 "base_response"에서 가져옵니다.
    • 최종 응답에는 "original_response" 및 "arguments_for" 및 "arguments_against"에서 가져온 결과를 표시하는 부분이 포함됩니다.
  5. "chain":
    • "planner"에서 생성된 "base_response"를 기반으로 "arguments_for" 및 "arguments_against"에 대한 결과를 생성하고, 최종 응답을 생성하는 체인을 구성합니다.

이렇게 구성된 체인을 사용하면 주어진 주제에 대한 인수와 해당 인수에 대한 "pros" 및 "cons"를 생성하고, 이를 결합하여 최종적인 응답을 얻을 수 있습니다.

 

chain.invoke({"input": "scrum"})

 

    'While Scrum has its potential cons and challenges, many organizations have successfully embraced and implemented this project management framework to great effect. The cons mentioned above can be mitigated or overcome with proper training, support, and a commitment to continuous improvement. It is also important to note that not all cons may be applicable to every organization or project.\n\nFor example, while Scrum may be complex initially, with proper training and guidance, teams can quickly grasp the concepts and practices. The lack of predictability can be mitigated by implementing techniques such as velocity tracking and release planning. The limited documentation can be addressed by maintaining a balance between lightweight documentation and clear communication among team members. The dependency on team collaboration can be improved through effective communication channels and regular team-building activities.\n\nScrum can be scaled and adapted to larger projects by using frameworks like Scrum of Scrums or LeSS (Large Scale Scrum). Concerns about speed versus quality can be addressed by incorporating quality assurance practices, such as continuous integration and automated testing, into the Scrum process. Scope creep can be managed by having a well-defined and prioritized product backlog, and a strong product owner can be developed through training and mentorship.\n\nResistance to change can be overcome by providing proper education and communication to stakeholders and involving them in the decision-making process. Ultimately, the cons of Scrum can be seen as opportunities for growth and improvement, and with the right mindset and support, they can be effectively managed.\n\nIn conclusion, while Scrum may have its challenges and potential cons, the benefits and advantages it offers in terms of collaboration, flexibility, adaptability, transparency, and customer satisfaction make it a widely adopted and successful project management framework. With proper implementation and continuous improvement, organizations can leverage Scrum to drive innovation, efficiency, and project success.'

 

프로젝트 프로세스 관리인 scrum과 관련된 단점과 이를 극복하는 방법 그리고 장점 등이 잘 설명돼 있습니다.

 

로컬 jupyterlab에서 실행한 결과는 아래와 같습니다.

 

저는 질문을 AI로 했습니다.

 

 

 

답변을 번역하면 아래와 같습니다.

 

'AI를 둘러싼 타당한 우려와 비판이 있지만, 균형 잡힌 관점으로 접근하는 것이 중요합니다. 일자리 대체는 타당한 우려 사항이지만 역사를 통틀어 기술 발전으로 인해 새로운 일자리 기회가 창출되었습니다. 변화하는 직업 시장에 적응하기 위해 인력을 재교육하고 기술을 향상시키는 데 집중하는 것이 중요합니다.\n\nAI 시스템에서 인간적 접촉과 감성 지능이 부족하다는 점은 특히 개인적인 연결이 필요한 산업에서 타당한 점입니다. 그러나 AI는 인간의 능력을 보완하고 효율성을 향상시켜 인간이 창의성과 공감이 필요한 작업에 집중할 수 있도록 해줍니다.\n\n윤리적 고려 사항, 편견, 개인 정보 보호 위험은 적절한 규제와 감독을 통해 해결해야 하는 정당한 문제입니다. AI 개발의 투명성과 책임성은 이러한 문제를 완화하고 공정하고 편견 없는 의사 결정을 보장하는 데 도움이 될 수 있습니다.\n\n시스템 오류 및 보안 위험이 발생할 가능성이 있지만 AI 시스템의 견고성과 신뢰성을 보장하기 위해 적절한 조치를 취할 수 있습니다. 여기에는 사이버 보안에 대한 투자와 악의적인 공격으로부터 보호하기 위한 보호 조치 구현이 포함됩니다.\n\n특정 AI 알고리즘의 예측 불가능성과 투명성 부족은 설명 가능한 AI에 초점을 맞춘 연구 및 개발 노력을 통해 해결할 수 있습니다. 이를 통해 사용자는 AI 시스템의 의사 결정 프로세스를 이해하고 책임을 질 수 있습니다.\n\nAI 기술과 기회에 대한 공평한 접근을 보장하는 정책을 통해 사회적 영향과 불평등 악화 가능성을 적극적으로 해결해야 합니다. 여기에는 디지털 인프라에 투자하고 서비스가 부족한 커뮤니티에 교육 및 훈련을 제공하는 것이 포함됩니다.\n\n전반적으로 AI를 둘러싼 우려를 인식하고 잠재적인 위험을 완화하기 위해 노력하는 것이 중요합니다. 책임감 있는 개발, 규제 및 감독을 통해 AI는 사회에 미치는 부정적인 영향을 최소화하면서 상당한 이점과 발전을 가져올 수 있는 잠재력을 가지고 있습니다.'

 

 

 

 

 

 

 

 

 

 

반응형
이전 1 2 3 다음