追踪与可观测性#

AutoGen 内置了对追踪的支持 和可观测性,用于收集应用程序执行的全面记录。此功能对于调试、性能分析和理解应用程序流程非常有用。

此功能由 OpenTelemetry 库提供支持,这意味着您可以使用任何兼容 OpenTelemetry 的后端来收集和分析追踪数据。

AutoGen 遵循 OpenTelemetry 语义约定 进行代理和工具的追踪。它还遵循目前正在开发中的 GenAI 系统语义约定

设置#

首先,您需要安装 OpenTelemetry Python 包。您可以使用 pip 完成此操作

pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc opentelemetry-instrumentation-openai

安装 SDK 后,在 AutoGen 中设置追踪的最简单方法是

  1. 配置 OpenTelemetry 追踪器提供程序

  2. 设置导出器以将追踪数据发送到您的后端

  3. 将追踪器提供程序连接到 AutoGen 运行时

遥测后端#

要收集和查看追踪数据,您需要设置一个遥测后端。有几个开源选项可用,包括 Jaeger、Zipkin。对于本例,我们将使用 Jaeger 作为我们的遥测后端。

为了快速开始,您可以使用 Docker 在本地运行 Jaeger

docker run -d --name jaeger \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  jaegertracing/all-in-one:latest

此命令启动一个 Jaeger 实例,该实例监听端口 16686 用于 Jaeger UI,监听端口 4317 用于 OpenTelemetry 收集器。您可以通过 https://:16686 访问 Jaeger UI。

追踪 AgentChat 团队#

在以下部分中,我们将回顾如何使用 AutoGen GroupChat 团队启用追踪。AutoGen 运行时已经支持开放遥测(自动记录消息元数据)。首先,我们将创建一个追踪服务,用于检测 AutoGen 运行时。

from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# Set up telemetry span exporter.
otel_exporter = OTLPSpanExporter(endpoint="https://:4317", insecure=True)
span_processor = BatchSpanProcessor(otel_exporter)

# Set up telemetry trace provider.
tracer_provider = TracerProvider(resource=Resource({"service.name": "autogen-test-agentchat"}))
tracer_provider.add_span_processor(span_processor)
trace.set_tracer_provider(tracer_provider)

# Instrument the OpenAI Python library
OpenAIInstrumentor().instrument()

# we will get reference this tracer later using its service name
# tracer = trace.get_tracer("autogen-test-agentchat")
Overriding of current TracerProvider is not allowed
Attempting to instrument while already instrumented

创建 团队 的所有代码您应该已经很熟悉了。

注意

AgentChat 团队使用 AutoGen Core 的代理运行时运行。反过来,运行时已经进行了检测以进行日志记录,请参阅 核心遥测指南。要禁用代理运行时遥测,您可以在运行时构造函数中将 trace_provider 设置为 opentelemetry.trace.NoOpTracerProvider

此外,如果您无法访问运行时构造函数,例如,如果您正在使用 ComponentConfig,您可以将环境变量 AUTOGEN_DISABLE_RUNTIME_TRACING 设置为 true 以禁用代理运行时遥测。

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_core import SingleThreadedAgentRuntime
from autogen_ext.models.openai import OpenAIChatCompletionClient


def search_web_tool(query: str) -> str:
    if "2006-2007" in query:
        return """Here are the total points scored by Miami Heat players in the 2006-2007 season:
        Udonis Haslem: 844 points
        Dwayne Wade: 1397 points
        James Posey: 550 points
        ...
        """
    elif "2007-2008" in query:
        return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214."
    elif "2008-2009" in query:
        return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398."
    return "No data found."


def percentage_change_tool(start: float, end: float) -> float:
    return ((end - start) / start) * 100


async def main() -> None:
    model_client = OpenAIChatCompletionClient(model="gpt-4o")

    # Get a tracer with the default tracer provider.
    tracer = trace.get_tracer("tracing-autogen-agentchat")

    # Use the tracer to create a span for the main function.
    with tracer.start_as_current_span("run_team"):
        planning_agent = AssistantAgent(
            "PlanningAgent",
            description="An agent for planning tasks, this agent should be the first to engage when given a new task.",
            model_client=model_client,
            system_message="""
            You are a planning agent.
            Your job is to break down complex tasks into smaller, manageable subtasks.
            Your team members are:
                WebSearchAgent: Searches for information
                DataAnalystAgent: Performs calculations

            You only plan and delegate tasks - you do not execute them yourself.

            When assigning tasks, use this format:
            1. <agent> : <task>

            After all tasks are complete, summarize the findings and end with "TERMINATE".
            """,
        )

        web_search_agent = AssistantAgent(
            "WebSearchAgent",
            description="An agent for searching information on the web.",
            tools=[search_web_tool],
            model_client=model_client,
            system_message="""
            You are a web search agent.
            Your only tool is search_tool - use it to find information.
            You make only one search call at a time.
            Once you have the results, you never do calculations based on them.
            """,
        )

        data_analyst_agent = AssistantAgent(
            "DataAnalystAgent",
            description="An agent for performing calculations.",
            model_client=model_client,
            tools=[percentage_change_tool],
            system_message="""
            You are a data analyst.
            Given the tasks you have been assigned, you should analyze the data and provide results using the tools provided.
            If you have not seen the data, ask for it.
            """,
        )

        text_mention_termination = TextMentionTermination("TERMINATE")
        max_messages_termination = MaxMessageTermination(max_messages=25)
        termination = text_mention_termination | max_messages_termination

        selector_prompt = """Select an agent to perform task.

        {roles}

        Current conversation context:
        {history}

        Read the above conversation, then select an agent from {participants} to perform the next task.
        Make sure the planner agent has assigned tasks before other agents start working.
        Only select one agent.
        """

        task = "Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?"

        runtime = SingleThreadedAgentRuntime(
            tracer_provider=trace.NoOpTracerProvider(),  # Disable telemetry for runtime.
        )
        runtime.start()

        team = SelectorGroupChat(
            [planning_agent, web_search_agent, data_analyst_agent],
            model_client=model_client,
            termination_condition=termination,
            selector_prompt=selector_prompt,
            allow_repeated_speaker=True,
            runtime=runtime,
        )
        await Console(team.run_stream(task=task))

        await runtime.stop()

    await model_client.close()


