Repository navigation
feat(ai): record the Anthropic web search count in the LangChain callback handler - #1097
pcbeingused333 wants to merge 5 commits into
Conversation
marandaneto
left a comment
There was a problem hiding this comment.
Automated advisory code review.
|
@PostHog/team-ai-observability do we need any backend/frontend change for this? |
…back handler Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # posthog/test/ai/langchain/test_callbacks.py
df78690 to
dd3f216
Compare
| ) | ||
| if usage.reasoning_tokens is not None: | ||
| event_properties["$ai_reasoning_tokens"] = usage.reasoning_tokens | ||
| if usage.web_search_count is not None: |
There was a problem hiding this comment.
This emits $ai_web_search_count even when it's 0, but the other Python wrappers only emit it when it's > 0 (posthog/ai/utils.py), so a LangChain Anthropic event would differ from a direct Anthropic wrapper event for the same call. Can we gate on > 0 here too?
| parsed_usage["reasoning"] = usage["output_token_details"].get("reasoning") | ||
|
|
||
| # Anthropic reports the exact number of web searches of a response | ||
| server_tool_use = usage.get("server_tool_use") |
There was a problem hiding this comment.
This never fires on real ChatAnthropic output. langchain-anthropic always sets AIMessage.usage_metadata, so the generations loop in _parse_usage runs after the llm_output["usage"] parse and overwrites it with usage that has no server_tool_use, resetting web_search_count to None. Same llm_output gives 2 without usage_metadata on the message and None with it. Could _parse_usage read server_tool_use from llm_output["usage"] separately and merge it into whichever ModelUsage wins for the tokens?
|
|
||
| class TestWebSearchCount: | ||
| @staticmethod | ||
| def _captured_properties(llm_output): |
There was a problem hiding this comment.
Could this follow the rest of the file? The mock_client fixture and the module-level imports already cover CallbackHandler, uuid, AIMessage and MagicMock, and the three tests could be one @pytest.mark.parametrize test like test_stop_reason_resolution just above.
| metadata={"ls_provider": "anthropic", "ls_model_name": "claude-sonnet"}, | ||
| ) | ||
| response = LLMResult( | ||
| generations=[[ChatGeneration(message=AIMessage(content="r"))]], |
There was a problem hiding this comment.
ChatAnthropic always sets usage_metadata on the message, and this fixture leaves it out, which is why the tests pass while the feature does nothing on real output. With usage_metadata={"input_tokens": 10, "output_tokens": 5, "total_tokens": 15} they cover the real path, and should fail until the override above is fixed.
No, but there were some issues with the implementation that I surfaced on my review |
…d omit zero Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks, all four points addressed in the latest commit:
|
💡 Motivation and Context
The
posthog-jsLangChain handler records$ai_web_search_count, and so do the Python OpenAI, Anthropic and Gemini wrappers, but the Python LangChain callback handler never did. When Anthropic reportsusage.server_tool_use.web_search_requests(as a dict or an object),_parse_usage_modelnow reads it into a newweb_search_countfield ofModelUsage, and the handler adds$ai_web_search_countto the event, including a count of 0. Nothing is added when the provider reports no count.langchain-anthropicpasses the raw Anthropicusage(withserver_tool_use) inllm_outputfor non-streamed calls, which is where the handler reads it; streamed calls only carry the standardusage_metadata, so no count is recorded for them. Only this exact count is handled;posthog-jsalso infers a single search from citations or grounding metadata for other providers, which is not ported here.💚 How did you test it?
TestWebSearchCountinposthog/test/ai/langchain/test_callbacks.py: a response with two web search requests, one with zero, and one withoutserver_tool_use. The first two fail onmasterand pass with the change; the third guards the omitted case.posthog/test/ai/langchain/test_callbacks.py: 83 passed, 8 skipped.ruff format --checkpasses on the touched directories. The rest of the suite and a live LangChain call with the Anthropic web search tool were not run.📝 Checklist
If releasing new changes
sampo addto generate a changeset file (added.sampo/changesets/langchain-web-search-count.md)🤖 Agent context
Autonomy: Fully autonomous
🤖 Generated with Claude Code
🤖 Generated with Claude Code