尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PostHog Trace Clustering 打标 Agent:基于 LangGraph ReAct 模式的 LLM 聚类标签自动生成

PostHog Trace Clustering 打标 Agent:基于 LangGraph ReAct 模式的 LLM 聚类标签自动生成 PostHog Trace Clustering 打标 Agent基于 LangGraph ReAct 模式的 LLM 聚类标签自动生成【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthogPostHog 的 AI Observability 模块会对海量 LLM trace 做周期性聚类分析而聚类产物若只有Cluster 0 / Cluster 1这样的编号对用户几乎没有可读价值。位于 labeling_agent 的 Cluster Labeling Agent 就是为了解决这个问题它是一个基于 LangGraphcreate_react_agent预构建模式实现的自主 Agent通过一组读取聚类结构 / 写入标签的工具反复探索聚类数据最终为每个聚类生成标题和描述。读完全文你可以掌握如何用create_react_agentInjectedState搭建一个状态可读写、带递归上限与兜底逻辑的最小化 ReAct Agent并理解它在 Temporal 工作流中的调用链与容错设计。一、它在整个 trace 聚类流水线中的位置打标 Agent 并非孤立运行而是 trace_clustering 这套 Temporal 工作流中的一个环节。工作流的核心参数都定义在 constants.py 中WORKFLOW_NAME llma-trace-clustering由llma-trace-clustering-coordinator协调器按每日 Schedule 为各团队派发子工作流默认回看窗口DEFAULT_LOOKBACK_DAYS 7、最多采样DEFAULT_MAX_SAMPLES 1500条 trace聚类算法默认 HDBSCANNOISE_CLUSTER_ID -1约定噪声/离群簇的 ID聚类结果随后交给 LLM 打标活动。打标活动的入口在 labeling.py 的generate_cluster_labels()它先把聚类结果items、labels、预计算的每条 trace 的x/y/距离/rank元数据、质心 2D 坐标组装成 Agent 能消费的cluster_data再通过fetch_item_summaries()从 ClickHouse 拉取每条 trace 的 LLM 摘要标题、流程图、要点、备注最后调用run_labeling_agent()。也就是说Agent 拿到的输入是聚类几何信息 每条 trace 的自然语言摘要两类数据输出则是dict[int, ClusterLabel]——聚类 ID 到标题/描述的映射最终被序列化进$ai_trace_clusters事件供前端散点图和 MCP 消费。二、架构create_react_agent 预构建 ReAct 循环README 给出的架构图清晰地表达了 Agent 的拓扑这是标准的 ReActReasoning Acting循环Agent 节点调用 LLM 决定下一步做什么若产生 tool calls 则路由到 Tool 节点执行工具结果回填消息历史后回到 Agent 节点继续推理直到 LLM 不再调用工具或触达递归上限而结束。选择预构建create_react_agent而非手写StateGraph的直接收益也是 README 列出的第一条设计决策是它替你处理了四件事LLM 与工具的绑定调用、经ToolNode的工具执行、tools_condition在 Agent 与工具节点之间的路由、以及消息历史管理。入口函数run_labeling_agent()在 graph.py 中核心装配只有三步agent create_react_agent( modelllm, # get_labeling_llm() 构造的 ChatOpenAI 客户端 toolsLABELING_TOOLS, # tools.py 中定义的 8 个 tool promptCLUSTER_LABELING_SYSTEM_PROMPT, # prompts.py 的系统提示词 state_schemaClusterLabelingState, ) result agent.invoke( initial_state, {recursion_limit: LABELING_AGENT_RECURSION_LIMIT, callbacks: callbacks}, )从源码看还有两个值得注意的细节LLM 客户端的构造llm来自 clustering_agent/init.py 的get_labeling_llm()。该共享模块为 trace/evaluation 两级打标 Agent 复用同一套机制打标属于每日批量任务因此白名单模型会请求 OpenAI 的 flex 服务层级以换取折扣 tokenflex 调用失败时自动降级到 standard 层级重试LABELING_FLEX_CALL_TIMEOUT 120s/LABELING_STANDARD_CALL_TIMEOUT 240s并且它强制AI 功能只在 Cloud 或本地 DEBUG 构建中运行的守卫。可观测性每次invoke都通过 llm_endpoint 的build_langchain_callbacks()挂载 LangChain callbacks以ai_productaio_clustering上报并带上team_id、analysis_level、clustering_run_id、clustering_job_id等属性使 Agent 自身的运行也能被 PostHog 观测到。三、文件结构与状态 Schema模块文件组织如下labeling_agent/ ├── __init__.py # 导出 run_labeling_agent ├── graph.py # create_react_agent 装配与 run_labeling_agent 入口 ├── state.py # ClusterLabelingState 等 TypedDict 与辅助类型 ├── tools.py # 基于 InjectedState 模式的工具定义 ├── prompts.py # CLUSTER_LABELING_SYSTEM_PROMPT └── README.md状态定义在 state.py是理解整个 Agent 的关键class ClusterLabelingState(TypedDict): # LangGraph 消息历史create_react_agent 必需用 add_messages reducer 追加 messages: Annotated[list, add_messages] # 步数追踪create_react_agent 依赖它配合 recursion_limit 工作 remaining_steps: RemainingSteps # 输入数据启动时写入工具经 InjectedState 只读 team_id: int cluster_data: dict[int, ClusterTraceData] # cluster_id - 聚类信息含 traces all_trace_summaries: dict[str, TraceSummary] # trace_id - 完整摘要 # 工作状态工具经 InjectedState 直接读写 current_labels: dict[int, ClusterLabel | None] # cluster_id - 标签或 None其中cluster_data的每个值是ClusterTraceDatacluster_id、size、质心坐标centroid_x/centroid_yUMAP 降维后的 2D 位置以及traces——每个 trace 的trace_id、rank1 最接近质心、最具代表性、distance_to_centroid和 2D 坐标。all_trace_summaries的每个值是TraceSummary定义在 models.pytitle、flow_diagram、bullets、interesting_notes、trace_timestamp。这里有一处 README 与源码的差异需要说明README 中的 State 示例只列了五个字段而从源码看实际的ClusterLabelingState还包含一个remaining_steps: RemainingSteps字段state.py#L42-L43这是新版create_react_agent用于配合recursion_limit的内部步数追踪字段属于必需但无需业务关心的框架字段。四、工具集InjectedState 模式与 8 个工具所有工具定义在 tools.py统一采用 LangGraph 的InjectedState模式from langgraph.prebuilt import InjectedState tool def set_cluster_label( state: Annotated[dict, InjectedState], # 框架注入LLM 不可见、不可填 cluster_id: int, title: str, description: str, ) - str: Set or update the label for a specific cluster. state[current_labels][cluster_id] ClusterLabel(titletitle, descriptiondescription) return fLabel set for cluster {cluster_id}: {title}InjectedState的作用是让state参数由框架自动注入、不出现在暴露给 LLM 的工具 schema 里工具直接读写图状态既免去了独立执行函数 手工工具分发的样板代码README 设计决策第 2 条又避免 LLM 伪造或截断大体积的状态数据。8 个工具按读和写两类组织工具用途关键参数源码实现要点get_clusters_overview全部聚类的 ID、规模、质心位置一览无遍历cluster_data按cluster_id排序输出 JSONget_all_clusters_with_sample_titles一次调用拿到所有聚类 样本标题Phase 1 首选titles_per_cluster默认 10按rank排序取前 N 条标题get_cluster_trace_titles扫描单个聚类内 trace 的标题与元数据cluster_id、limit默认 30返回trace_id/title/rank/distance_to_centroid/x/y按 rank 截断get_trace_details获取完整 trace 摘要流程图、要点、备注trace_ids列表成本最高提示词中明确要求战略性使用get_current_labels检查已设置的全部标签无未打标的聚类显示nullset_cluster_label设置/更新单个聚类标签cluster_id、title、description写入current_labelsbulk_set_labels批量设置多个聚类标签labelsdict 列表Phase 1 一次性覆盖所有聚类finalize_labels声明打标完成无返回labeled/total计数信号两个设计点值得展开信息分层与成本控制工具的返回粒度从粗到细排列为 overview → 标题列表 → 完整摘要对应 token 成本递增。提示词中明确get_trace_details比标题类工具更贵应选择性使用引导 Agent 先用廉价工具建立全局认知再对模糊聚类做定点深挖。rank 语义rank1表示最接近质心、最能代表该聚类的 trace高 rank 的是边缘 trace——边缘 trace 往往揭示聚类内部的子模式系统提示词专门提示 Agent考虑边缘 trace它们有时值得写入描述。五、两阶段 Agent 策略由系统提示词驱动系统提示词CLUSTER_LABELING_SYSTEM_PROMPTprompts.py是整个 Agent 行为的核心约束它规定了严格的两阶段策略Phase 1 - 快速初标必须先做调用get_all_clusters_with_sample_titles(titles_per_cluster10)一次拿到全局视图用bulk_set_labels()为所有聚类一次性写入初始标签离群簇cluster_id -1统一命名为 Outliers。Phase 2 - 精细化时间允许时对感觉不确定的聚类用get_cluster_trace_titles()/get_trace_details()深挖 top-ranked 与边缘 trace用set_cluster_label()更新标签用get_current_labels()复查所有标签的区分度淘汰过于相似或宽泛的表述满意后调用finalize_labels()收尾。之所以强制先全量粗标、再定点精修提示词给出了直接理由Agent 的迭代次数有限受recursion_limit约束先保证每个聚类都有基于标题的标签即使 Phase 2 没跑完每个聚类也至少有一个比 Cluster N 兜底名好得多的标签。提示词同时给出了明确的标签质量准则具体优于宽泛PDF Generation Errors 而非 Data Processing行动导向描述 trace 做了什么、代表什么模式相互区分每个标签要能和其他聚类明显区分开标题 3–10 个词描述用 2–5 个以-开头的要点解释 trace 为何被归到一组充分利用完整摘要流程图和 notes 能揭示标题里看不出的模式。提示词末尾还附了一段完整的示例交互从 Phase 1 的两次工具调用到 Phase 2 的 refine 与 finalize相当于给 LLM 提供了一份 few-shot 轨迹最后以Now, lets begin. Start by calling get_all_clusters_with_sample_titles()…强制指定第一个动作。而 graph.py 中的initial_state也用一条HumanMessage(Please begin labeling the clusters.)触发首轮推理与系统提示词的收尾指令形成呼应。六、配置参数打标 Agent 的三个核心常量定义在 constants.py常量值说明LABELING_AGENT_MODELgpt-5.4用于推理的 OpenAI 模型LABELING_AGENT_MAX_ITERATIONS50Agent 最大迭代次数保留常量run_labeling_agent中的max_iterations参数已标注 Unused, kept for API compatibilityLABELING_AGENT_RECURSION_LIMIT150LangGraph 图步数上限强制停止前的最大 steps注释标明其值应大于 2 × max_iterationsLABELING_AGENT_TIMEOUT600.0LLM 请求超时秒结合工作流层的常量可以还原出完整的运行预算打标活动单次尝试超时LLM_ACTIVITY_TIMEOUT 600s心跳间隔LLM_HEARTBEAT_TIMEOUT 120s注释解释为agent 运行在 LLM 调用之间可能有长停顿LLM_SCHEDULE_TO_CLOSE_TIMEOUT 1260s意味着两次 600s 尝试加退避后总预算 21 分钟——即 Temporal 层面允许重试一次完整的 Agent 运行而recursion_limit 150则是图内部的独立熔断器无论 LLM 多勤奋Agent 最多执行 150 步图节点后停止。从源码结构看run_labeling_agent的max_iterations参数被刻意保留但不再使用正是设计决策第 3 条的体现用recursion_limit取代手工迭代计数控制流更干净不需要自定义迭代追踪。七、使用方式模块只对外导出一个入口init.pyfrom posthog.temporal.ai_observability.trace_clustering.labeling_agent import run_labeling_agent labels run_labeling_agent( team_id1, cluster_data{ 0: { cluster_id: 0, size: 50, centroid_x: -2.2, centroid_y: 0.8, traces: { trace_1: {trace_id: trace_1, rank: 1, distance_to_centroid: 0.08, x: -2.3, y: 0.9}, trace_2: {trace_id: trace_2, rank: 2, distance_to_centroid: 0.12, x: -2.1, y: 0.7}, }, }, -1: { # 离群簇 cluster_id: -1, size: 10, centroid_x: 1.5, centroid_y: -0.5, traces: {...}, }, }, all_trace_summaries{ trace_1: {title: ..., flow_diagram: ..., bullets: ..., interesting_notes: ..., trace_timestamp: ...}, # ... }, ) # 返回: {0: ClusterLabel(title..., description...), -1: ClusterLabel(...)}除 README 示例中的三个必需参数外run_labeling_agent还支持trace_id/session_id/clustering_run_id/clustering_job_id/analysis_level等可选参数缺省时自动生成 UUID 并挂载到观测属性中用于把 Agent 运行关联到具体的聚类批次。实际工作流中的调用路径是generate_cluster_labels()labeling.py它把 HDBSCAN 输出的labels数组和预计算的TraceLabelingMetadata每条 trace 的x/y/distance_to_centroid/rank转换成上述cluster_data结构——其中噪声簇 -1 的质心取噪声点坐标均值正常簇取 UMAP 质心 2D 坐标——从而保证 Agent 看到的几何信息与前端散点图一致。八、错误处理与兜底标签README 的三条错误处理策略在源码中都能找到对应实现递归上限触达LangGraph 停止推进agent.invoke正常返回当前状态代码直接取result[current_labels]并进入兜底填充——这就是 Phase 1 强制全量初标策略的价值所在此时大部分聚类已有标签。LLM 异常run_labeling_agent用try/except包裹整个invoke异常经logger.exception(cluster_labeling_agent_error, ...)记录后返回_apply_fallbacks({}, cluster_data)即全量兜底。缺失标签_apply_fallbacks()graph.py#L126-L136委托给共享模块的 fill_missing_labels() 保证每个聚类必有标签的不变量已有标签的聚类原样保留cluster_id -1的离群簇填充 Outliers 标题与固定描述trace 场景下为 Traces that didnt fit other clusters / May include edge cases or rare patterns其余未打标聚类填充Cluster {id}标题加 Contains N similar traces / Label not generated by agent 描述。这一保证使下游事件发射活动永远不会因缺失 key 而崩溃。该兜底函数由 clustering_agent 包提供注释说明其被 trace 与 evaluation 两个打标 Agent 复用——两者结构平行同一 ReAct 循环、同一 ChatOpenAI 守卫、同一默认标签填充仅提示词、工具和状态 TypedDict 各自独立便于分级别迭代 prompt。九、关键设计决策与测试验证README 总结的四条设计决策逐条都有源码支撑create_react_agent优于手写StateGraph——消除 Agent 循环、工具路由、消息处理的样板代码graph.py#L73-L78工具用InjectedState——工具直接访问/修改图状态无需独立执行函数与手工分发tools.pyrecursion_limit优于迭代计数——控制流干净无需自定义迭代追踪invoke配置中的{recursion_limit: 150, ...}批量操作减少往返——get_all_clusters_with_sample_titles一次拿全所有聚类的样本标题bulk_set_labels一次写全部初标Phase 1 全程只需 2 次工具调用。行为正确性由 tests/test_labeling_agent.py 覆盖测试通过构造测试 state 直接invoke各工具断言get_clusters_overview按 ID 排序并包含 size/质心、get_all_clusters_with_sample_titles尊重titles_per_cluster限制且标题按 rank 排序、get_cluster_trace_titles正确过滤指定聚类等同时直接测试run_labeling_agent与兜底填充路径测试文件中导入的_apply_fallbacks别名即验证 README 所述缺失标签 → 默认名行为。十、小结Cluster Labeling Agent 是一个典型的预构建 Agent 状态注入工具 提示词驱动策略 多层兜底的工业级 ReAct 实现LangGraph 的create_react_agent提供循环骨架InjectedState工具让 LLM 在受控的状态空间里读写两阶段提示词策略把有限的recursion_limit预算花在刀刃上而fill_missing_labels兜底加上 Temporal 层的超时/重试/心跳配置保证了批量任务在任何部分失败下都能产出完整可用的聚类标签。如果你在为自己的 LLM 应用构建数据探索 批量标注类 Agent这套粗标先行、精修随后、全程可观测、失败必兜底的模式值得直接参考。【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表