ai icon indicating copy to clipboard operation
ai copied to clipboard

Langchain handlers being use case specific

Open aranlucas opened this issue 2 years ago • 8 comments

Context:

  • https://github.com/vercel-labs/ai/pull/201
  • https://github.com/vercel-labs/ai/issues/97
  • https://github.com/vercel-labs/ai/issues/63
  • https://github.com/hwchase17/langchainjs/issues/1740

It seems that having 1 set of handlers does not work for all usecases https://github.com/vercel-labs/ai/blob/main/packages/core/streams/langchain-stream.ts

The proposal in https://github.com/vercel-labs/ai/pull/201 is to add a callBackManager for each use-case (Agent, Chain, LLM)

This could be represented as:

  // Different handlers for llm, agents, chains
  const { stream, llmHandlers, chainHandlers } = LangChainStream()
 
  // Do not pass handlers here
  const llm = new ChatOpenAI({
    streaming: true,
  })
 
  // Pass handlers here instead
  llm
    .call(
      (messages as Message[]).map((m) =>
        m.role == "user"
          ? new HumanChatMessage(m.content)
          : new AIChatMessage(m.content)
      ),
      [llmHandlers]
    )
    .catch(console.error);
 
  return new StreamingTextResponse(stream)

Otherwise the different handlers can break each other.

What do you think about this solution?

aranlucas avatar Jun 22 '23 19:06 aranlucas

This is maybe a little bit more complicated than I expected.

They do seem to have a generic callback handler that works across Agent/LLM/Chain/Whatever https://github.com/hwchase17/langchainjs/tree/main/langchain/src/callbacks/handlers

However, they need to keep some internal state to figure out if everything is done. This becomes more clear when you use verbose: true

[chain/start] [1:chain:ConversationalRetrievalQAChain] Entering Chain run with input: {
[chain/start] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain] Entering Chain run with input: {
[chain/start] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain] Entering Chain run with input: {
[llm/start] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain > 4:llm:ChatOpenAI] Entering LLM run with input: {
[llm/end] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain > 4:llm:ChatOpenAI] [1.35s] Exiting LLM run with output: {
Error in handler Handler, handleChainEnd: TypeError: The stream (in closed state) is not in the writable state and cannot be closed      
[chain/end] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain] [1.36s] Exiting Chain run with output: {
Error in handler Handler, handleChainEnd: TypeError: The stream (in closed state) is not in the writable state and cannot be closed      
[chain/end] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain] [1.36s] Exiting Chain run with output: {
[chain/end] [1:chain:ConversationalRetrievalQAChain] [2.48s] Exiting Chain run with output: {

Even in this case, the stream is closed too early because a chain can spawn a chain.

This would probably mean create a custom CallBackManager that keeps track of runs, and only closes writer when all of them are done.

I'm currently thinking of it as "valid parenthesis" but they might not be guaranteed to finish sequentially.

aranlucas avatar Jun 22 '23 20:06 aranlucas

The first minor change to fix this is definitely updating the docs/demo to use request callback handlers on the call as mentioned by https://js.langchain.com/docs/production/callbacks/#when-do-you-want-to-use-each-of-these

When do you want to use each of these?
* Constructor callbacks are most useful for use cases such as logging, monitoring, etc., which are not specific to a single request, but rather to the entire chain. For example, if you want to log all the requests made to an LLMChain, you would pass a handler to the constructor.
* Request callbacks are most useful for use cases such as streaming, where you want to stream the output of a single request to a specific websocket connection, or other similar use cases. For example, if you want to stream the output of a single request to a websocket, you would pass a handler to the call() method

aranlucas avatar Jun 22 '23 20:06 aranlucas

https://github.com/hwchase17/langchainjs/blob/main/langchain/src/callbacks/handlers/tracer.ts looks useful.

If runMap is empty, close the writer()

aranlucas avatar Jun 22 '23 20:06 aranlucas

Definitely not ready for primetime but a good demonstration

import { BaseTracer } from "langchain/callbacks";
import { type Run } from "langchain/dist/callbacks";

export class StreamingCallback extends BaseTracer {
  name = "streaming_callback";

  writer = null;

  constructor(props: any) {
    super(props);

    this.writer = props.stream.writable.getWriter();
  }

  protected async persistRun(run: Run): Promise<void> {
    console.log(this.runMap.size);
  }

  async handleLLMNewToken(token: string): Promise<void> {
    await this.writer.ready;
    await this.writer.write(token);
  }

  protected async _endTrace(run: Run): Promise<void> {
    const parentRun =
      run.parent_run_id !== undefined && this.runMap.get(run.parent_run_id);
    if (parentRun) {
      parentRun.child_execution_order = Math.max(
        parentRun.child_execution_order,
        run.child_execution_order
      );
    } else {
      await this.persistRun(run);
    }
    this.runMap.delete(run.id);
    if (this.runMap.size === 0) {
      await this.writer.ready;
      await this.writer.close();
    }
  }
}

Usage:

 const stream = new TransformStream();

  const model = new ChatOpenAI({
    temperature: 0,
    streaming: true,
  });

  const nonStreamingModel = new ChatOpenAI();

  const chain = ConversationalRetrievalQAChain.fromLLM(
    model,
    vectorStore.asRetriever(1),
    {
      // verbose: true,
      memory: new BufferMemory({
        memoryKey: "chat_history",
        inputKey: "question",
        outputKey: "text",
      }),
      questionGeneratorChainOptions: {
        llm: nonStreamingModel,
        template: templates.qaPrompt,
      },
    }
  );

  const question = messages[messages.length - 1].content;

  chain
    .call(
      {
        question,
        chat_history: pastMessages,
      },
      [new StreamingCallback({ stream })]
    )
    .catch(console.error);

  return new StreamingTextResponse(
    stream.readable.pipeThrough(createCallbacksTransformer({}))
  );

logs out

3
2
1
0

Meaning that runMap has completed all runs, safe to close the stream

aranlucas avatar Jun 22 '23 21:06 aranlucas

Well, working backwards from that example I think I found the minimum needed to get handlers working for all cases.

I created this class to replicate the library functionality

import { createCallbacksTransformer, type AIStreamCallbacks } from "ai";

export function LangChainStream(callbacks?: AIStreamCallbacks) {
  const stream = new TransformStream();
  const writer = stream.writable.getWriter();

  const runMap = new Set();

  const endStream = async () => {
    if (runMap.size === 0) {
      await writer.ready;
      await writer.close();
    }
    console.log(runMap);
  };

  return {
    stream: stream.readable.pipeThrough(createCallbacksTransformer(callbacks)),
    handlers: {
      handleLLMStart: async (_llm, _prompts: string[], runId: string) => {
        runMap.add(runId);
      },
      handleLLMNewToken: async (token: string) => {
        await writer.ready;
        await writer.write(token);
      },
      handleLLMError: async (e: any, runId: string) => {
        runMap.delete(runId);
        await writer.ready;
        await writer.abort(e);
      },
      handleLLMEnd: async (_output, runId: string) => {
        runMap.delete(runId);
        await endStream();
      },
      handleChatModelStart: async (_llm, _messages, runId: string) => {
        runMap.add(runId);
      },
      handleChatModelEnd: async (_output, runId: string) => {
        runMap.delete(runId);

        await endStream();
      },
      handleChainStart: async (_chain, _inputs, runId: string) => {
        runMap.add(runId);
      },
      handleChainError: async (e, runId: string) => {
        runMap.delete(runId);

        await writer.ready;
        await writer.abort(e);
      },
      handleChainEnd: async (_outputs, runId: string) => {
        runMap.delete(runId);

        await endStream();
      },
      handleToolStart: async (_tool, _input: string, runId: string) => {
        runMap.add(runId);
      },
      handleToolError: async (error: Error, runId: string) => {
        runMap.delete(runId);

        await writer.ready;
        await writer.abort(error);
      },
      handleToolEnd: async (_output: string, runId: string) => {
        runMap.delete(runId);

        await endStream();
      },
      handleAgentAction: async (_action, runId: string) => {
        runMap.add(runId);
      },
      handleAgentEnd: async (_output, runId: string) => {
        runMap.delete(runId);

        await endStream();
      },
    },
  };
}

Outputs (for my use case)

[chain/start] [1:chain:ConversationalRetrievalQAChain] Entering Chain run with input: {
[chain/start] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain] Entering Chain run with input: {
[chain/start] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain] Entering Chain run with input: { 
[llm/start] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain > 4:llm:ChatOpenAI] Entering LLM run with input: {
  "messages": [
Set(3) {
  '87d40ad6-e3cd-410e-8f11-7c6992f5de1a',
  '551605d2-eab5-4064-b797-ede20eeeeb40',
  '3ae203ad-57c3-41fc-9eff-f45c1c2695ee'
}
[llm/end] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain > 4:llm:ChatOpenAI] [644ms] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "Hello! How can I assist you today?",
        "message": {
          "type": "ai",
          "data": {
            "content": "Hello! How can I assist you today?",
            "additional_kwargs": {}
          }
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "completionTokens": 0,
      "promptTokens": 0,
      "totalTokens": 0
    }
  }
}
Set(2) {
  '87d40ad6-e3cd-410e-8f11-7c6992f5de1a',
  '551605d2-eab5-4064-b797-ede20eeeeb40'
}
[chain/end] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain > 3:chain:LLMChain] [656ms] Exiting Chain run with output: {
  "text": "Hello! How can I assist you today?"
}
Set(1) { '87d40ad6-e3cd-410e-8f11-7c6992f5de1a' }
[chain/end] [1:chain:ConversationalRetrievalQAChain > 2:chain:StuffDocumentsChain] [663ms] Exiting Chain run with output: {
  "text": "Hello! How can I assist you today?"
}
[chain/end] [1:chain:ConversationalRetrievalQAChain] [1.83s] Exiting Chain run with output: {
Set(0) {}

No more early stream termination :)

