mirror of
https://github.com/langchain-ai/langchain.git
synced 2026-10-06 18:05:25 +03:00
38 KiB
38 KiB
In [2]:
from langchain.callbacks import StdOutCallbackHandler
from langchain.chains import LLMChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
handler = StdOutCallbackHandler()
llm = OpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")
# First, let's explicitly set the StdOutCallbackHandler in `callbacks`
chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])
chain.run(number=2)
# Then, let's use the `verbose` flag to achieve the same result
chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
chain.run(number=2)
# Finally, let's use the request `callbacks` to achieve the same result
chain = LLMChain(llm=llm, prompt=prompt)
chain.run(number=2, callbacks=[handler])Out [2]:
[1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m1 + 2 = [0m [1m> Finished chain.[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m1 + 2 = [0m [1m> Finished chain.[0m [1m> Entering new LLMChain chain...[0m Prompt after formatting: [32;1m[1;3m1 + 2 = [0m [1m> Finished chain.[0m
'\n\n3'
In [2]:
from langchain.callbacks.base import BaseCallbackHandler
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage
class MyCustomHandler(BaseCallbackHandler):
def on_llm_new_token(self, token: str, **kwargs) -> None:
print(f"My custom handler, token: {token}")
# To enable streaming, we pass in `streaming=True` to the ChatModel constructor
# Additionally, we pass in a list with our custom handler
chat = ChatOpenAI(max_tokens=25, streaming=True, callbacks=[MyCustomHandler()])
chat([HumanMessage(content="Tell me a joke")])Out [2]:
My custom handler, token: My custom handler, token: Why My custom handler, token: did My custom handler, token: the My custom handler, token: tomato My custom handler, token: turn My custom handler, token: red My custom handler, token: ? My custom handler, token: Because My custom handler, token: it My custom handler, token: saw My custom handler, token: the My custom handler, token: salad My custom handler, token: dressing My custom handler, token: ! My custom handler, token:
AIMessage(content='Why did the tomato turn red? Because it saw the salad dressing!', additional_kwargs={})In [3]:
import asyncio
from typing import Any, Dict, List
from langchain.schema import LLMResult
from langchain.callbacks.base import AsyncCallbackHandler
class MyCustomSyncHandler(BaseCallbackHandler):
def on_llm_new_token(self, token: str, **kwargs) -> None:
print(f"Sync handler being called in a `thread_pool_executor`: token: {token}")
class MyCustomAsyncHandler(AsyncCallbackHandler):
"""Async callback handler that can be used to handle callbacks from langchain."""
async def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> None:
"""Run when chain starts running."""
print("zzzz....")
await asyncio.sleep(0.3)
class_name = serialized["name"]
print("Hi! I just woke up. Your llm is starting")
async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
"""Run when chain ends running."""
print("zzzz....")
await asyncio.sleep(0.3)
print("Hi! I just woke up. Your llm is ending")
# To enable streaming, we pass in `streaming=True` to the ChatModel constructor
# Additionally, we pass in a list with our custom handler
chat = ChatOpenAI(max_tokens=25, streaming=True, callbacks=[MyCustomSyncHandler(), MyCustomAsyncHandler()])
await chat.agenerate([[HumanMessage(content="Tell me a joke")]])Out [3]:
zzzz.... Hi! I just woke up. Your llm is starting Sync handler being called in a `thread_pool_executor`: token: Sync handler being called in a `thread_pool_executor`: token: Why Sync handler being called in a `thread_pool_executor`: token: don Sync handler being called in a `thread_pool_executor`: token: 't Sync handler being called in a `thread_pool_executor`: token: scientists Sync handler being called in a `thread_pool_executor`: token: trust Sync handler being called in a `thread_pool_executor`: token: atoms Sync handler being called in a `thread_pool_executor`: token: ? Sync handler being called in a `thread_pool_executor`: token: Because Sync handler being called in a `thread_pool_executor`: token: they Sync handler being called in a `thread_pool_executor`: token: make Sync handler being called in a `thread_pool_executor`: token: up Sync handler being called in a `thread_pool_executor`: token: everything Sync handler being called in a `thread_pool_executor`: token: ! Sync handler being called in a `thread_pool_executor`: token: zzzz.... Hi! I just woke up. Your llm is ending
LLMResult(generations=[[ChatGeneration(text="Why don't scientists trust atoms?\n\nBecause they make up everything!", generation_info=None, message=AIMessage(content="Why don't scientists trust atoms?\n\nBecause they make up everything!", additional_kwargs={}))]], llm_output={'token_usage': {}, 'model_name': 'gpt-3.5-turbo'})In [4]:
from typing import Dict, Union, Any, List
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.callbacks import tracing_enabled
from langchain.llms import OpenAI
# First, define custom callback handler implementations
class MyCustomHandlerOne(BaseCallbackHandler):
def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> Any:
print(f"on_llm_start {serialized['name']}")
def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:
print(f"on_new_token {token}")
def on_llm_error(
self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
) -> Any:
"""Run when LLM errors."""
def on_chain_start(
self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
) -> Any:
print(f"on_chain_start {serialized['name']}")
def on_tool_start(
self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
) -> Any:
print(f"on_tool_start {serialized['name']}")
def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
print(f"on_agent_action {action}")
class MyCustomHandlerTwo(BaseCallbackHandler):
def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> Any:
print(f"on_llm_start (I'm the second handler!!) {serialized['name']}")
# Instantiate the handlers
handler1 = MyCustomHandlerOne()
handler2 = MyCustomHandlerTwo()
# Setup the agent. Only the `llm` will issue callbacks for handler2
llm = OpenAI(temperature=0, streaming=True, callbacks=[handler2])
tools = load_tools(["llm-math"], llm=llm)
agent = initialize_agent(
tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)
# Callbacks for handler1 will be issued by every object involved in the
# Agent execution (llm, llmchain, tool, agent executor)
agent.run("What is 2 raised to the 0.235 power?", callbacks=[handler1])Out [4]:
on_chain_start AgentExecutor
on_chain_start LLMChain
on_llm_start OpenAI
on_llm_start (I'm the second handler!!) OpenAI
on_new_token I
on_new_token need
on_new_token to
on_new_token use
on_new_token a
on_new_token calculator
on_new_token to
on_new_token solve
on_new_token this
on_new_token .
on_new_token
Action
on_new_token :
on_new_token Calculator
on_new_token
Action
on_new_token Input
on_new_token :
on_new_token 2
on_new_token ^
on_new_token 0
on_new_token .
on_new_token 235
on_new_token
on_agent_action AgentAction(tool='Calculator', tool_input='2^0.235', log=' I need to use a calculator to solve this.\nAction: Calculator\nAction Input: 2^0.235')
on_tool_start Calculator
on_chain_start LLMMathChain
on_chain_start LLMChain
on_llm_start OpenAI
on_llm_start (I'm the second handler!!) OpenAI
on_new_token
on_new_token ```text
on_new_token
on_new_token 2
on_new_token **
on_new_token 0
on_new_token .
on_new_token 235
on_new_token
on_new_token ```
on_new_token ...
on_new_token num
on_new_token expr
on_new_token .
on_new_token evaluate
on_new_token ("
on_new_token 2
on_new_token **
on_new_token 0
on_new_token .
on_new_token 235
on_new_token ")
on_new_token ...
on_new_token
on_new_token
on_chain_start LLMChain
on_llm_start OpenAI
on_llm_start (I'm the second handler!!) OpenAI
on_new_token I
on_new_token now
on_new_token know
on_new_token the
on_new_token final
on_new_token answer
on_new_token .
on_new_token
Final
on_new_token Answer
on_new_token :
on_new_token 1
on_new_token .
on_new_token 17
on_new_token 690
on_new_token 67
on_new_token 372
on_new_token 187
on_new_token 674
on_new_token
'1.1769067372187674'
In [5]:
import os
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.callbacks import tracing_enabled
from langchain.llms import OpenAI
# To run the code, make sure to set OPENAI_API_KEY and SERPAPI_API_KEY
llm = OpenAI(temperature=0)
tools = load_tools(["llm-math", "serpapi"], llm=llm)
agent = initialize_agent(
tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
questions = [
"Who won the US Open men's final in 2019? What is his age raised to the 0.334 power?",
"Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?",
"Who won the most recent formula 1 grand prix? What is their age raised to the 0.23 power?",
"Who won the US Open women's final in 2019? What is her age raised to the 0.34 power?",
"Who is Beyonce's husband? What is his age raised to the 0.19 power?",
]In [6]:
os.environ["LANGCHAIN_TRACING"] = "true"
# Both of the agent runs will be traced because the environment variable is set
agent.run(questions[0])
with tracing_enabled() as session:
assert session
agent.run(questions[1])[1m> Entering new AgentExecutor chain...[0m [32;1m[1;3m I need to find out who won the US Open men's final in 2019 and then calculate his age raised to the 0.334 power. Action: Search Action Input: "US Open men's final 2019 winner"[0m Observation: [33;1m[1;3mRafael Nadal defeated Daniil Medvedev in the final, 7–5, 6–3, 5–7, 4–6, 6–4 to win the men's singles tennis title at the 2019 US Open. It was his fourth US ...[0m Thought:[32;1m[1;3m I need to find out the age of the winner Action: Search Action Input: "Rafael Nadal age"[0m Observation: [33;1m[1;3m36 years[0m Thought:[32;1m[1;3m I need to calculate the age raised to the 0.334 power Action: Calculator Action Input: 36^0.334[0m Observation: [36;1m[1;3mAnswer: 3.3098250249682484[0m Thought:[32;1m[1;3m I now know the final answer Final Answer: Rafael Nadal, aged 36, won the US Open men's final in 2019 and his age raised to the 0.334 power is 3.3098250249682484.[0m [1m> Finished chain.[0m [1m> Entering new AgentExecutor chain...[0m [32;1m[1;3m I need to find out who Olivia Wilde's boyfriend is and then calculate his age raised to the 0.23 power. Action: Search Action Input: "Olivia Wilde boyfriend"[0m Observation: [33;1m[1;3mSudeikis and Wilde's relationship ended in November 2020. Wilde was publicly served with court documents regarding child custody while she was presenting Don't Worry Darling at CinemaCon 2022. In January 2021, Wilde began dating singer Harry Styles after meeting during the filming of Don't Worry Darling.[0m Thought:[32;1m[1;3m I need to find out Harry Styles' age. Action: Search Action Input: "Harry Styles age"[0m Observation: [33;1m[1;3m29 years[0m Thought:[32;1m[1;3m I need to calculate 29 raised to the 0.23 power. Action: Calculator Action Input: 29^0.23[0m Observation: [36;1m[1;3mAnswer: 2.169459462491557[0m Thought:[32;1m[1;3m I now know the final answer. Final Answer: Harry Styles is Olivia Wilde's boyfriend and his current age raised to the 0.23 power is 2.169459462491557.[0m [1m> Finished chain.[0m
In [10]:
# Now, we unset the environment variable and use a context manager.
if "LANGCHAIN_TRACING" in os.environ:
del os.environ["LANGCHAIN_TRACING"]
# here, we are writing traces to "my_test_session"
with tracing_enabled("my_test_session") as session:
assert session
agent.run(questions[0]) # this should be traced
agent.run(questions[1]) # this should not be tracedOut [10]:
[1m> Entering new AgentExecutor chain...[0m [32;1m[1;3m I need to find out who won the US Open men's final in 2019 and then calculate his age raised to the 0.334 power. Action: Search Action Input: "US Open men's final 2019 winner"[0m Observation: [33;1m[1;3mRafael Nadal defeated Daniil Medvedev in the final, 7–5, 6–3, 5–7, 4–6, 6–4 to win the men's singles tennis title at the 2019 US Open. It was his fourth US ...[0m Thought:[32;1m[1;3m I need to find out the age of the winner Action: Search Action Input: "Rafael Nadal age"[0m Observation: [33;1m[1;3m36 years[0m Thought:[32;1m[1;3m I need to calculate the age raised to the 0.334 power Action: Calculator Action Input: 36^0.334[0m Observation: [36;1m[1;3mAnswer: 3.3098250249682484[0m Thought:[32;1m[1;3m I now know the final answer Final Answer: Rafael Nadal, aged 36, won the US Open men's final in 2019 and his age raised to the 0.334 power is 3.3098250249682484.[0m [1m> Finished chain.[0m [1m> Entering new AgentExecutor chain...[0m [32;1m[1;3m I need to find out who Olivia Wilde's boyfriend is and then calculate his age raised to the 0.23 power. Action: Search Action Input: "Olivia Wilde boyfriend"[0m Observation: [33;1m[1;3mSudeikis and Wilde's relationship ended in November 2020. Wilde was publicly served with court documents regarding child custody while she was presenting Don't Worry Darling at CinemaCon 2022. In January 2021, Wilde began dating singer Harry Styles after meeting during the filming of Don't Worry Darling.[0m Thought:[32;1m[1;3m I need to find out Harry Styles' age. Action: Search Action Input: "Harry Styles age"[0m Observation: [33;1m[1;3m29 years[0m Thought:[32;1m[1;3m I need to calculate 29 raised to the 0.23 power. Action: Calculator Action Input: 29^0.23[0m Observation: [36;1m[1;3mAnswer: 2.169459462491557[0m Thought:[32;1m[1;3m I now know the final answer. Final Answer: Harry Styles is Olivia Wilde's boyfriend and his current age raised to the 0.23 power is 2.169459462491557.[0m [1m> Finished chain.[0m
"Harry Styles is Olivia Wilde's boyfriend and his current age raised to the 0.23 power is 2.169459462491557."
In [8]:
# The context manager is concurrency safe:
if "LANGCHAIN_TRACING" in os.environ:
del os.environ["LANGCHAIN_TRACING"]
# start a background task
task = asyncio.create_task(agent.arun(questions[0])) # this should not be traced
with tracing_enabled() as session:
assert session
tasks = [agent.arun(q) for q in questions[1:3]] # these should be traced
await asyncio.gather(*tasks)
await taskOut [8]:
[1m> Entering new AgentExecutor chain...[0m [1m> Entering new AgentExecutor chain...[0m [1m> Entering new AgentExecutor chain...[0m [32;1m[1;3m I need to find out who won the grand prix and then calculate their age raised to the 0.23 power. Action: Search Action Input: "Formula 1 Grand Prix Winner"[0m[32;1m[1;3m I need to find out who won the US Open men's final in 2019 and then calculate his age raised to the 0.334 power. Action: Search Action Input: "US Open men's final 2019 winner"[0m[33;1m[1;3mRafael Nadal defeated Daniil Medvedev in the final, 7–5, 6–3, 5–7, 4–6, 6–4 to win the men's singles tennis title at the 2019 US Open. It was his fourth US ...[0m[32;1m[1;3m I need to find out who Olivia Wilde's boyfriend is and then calculate his age raised to the 0.23 power. Action: Search Action Input: "Olivia Wilde boyfriend"[0m[33;1m[1;3mSudeikis and Wilde's relationship ended in November 2020. Wilde was publicly served with court documents regarding child custody while she was presenting Don't Worry Darling at CinemaCon 2022. In January 2021, Wilde began dating singer Harry Styles after meeting during the filming of Don't Worry Darling.[0m[33;1m[1;3mLewis Hamilton has won 103 Grands Prix during his career. He won 21 races with McLaren and has won 82 with Mercedes. Lewis Hamilton holds the record for the ...[0m[32;1m[1;3m I need to find out the age of the winner Action: Search Action Input: "Rafael Nadal age"[0m[33;1m[1;3m36 years[0m[32;1m[1;3m I need to find out Harry Styles' age. Action: Search Action Input: "Harry Styles age"[0m[32;1m[1;3m I need to find out Lewis Hamilton's age Action: Search Action Input: "Lewis Hamilton Age"[0m[33;1m[1;3m29 years[0m[32;1m[1;3m I need to calculate the age raised to the 0.334 power Action: Calculator Action Input: 36^0.334[0m[32;1m[1;3m I need to calculate 29 raised to the 0.23 power. Action: Calculator Action Input: 29^0.23[0m[36;1m[1;3mAnswer: 3.3098250249682484[0m[36;1m[1;3mAnswer: 2.169459462491557[0m[33;1m[1;3m38 years[0m [1m> Finished chain.[0m [1m> Finished chain.[0m [32;1m[1;3m I now need to calculate 38 raised to the 0.23 power Action: Calculator Action Input: 38^0.23[0m[36;1m[1;3mAnswer: 2.3086081644669734[0m [1m> Finished chain.[0m
"Rafael Nadal, aged 36, won the US Open men's final in 2019 and his age raised to the 0.334 power is 3.3098250249682484."
In [9]:
from langchain.callbacks import get_openai_callback
llm = OpenAI(temperature=0)
with get_openai_callback() as cb:
llm("What is the square root of 4?")
total_tokens = cb.total_tokens
assert total_tokens > 0
with get_openai_callback() as cb:
llm("What is the square root of 4?")
llm("What is the square root of 4?")
assert cb.total_tokens == total_tokens * 2
# You can kick off concurrent runs from within the context manager
with get_openai_callback() as cb:
await asyncio.gather(
*[llm.agenerate(["What is the square root of 4?"]) for _ in range(3)]
)
assert cb.total_tokens == total_tokens * 3
# The context manager is concurrency safe
task = asyncio.create_task(llm.agenerate(["What is the square root of 4?"]))
with get_openai_callback() as cb:
await llm.agenerate(["What is the square root of 4?"])
await task
assert cb.total_tokens == total_tokens