核心: `AsyncBaseTracer` 在 `on_tool_start` 中删除 `name` 和 `on_llm_error` 中删除 `response`, 与 `BaseTracer` 不同
作者: mrutunjay-kinagi创建于 2026年9月16日更新于 2026年9月17日
标签bugcoreexternal
22151 (introduced with_alisteners / AsyncRootListenersTracer)
Reproduction Steps / Example Code (Python)
import asyncio
from langchain_core.language_models import GenericFakeChatModel
from langchain_core.messages import AIMessageChunk
from langchain_core.outputs import ChatGenerationChunk
from langchain_core.tools import tool
from langchain_core.tracers.base import AsyncBaseTracer, BaseTracer
# --- 1. on_tool_start ignores `name` -----------------------------------------
@tool
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
# --- 2. on_llm_error ignores `response` --------------------------------------
class SyncTracer(BaseTracer):
def __init__(self) -> None:
super().__init__()
self.error_outputs = []
def _persist_run(self, run) -> None:
pass
def _on_llm_error(self, run) -> None:
self.error_outputs.append(run.outputs)
class AsyncTracer(AsyncBaseTracer):
def __init__(self) -> None:
super().__init__()
self.error_outputs = []
async def _persist_run(self, run) -> None:
pass
async def _on_llm_error(self, run) -> None:
self.error_outputs.append(run.outputs)
class FailsMidStream(GenericFakeChatModel):
def _stream(self, *args, **kwargs):
yield ChatGenerationChunk(message=AIMessageChunk(content="partial"))
raise ValueError("boom")
async def main() -> None:
names = []
add.with_listeners(on_end=lambda run: names.append(run.name)).invoke(
{"a": 1, "b": 2}, config={"run_name": "renamed"}
)
async def aon_end(run) -> None:
names.append(run.name)
await add.with_alisteners(on_end=aon_end).ainvoke(
{"a": 1, "b": 2}, config={"run_name": "renamed"}
)
print("run names (sync, async):", names)
内容来源: langchain-ai/langchain