langflow icon indicating copy to clipboard operation
langflow copied to clipboard

"Store Message" duplicates human messages, but only on API call (not Playground)

Open mieslep opened this issue 1 year ago • 2 comments

Bug Description

When I invoke a flow using "Store Messages" components, I am getting duplicate Human messages in the database, but only when I invoke via API call. The database messages are correct when I invoke from the Playground.

Reproduction

Reference flow https://raw.githubusercontent.com/AI-Phil/langflow-demo-flows/3b1afde4d590c5670e44417322dce580627353b1/flows/AstraMemoryChatbot.json

Note this flow has implemented fix for https://github.com/langflow-ai/langflow/pull/3024

when I invoke via Postman http://127.0.0.1:7861/api/v1/run/astra-memory-chatbot?stream=false

{"input_value": "what is my name?",
 "output_type": "chat",
 "input_type": "chat",
 "session_id": "1932f591-0a43-4546-8869-9f545503b5f3"
}

In both cases, there are two Langsmith entries: one for "OpenAI" and another for "Astra Memory Chatbot". I am not sure why there is not a single entry...

Versus when I invoke via the Playground, I have two different sorts of results.

  1. On the API invocation, the Human message is double-entered into the "Store Message"
  2. The order in Langsmith is different: on the Playground entry, the "OpenAI" is logged first, and the "Astra Memory Chatbot" is logged second. On the API call, the order is reversed.

Expected behavior

  1. There should be only one Human message in the database
  2. There should be only one Langsmith entry for the invocation (maybe a separate issue?)

Who can help?

No response

Operating System

Windows 11

Langflow Version

1.0.13

Python Version

3.10

Screenshot

No response

Flow File

https://raw.githubusercontent.com/AI-Phil/langflow-demo-flows/3b1afde4d590c5670e44417322dce580627353b1/flows/AstraMemoryChatbot.json

mieslep avatar Jul 29 '24 14:07 mieslep

The issue of duplicate Human messages being stored in the database when invoking a flow via an API call using the "Store Messages" component is due to the store_message function being called every time the build method is executed. This behavior might differ in the Playground due to different execution contexts or flow handling mechanisms that prevent the build method from being called multiple times.

In the Playground, the Chat Memory component retrieves message histories by session ID, and users can manage these memories directly. This includes editing or removing previous messages, which can prevent duplicates from being stored. The Playground's ability to manage and visualize memories directly allows for more controlled handling of message storage, which might not be the case when invoking flows via API calls.

Here is the relevant code snippet from StoreMessageComponent:

from langflow.custom import CustomComponent
from langflow.memory import get_messages, store_message
from langflow.schema.message import Message

class StoreMessageComponent(CustomComponent):
    display_name = "Store Message"
    description = "Stores a chat message."

    def build_config(self):
        return {
            "message": {"display_name": "Message"},
        }

    def build(
        self,
        message: Message,
    ) -> Message:
        store_message(message, flow_id=self.graph.flow_id)
        self.status = get_messages()

        return message

In this method, store_message(message, flow_id=self.graph.flow_id) is called, which stores the message in the database. If this method is invoked multiple times during an API call, it will result in duplicate messages being stored. The Playground's advanced settings and memory management features help prevent such issues by allowing users to control and manipulate message histories more effectively [1][2][3].

To continue talking to Dosu, mention @dosu.

dosubot[bot] avatar Jul 29 '24 14:07 dosubot[bot]

Hey @mieslep for the duplicated messages, I sent out a fix in #3062

For Langsmith, the duplicate comes from the fact that Langchain tracing is also enabled and the ChatOpenAI component is sending his own tracing. Since the same key LANGCHAIN_API_KEY is used both by langflow and langchain, they both think they need to trace. To demonstrate that, you can remove the variable LANGCHAIN_PROJECT. Default project for langflow is "Langflow", for langchain is "default". You will see the traces going in different projects.

This can't be avoided currently.

As follow up, I've created this issue for the wrong latencies #3064

nicoloboschi avatar Jul 30 '24 09:07 nicoloboschi