Let me know if this works and I can send a PR.

aranlucas avatar Jun 22 '23 22:06 aranlucas

Tested with sequential chain (Example https://github.com/vercel-labs/ai/issues/63 https://js.langchain.com/docs/modules/chains/sequential_chain)

const { stream, handlers } = LangChainStream();
  // This is an LLMChain to write a synopsis given a title of a play.
  const llm = new OpenAI({ temperature: 0, streaming: true });
  const template = `You are a playwright. Given the title of play, it is your job to write a synopsis for that title.
 
  Title: {title}
  Playwright: This is a synopsis for the above play:`;
  const promptTemplate = new PromptTemplate({
    template,
    inputVariables: ["title"],
  });
  const synopsisChain = new LLMChain({ llm, prompt: promptTemplate });

  // This is an LLMChain to write a review of a play given a synopsis.
  const reviewLLM = new OpenAI({ temperature: 0 , streaming: true });
  const reviewTemplate = `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.
 
  Play Synopsis:
  {synopsis}
  Review from a New York Times play critic of the above play:`;

  const reviewPromptTemplate = new PromptTemplate({
    template: reviewTemplate,
    inputVariables: ["synopsis"],
  });
  const reviewChain = new LLMChain({
    llm: reviewLLM,
    prompt: reviewPromptTemplate,
  });

  const overallChain = new SimpleSequentialChain({
    chains: [synopsisChain, reviewChain],
    verbose: true,
  });

  void overallChain.run("Tragedy at sunset on the beach", [handlers]);

  return new StreamingTextResponse(stream);
[chain/start] [1:chain:SimpleSequentialChain] Entering Chain run with input: {
  "input": "Tragedy at sunset on the beach"
}
[chain/start] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] Entering Chain run with input: {        
  "title": "Tragedy at sunset on the beach"
}
[llm/start] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:OpenAI] Entering LLM run with input: {
  "prompts": [
    "You are a playwright. Given the title of play, it is your job to write a synopsis for that title.\n \n  Title: Tragedy at sunset on the beach\n  Playwright: This is a synopsis for the above play:"
  ]
}
[llm/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:OpenAI] [4.40s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to spend the rest of their lives together. \n\nHowever, tragedy strikes when Jack is killed in a car accident. Jill is left devastated and unable to cope with the loss of her beloved. She spirals into a deep depression and begins to lose hope. \n\nJust when all seems lost, Jill discovers that Jack had left her a letter before his death. In the letter, he tells her that he will always love her and that she should never give up hope. With this newfound strength, Jill is able to find the courage to move on with her life and find happiness again. \n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It is a story of hope and courage in the face of tragedy. It is a story of finding strength in the darkest of times and of never giving up.",
        "generationInfo": {
          "finishReason": "stop",
          "logprobs": null
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {}
  }
}
[chain/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] [4.41s] Exiting Chain run with output: {
  "text": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to spend the rest of their lives together. \n\nHowever, tragedy strikes when Jack is killed in a car accident. Jill is left devastated and unable to cope with the loss of her beloved. She spirals into a deep depression and begins to lose hope. \n\nJust when all seems lost, Jill discovers that Jack had left her a letter before his death. In the letter, he tells her that he will always love her and that she should never give up hope. With this newfound strength, Jill is able to find the courage to move on with her life and find happiness again. \n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It is a story of hope and courage in the face of tragedy. It is a story of finding strength in the darkest of times and of never giving up."
}
[chain/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] Entering Chain run with input: {        
  "synopsis": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to spend the rest of their lives together. \n\nHowever, tragedy strikes when Jack is killed in a car accident. Jill is left devastated and unable to cope with the loss of her beloved. She spirals into a deep depression and begins to lose hope. \n\nJust when all seems lost, Jill discovers that Jack had left her a letter before his death. In the letter, he tells her that he will always love her and that she should never give up hope. With this newfound strength, Jill is able to find the courage to move on with her life and find happiness again. \n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption.kes when Jack is killed in a car accident. Jill is left devastated and unable to cope with the loss of her beloved. She spirals into a deep depression and begins to lose hope. \n\nJust when all seems lost, Jill discovers that Jack had left her a letter before his death. In the letter, he tells her that he will always love her and that she should never give up hope. With this newfound strength, Jill is able to find the courage to move on with her life and find happiness again. \n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It is a story of hope and courage in the face of tragedy. It is a story of finding strength in the darkest of times and of never giving up.\n  Review from a New York Times play critic of the above play:"
  ]
}
[llm/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:OpenAI] [3.90s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The story follows two young lovers, Jack and Jill, who meet on a beach at sunset and quickly fall in love. However, tragedy strikes when Jack is killed in a car accident, leaving Jill devastated and unable to cope with the loss. \n\nThe play is beautifully written and the actors do an excellent job of conveying the emotions of the characters. The audience is taken on an emotional journey as they watch Jill struggle to cope with her loss and find the courage to move on with her life. The play is a testament to the power of love and hope in the face of tragedy. \n\nOverall, Tragedy at Sunset on the Beach is an emotionally powerful and moving play. It is a story of love, loss, and redemption that will leave the audience with a sense of hope and courage. Highly recommended.",
        "generationInfo": {
          "finishReason": "stop",
          "logprobs": null
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "completionTokens": 191,
      "promptTokens": 277,
      "totalTokens": 468
    }
  }
}
[chain/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] [3.90s] Exiting Chain run with output: {  
  "text": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The story follows two young lovers, Jack and Jill, who meet on a beach at sunset and quickly fall in love. However, tragedy strikes when Jack is killed in a car accident, leaving Jill devastated and unable to cope with the loss. \n\nThe play is beautifully written and the actors do an excellent job of conveying the emotions of the characters. The audience is taken on an emotional journey as they watch Jill struggle to cope with her loss and find the courage to move on with her life. The play is a testament to the power of love and hope in the face of tragedy. \n\nOverall, Tragedy at Sunset on the Beach is an emotionally powerful and moving play. It is a story of love, loss, and redemption that will leave the audience with a sense of hope and courage. Highly recommended."
}
[chain/end] [1:chain:SimpleSequentialChain] [8.33s] Exiting Chain run with output: {
  "output": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The story follows two young lovers, Jack and Jill, who meet on a beach at sunset and quickly fall in love. However, tragedy strikes when Jack is killed in a car accident, leaving Jill devastated and unable to cope with the loss. \n\nThe play is beautifully written and the actors do an excellent job of conveying the emotions of the characters. The audience is taken on an emotional journey as they watch Jill struggle to cope with her loss and find the courage to move on with her life. The play is a testament to the power of love and hope in the face of tragedy. \n\nOverall, Tragedy at Sunset on the Beach is an emotionally powerful and moving play. It is a story of love, loss, and redemption that will leave the audience with a sense of hope and courage. Highly recommended."
}
[WARN] Importing from 'langchain' is deprecated. See https://js.langchain.com/docs/getting-started/install#updating-from-0052 for upgrade instructions.
[chain/start] [1:chain:SimpleSequentialChain] Entering Chain run with input: {
  "input": "Tragedy at sunset on the beach"
}
[chain/start] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] Entering Chain run with input: {        
  "title": "Tragedy at sunset on the beach"
}
[llm/start] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:OpenAI] Entering LLM run with input: {
  "prompts": [
    "You are a playwright. Given the title of play, it is your job to write a synopsis for that title.\n \n  Title: Tragedy at sunset on the beach\n  Playwright: This is a synopsis for the above play:"
  ]
}
[llm/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:OpenAI] [3.72s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love.",
        "generationInfo": {
          "finishReason": "stop",
          "logprobs": null
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {}
  }
}
[chain/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] [3.74s] Exiting Chain run with output: {  
  "text": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love."
}
[chain/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] Entering Chain run with input: {        
  "synopsis": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love."
}
[llm/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:OpenAI] Entering LLM run with input: {
  "prompts": [
    "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.\n \n  Play Synopsis:\n  \n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love.\n  Review from a New York Times play critic of the above play:"
  ]
}
[llm/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:OpenAI] [3.63s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The play follows the story of two young lovers, Jack and Jill, whose plans for a future together are tragically cut short when Jack is killed in a car accident. \n\nThe play is beautifully written and the performances are outstanding. The actors bring a depth of emotion to their characters that is both heartbreaking and inspiring. The story is full of unexpected twists and turns, and the audience is taken on an emotional rollercoaster as Jill struggles to come to terms with her loss. \n\nThe play is ultimately a story of hope and resilience, and it is sure to leave audiences with a newfound appreciation for life and love. Tragedy at Sunset on the Beach is a must-see for anyone looking for an emotionally charged and thought-provoking experience.",
        "generationInfo": {
          "finishReason": "stop",
          "logprobs": null
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "completionTokens": 177,
      "promptTokens": 247,
      "totalTokens": 424
    }
  }
}
[chain/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] [3.63s] Exiting Chain run with output: {
  "text": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The play follows the story of two young lovers, Jack and Jill, whose plans for a future together are tragically cut short when Jack is killed in a car accident. \n\nThe play is beautifully written and the performances are outstanding. The actors bring a depth of emotion to their characters that is both heartbreaking and inspiring. The story is full of unexpected twists and turns, and the audience is taken on an emotional rollercoaster as Jill struggles to come to terms with her loss. \n\nThe play is ultimately a story of hope and resilience, and it is sure to leave audiences with a newfound appreciation for life and love. Tragedy at Sunset on the Beach is a must-see for anyone looking for an emotionally charged and thought-provoking experience."
}
[chain/end] [1:chain:SimpleSequentialChain] [7.39s] Exiting Chain run with output: {
  "output": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The play follows the story of two young lovers, Jack and Jill, whose plans for a future together are tragically cut short when Jack is killed in a car accident. \n\nThe play is beautifully written and the performances are outstanding. The actors bring a depth of emotion to their characters that is both heartbreaking and inspiring. The story is full of unexpected twists and turns, and the audience is taken on an : {
  "prompts": [
    "You are a playwright. Given the title of play, it is your job to write a synopsis for that title.\n \n  Title: Tragedy at sunset on the beach\n  Playwright: This is a synopsis for the above play:"
  ]
}
Set(2) {
  '0878c1b9-d010-4663-bb13-957882d0e4d6',
  '4fd43a27-a33f-4e5b-9378-15c6ca60e7ed'
}
[llm/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:OpenAI] [3.57s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love.",
        "generationInfo": {
          "finishReason": "stop",
          "logprobs": null
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {}
  }
}
Set(1) { '0878c1b9-d010-4663-bb13-957882d0e4d6' }
[chain/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] [3.59s] Exiting Chain run with output: {  
  "text": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love."
}
[chain/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] Entering Chain run with input: {        
  "synopsis": "\n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love."
}
[llm/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:OpenAI] Entering LLM run with input: {
  "prompts": [
    "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.\n \n  Play Synopsis:\n  \n\nTragedy at Sunset on the Beach is a story of love, loss, and redemption. It follows the story of two young lovers, Jack and Jill, who meet on a beach at sunset. They quickly fall in love and plan to marry, but their plans are shattered when Jack is tragically killed in a car accident. \n\nJill is left devastated and struggles to cope with her grief. She finds solace in the company of her best friend, Mary, who helps her to come to terms with her loss. As Jill begins to heal, she discovers that Jack had left her a letter before his death, which reveals a secret that changes everything. \n\nJill must now make a difficult decision: to accept the truth and move on with her life, or to remain in the past and never find closure. In the end, Jill finds the strength to forgive and move forward, and discovers a newfound appreciation for life and love.\n  Review from a New York Times play critic of the above play:"
  ]
}
Set(2) {
  '0878c1b9-d010-4663-bb13-957882d0e4d6',
  '1046eecb-b022-41c8-852b-b880bc1acba7'
}
[llm/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:OpenAI] [3.39s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The play follows the story of two young lovers, Jack and Jill, whose plans for a future together are tragically cut short when Jack is killed in a car accident. \n\nThe play is beautifully written and the performances are outstanding. The actors bring a depth of emotion to their characters that is both heartbreaking and inspiring. The story is full of unexpected twists and turns, and the audience is taken on an emotional rollercoaster as Jill struggles to come to terms with her loss. \n\nThe play is ultimately a story of hope and resilience, and it is sure to leave audiences with a newfound appreciation for life and love. Tragedy at Sunset on the Beach is a must-see for anyone looking for an emotionally charged and thought-provoking experience.",
        "generationInfo": {
          "finishReason": "stop",
          "logprobs": null
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "completionTokens": 177,
      "promptTokens": 247,
      "totalTokens": 424
    }
  }
}
Set(1) { '0878c1b9-d010-4663-bb13-957882d0e4d6' }
[chain/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] [3.39s] Exiting Chain run with output: {  
  "text": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The play follows the story of two young lovers, Jack and Jill, whose plans for a future together are tragically cut short when Jack is killed in a car accident. \n\nThe play is beautifully written and the performances are outstanding. The actors bring a depth of emotion to their characters that is both heartbreaking and inspiring. The story is full of unexpected twists and turns, and the audience is taken on an emotional rollercoaster as Jill struggles to come to terms with her loss. \n\nThe play is ultimately a story of hope and resilience, and it is sure to leave audiences with a newfound appreciation for life and love. Tragedy at Sunset on the Beach is a must-see for anyone looking for an emotionally charged and thought-provoking experience."
}
[chain/end] [1:chain:SimpleSequentialChain] [6.99s] Exiting Chain run with output: {
  "output": "\n\nTragedy at Sunset on the Beach is a powerful and moving story of love, loss, and redemption. The play follows the story of two young lovers, Jack and Jill, whose plans for a future together are tragically cut short when Jack is killed in a car accident. \n\nThe play is beautifully written and the performances are outstanding. The actors bring a depth of emotion to their characters that is both heartbreaking and inspiring. The story is full of unexpected twists and turns, and the audience is taken on an emotional rollercoaster as Jill struggles to come to terms with her loss. \n\nThe play is ultimately a story of hope and resilience, and it is sure to leave audiences with a newfound appreciation for life and love. Tragedy at Sunset on the Beach is a must-see for anyone looking for an emotionally charged and thought-provoking experience."
}
Set(0) {}

Worked like a charm

aranlucas avatar Jun 22 '23 23:06 aranlucas

This is awesome, @aranlucas... thanks for all your time on this issue and finding the best solution that fits all use cases! :pray:

gadicc avatar Jun 23 '23 06:06 gadicc

It was a fun ride to understanding internals of LangChain :)

aranlucas avatar Jun 23 '23 20:06 aranlucas

hey @aranlucas, my bad for missing this issue. From my understanding this can be closed as of #201?

MaxLeiter avatar Jul 21 '23 23:07 MaxLeiter

Good to close :)

aranlucas avatar Jul 21 '23 23:07 aranlucas