# asyncio.run(main())
await main()
---------- TextMessage (user) ----------
Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?
---------- TextMessage (PlanningAgent) ----------
To find the information requested, we need to follow these steps:

1. Identify the Miami Heat player with the highest points during the 2006-2007 season.
2. Get the total rebounds for that player in both the 2007-2008 and 2008-2009 seasons.
3. Calculate the percentage change in total rebounds between these two seasons.

Here are the tasks assigned to achieve this:

1. WebSearchAgent: Find the Miami Heat player with the highest points during the 2006-2007 season.
2. WebSearchAgent: After identifying the player, find the total rebounds for that player in the 2007-2008 and 2008-2009 seasons.
3. DataAnalystAgent: Calculate the percentage change in the player's total rebounds between the 2007-2008 and 2008-2009 seasons.
---------- ToolCallRequestEvent (WebSearchAgent) ----------
[FunctionCall(id='call_hS8yod9l6CYUllDveUffp58e', arguments='{"query":"Miami Heat leading scorer 2006-2007 season"}', name='search_web_tool')]
---------- ToolCallExecutionEvent (WebSearchAgent) ----------
[FunctionExecutionResult(content='Here are the total points scored by Miami Heat players in the 2006-2007 season:\n        Udonis Haslem: 844 points\n        Dwayne Wade: 1397 points\n        James Posey: 550 points\n        ...\n        ', name='search_web_tool', call_id='call_hS8yod9l6CYUllDveUffp58e', is_error=False)]
---------- ToolCallSummaryMessage (WebSearchAgent) ----------
Here are the total points scored by Miami Heat players in the 2006-2007 season:
        Udonis Haslem: 844 points
        Dwayne Wade: 1397 points
        James Posey: 550 points
        ...
        
---------- ToolCallRequestEvent (WebSearchAgent) ----------
[FunctionCall(id='call_bUJxtpxUXFSxECDogye9WL0g', arguments='{"query":"Dwyane Wade total rebounds in 2007-2008 season"}', name='search_web_tool')]
---------- ToolCallExecutionEvent (WebSearchAgent) ----------
[FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.', name='search_web_tool', call_id='call_bUJxtpxUXFSxECDogye9WL0g', is_error=False)]
---------- ToolCallSummaryMessage (WebSearchAgent) ----------
The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.
---------- ToolCallRequestEvent (WebSearchAgent) ----------
[FunctionCall(id='call_pgYNSDhhyodtteot56FRktxp', arguments='{"query":"Dwyane Wade total rebounds in 2008-2009 season"}', name='search_web_tool')]
---------- ToolCallExecutionEvent (WebSearchAgent) ----------
[FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.', name='search_web_tool', call_id='call_pgYNSDhhyodtteot56FRktxp', is_error=False)]
---------- ToolCallSummaryMessage (WebSearchAgent) ----------
The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.
---------- ToolCallRequestEvent (DataAnalystAgent) ----------
[FunctionCall(id='call_A89acjYHlNDLzG09rVNJ0J6H', arguments='{"start":214,"end":398}', name='percentage_change_tool')]
---------- ToolCallExecutionEvent (DataAnalystAgent) ----------
[FunctionExecutionResult(content='85.98130841121495', name='percentage_change_tool', call_id='call_A89acjYHlNDLzG09rVNJ0J6H', is_error=False)]
---------- ToolCallSummaryMessage (DataAnalystAgent) ----------
85.98130841121495
---------- TextMessage (PlanningAgent) ----------
The Miami Heat player with the highest points during the 2006-2007 season was Dwyane Wade, who scored 1,397 points. 

The total rebounds for Dwyane Wade in the 2007-2008 season were 214, and in the 2008-2009 season, they were 398.

The percentage change in his total rebounds between these two seasons is approximately 86.0%.

TERMINATE

然后,您可以使用 Jaeger UI 查看从上述应用程序运行收集的追踪数据。

Jaeger UI