|
319 | 319 | " async def run_async(self, name: str, dataset: Dataset): ..." |
320 | 320 | ] |
321 | 321 | }, |
322 | | - { |
323 | | - "cell_type": "code", |
324 | | - "execution_count": null, |
325 | | - "metadata": {}, |
326 | | - "outputs": [], |
327 | | - "source": [ |
328 | | - "# | export\n", |
329 | | - "\n", |
330 | | - "# this one we have to clean up\n", |
331 | | - "from langfuse.decorators import observe" |
332 | | - ] |
333 | | - }, |
334 | 322 | { |
335 | 323 | "cell_type": "code", |
336 | 324 | "execution_count": null, |
|
477 | 465 | "name": "stderr", |
478 | 466 | "output_type": "stream", |
479 | 467 | "text": [ |
480 | | - "Running experiment: 100%|██████████| 6/6 [00:01<00:00, 3.84it/s]\n" |
| 468 | + "Running experiment: 100%|██████████| 6/6 [00:01<00:00, 3.23it/s]\n" |
481 | 469 | ] |
482 | 470 | }, |
483 | 471 | { |
484 | 472 | "data": { |
485 | 473 | "text/plain": [ |
486 | | - "Experiment(name=gallant_torvalds, model=TextExperimentModel)" |
| 474 | + "Experiment(name=dazzling_knuth, model=TextExperimentModel)" |
487 | 475 | ] |
488 | 476 | }, |
489 | 477 | "execution_count": null, |
|
496 | 484 | "await test_experiment.run_async(test_dataset)" |
497 | 485 | ] |
498 | 486 | }, |
| 487 | + { |
| 488 | + "cell_type": "code", |
| 489 | + "execution_count": null, |
| 490 | + "metadata": {}, |
| 491 | + "outputs": [], |
| 492 | + "source": [ |
| 493 | + "# | export\n", |
| 494 | + "\n", |
| 495 | + "# this one we have to clean up\n", |
| 496 | + "from langfuse.decorators import observe" |
| 497 | + ] |
| 498 | + }, |
499 | 499 | { |
500 | 500 | "cell_type": "code", |
501 | 501 | "execution_count": null, |
|
518 | 518 | " \"\"\"\n", |
519 | 519 | "\n", |
520 | 520 | " def decorator(func: t.Callable) -> ExperimentProtocol:\n", |
521 | | - " # First, create a base experiment wrapper\n", |
522 | | - " base_experiment = self.experiment(experiment_model, name_prefix)(func)\n", |
523 | | - "\n", |
524 | | - " # Override the wrapped function to add Langfuse observation\n", |
525 | 521 | " @wraps(func)\n", |
526 | | - " async def wrapped_with_langfuse(*args, **kwargs):\n", |
527 | | - " # wrap the function with langfuse observation\n", |
528 | | - " observed_func = observe(name=f\"{name_prefix}-{func.__name__}\")(func)\n", |
| 522 | + " async def langfuse_wrapped_func(*args, **kwargs):\n", |
| 523 | + " # Apply langfuse observation directly here\n", |
| 524 | + " trace_name = f\"{name_prefix}-{func.__name__}\" if name_prefix else func.__name__\n", |
| 525 | + " observed_func = observe(name=trace_name)(func)\n", |
529 | 526 | " return await observed_func(*args, **kwargs)\n", |
530 | | - "\n", |
531 | | - " # Replace the async function to use Langfuse\n", |
532 | | - " original_run_async = base_experiment.run_async\n", |
533 | | - "\n", |
534 | | - " # Use the original run_async but with the Langfuse-wrapped function\n", |
535 | | - " async def run_async_with_langfuse(\n", |
536 | | - " dataset: Dataset, name: t.Optional[str] = None\n", |
537 | | - " ):\n", |
538 | | - " # Override the internal wrapped_experiment with our Langfuse version\n", |
539 | | - " base_experiment.__wrapped__ = wrapped_with_langfuse\n", |
540 | | - "\n", |
541 | | - " # Call the original run_async which will now use our Langfuse-wrapped function\n", |
542 | | - " return await original_run_async(dataset, name)\n", |
543 | | - "\n", |
544 | | - " # Replace the run_async method\n", |
545 | | - " base_experiment.__setattr__(\"run_async\", run_async_with_langfuse)\n", |
546 | | - "\n", |
547 | | - " return t.cast(ExperimentProtocol, base_experiment)\n", |
| 527 | + " \n", |
| 528 | + " # Now create the experiment wrapper with our already-observed function\n", |
| 529 | + " experiment_wrapper = self.experiment(experiment_model, name_prefix)(langfuse_wrapped_func)\n", |
| 530 | + " \n", |
| 531 | + " return t.cast(ExperimentProtocol, experiment_wrapper)\n", |
548 | 532 | "\n", |
549 | 533 | " return decorator" |
550 | 534 | ] |
551 | 535 | }, |
| 536 | + { |
| 537 | + "cell_type": "code", |
| 538 | + "execution_count": null, |
| 539 | + "metadata": {}, |
| 540 | + "outputs": [], |
| 541 | + "source": [ |
| 542 | + "import os\n", |
| 543 | + "# import langfuse\n", |
| 544 | + "from langfuse import Langfuse" |
| 545 | + ] |
| 546 | + }, |
| 547 | + { |
| 548 | + "cell_type": "code", |
| 549 | + "execution_count": null, |
| 550 | + "metadata": {}, |
| 551 | + "outputs": [], |
| 552 | + "source": [ |
| 553 | + "\n", |
| 554 | + "langfuse = Langfuse(\n", |
| 555 | + " secret_key=os.getenv(\"LANGFUSE_SECRET_KEY\"),\n", |
| 556 | + " public_key=os.getenv(\"LANGFUSE_PUBLIC_KEY\"),\n", |
| 557 | + " host=\"https://us.cloud.langfuse.com\"\n", |
| 558 | + ")" |
| 559 | + ] |
| 560 | + }, |
| 561 | + { |
| 562 | + "cell_type": "code", |
| 563 | + "execution_count": null, |
| 564 | + "metadata": {}, |
| 565 | + "outputs": [], |
| 566 | + "source": [ |
| 567 | + "@p.langfuse_experiment(TextExperimentModel)\n", |
| 568 | + "async def test_experiment(item: TestModel):\n", |
| 569 | + " return TextExperimentModel(**item.model_dump(), response=\"test response\", is_correct=\"yes\")" |
| 570 | + ] |
| 571 | + }, |
| 572 | + { |
| 573 | + "cell_type": "code", |
| 574 | + "execution_count": null, |
| 575 | + "metadata": {}, |
| 576 | + "outputs": [ |
| 577 | + { |
| 578 | + "data": { |
| 579 | + "text/plain": [ |
| 580 | + "TextExperimentModel(name='test item 1', description='test item 1 description', price=100.0, url='https://www.google.com', tags='test', response='test response', is_correct='yes')" |
| 581 | + ] |
| 582 | + }, |
| 583 | + "execution_count": null, |
| 584 | + "metadata": {}, |
| 585 | + "output_type": "execute_result" |
| 586 | + } |
| 587 | + ], |
| 588 | + "source": [ |
| 589 | + "await test_experiment(test_dataset[0])" |
| 590 | + ] |
| 591 | + }, |
| 592 | + { |
| 593 | + "cell_type": "code", |
| 594 | + "execution_count": null, |
| 595 | + "metadata": {}, |
| 596 | + "outputs": [ |
| 597 | + { |
| 598 | + "name": "stderr", |
| 599 | + "output_type": "stream", |
| 600 | + "text": [ |
| 601 | + "Running experiment: 100%|██████████| 6/6 [00:01<00:00, 4.01it/s]\n" |
| 602 | + ] |
| 603 | + }, |
| 604 | + { |
| 605 | + "data": { |
| 606 | + "text/plain": [ |
| 607 | + "Experiment(name=cool_matsumoto, model=TextExperimentModel)" |
| 608 | + ] |
| 609 | + }, |
| 610 | + "execution_count": null, |
| 611 | + "metadata": {}, |
| 612 | + "output_type": "execute_result" |
| 613 | + } |
| 614 | + ], |
| 615 | + "source": [ |
| 616 | + "await test_experiment.run_async(test_dataset)" |
| 617 | + ] |
| 618 | + }, |
| 619 | + { |
| 620 | + "cell_type": "markdown", |
| 621 | + "metadata": {}, |
| 622 | + "source": [ |
| 623 | + "## Compare and Plot" |
| 624 | + ] |
| 625 | + }, |
552 | 626 | { |
553 | 627 | "cell_type": "code", |
554 | 628 | "execution_count": null, |
|
0 commit comments