Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core[patch]: Deduplicate of callback handlers in merge_configs #22478

Merged
merged 6 commits into from
Jun 4, 2024

Conversation

eyurtsev
Copy link
Collaborator

@eyurtsev eyurtsev commented Jun 4, 2024

This PR adds deduplication of callback handlers in merge_configs.

Fix for this issue: #22227

The issue appears when the code is:

  1. running python >=3.11
  2. invokes a runnable from within a runnable
  3. binds the callbacks to the child runnable from the parent runnable using with_config

In this case, the same callbacks end up appearing twice: (1) the first time from with_config, (2) the second time with langchain automatically propagating them on behalf of the user.

Prior to this PR this will emit duplicate events:

@tool
async def get_items(question: str, callbacks: Callbacks):  # <--- Accept callbacks
    """Ask question"""
    template = ChatPromptTemplate.from_messages(
        [
            (
                "human",
                "'{question}"
            )
        ]
    )
    chain = template | chat_model.with_config(
        {
            "callbacks": callbacks,  # <-- Propagate callbacks
        }
    )
    return await chain.ainvoke({"question": question})

Prior to this PR this will work work correctly (no duplicate events):

@tool
async def get_items(question: str, callbacks: Callbacks):  # <--- Accept callbacks
    """Ask question"""
    template = ChatPromptTemplate.from_messages(
        [
            (
                "human",
                "'{question}"
            )
        ]
    )
    chain = template | chat_model
    return await chain.ainvoke({"question": question}, {"callbacks": callbacks})

This will also work (as long as the user is using python >= 3.11) -- as langchain will automatically propagate callbacks

@tool
async def get_items(question: str,):  
    """Ask question"""
    template = ChatPromptTemplate.from_messages(
        [
            (
                "human",
                "'{question}"
            )
        ]
    )
    chain = template | chat_model
    return await chain.ainvoke({"question": question})

Copy link

vercel bot commented Jun 4, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
langchain ⬜️ Ignored (Inspect) Visit Preview Jun 4, 2024 7:43pm

@eyurtsev
Copy link
Collaborator Author

eyurtsev commented Jun 4, 2024

Investigating source of issue for: #22227

@eyurtsev eyurtsev changed the title core[patch]: Add unit test for catching duplicate events core[patch]: Deduplicate of callback handlers in merge_configs Jun 4, 2024
@eyurtsev eyurtsev marked this pull request as ready for review June 4, 2024 19:53
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jun 4, 2024
@eyurtsev eyurtsev requested a review from nfcampos June 4, 2024 19:53
@dosubot dosubot bot added the 🤖:bug Related to a bug, vulnerability, unexpected error with an existing feature label Jun 4, 2024
@dosubot dosubot bot added the lgtm PR looks good. Use to confirm that a PR is ready for merging. label Jun 4, 2024
@eyurtsev eyurtsev merged commit 9120cf5 into master Jun 4, 2024
96 checks passed
@eyurtsev eyurtsev deleted the eugene/duplicate_events branch June 4, 2024 20:19
hinthornw pushed a commit that referenced this pull request Jun 20, 2024
This PR adds deduplication of callback handlers in merge_configs.

Fix for this issue:
#22227

The issue appears when the code is:

1) running python >=3.11
2) invokes a runnable from within a runnable
3) binds the callbacks to the child runnable from the parent runnable
using with_config

In this case, the same callbacks end up appearing twice: (1) the first
time from with_config, (2) the second time with langchain automatically
propagating them on behalf of the user.


Prior to this PR this will emit duplicate events:

```python
@tool
async def get_items(question: str, callbacks: Callbacks):  # <--- Accept callbacks
    """Ask question"""
    template = ChatPromptTemplate.from_messages(
        [
            (
                "human",
                "'{question}"
            )
        ]
    )
    chain = template | chat_model.with_config(
        {
            "callbacks": callbacks,  # <-- Propagate callbacks
        }
    )
    return await chain.ainvoke({"question": question})
```

Prior to this PR this will work work correctly (no duplicate events):

```python
@tool
async def get_items(question: str, callbacks: Callbacks):  # <--- Accept callbacks
    """Ask question"""
    template = ChatPromptTemplate.from_messages(
        [
            (
                "human",
                "'{question}"
            )
        ]
    )
    chain = template | chat_model
    return await chain.ainvoke({"question": question}, {"callbacks": callbacks})
```

This will also work (as long as the user is using python >= 3.11) -- as
langchain will automatically propagate callbacks

```python
@tool
async def get_items(question: str,):  
    """Ask question"""
    template = ChatPromptTemplate.from_messages(
        [
            (
                "human",
                "'{question}"
            )
        ]
    )
    chain = template | chat_model
    return await chain.ainvoke({"question": question})
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖:bug Related to a bug, vulnerability, unexpected error with an existing feature lgtm PR looks good. Use to confirm that a PR is ready for merging. size:M This PR changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants