trulens-eval 0.33.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. trulens_eval-0.33.0/MANIFEST.in +6 -0
  2. trulens_eval-0.33.0/PKG-INFO +98 -0
  3. trulens_eval-0.33.0/README.md +55 -0
  4. trulens_eval-0.33.0/setup.cfg +20 -0
  5. trulens_eval-0.33.0/setup.py +72 -0
  6. trulens_eval-0.33.0/trulens_eval/Example_TruBot.py +172 -0
  7. trulens_eval-0.33.0/trulens_eval/LICENSE +21 -0
  8. trulens_eval-0.33.0/trulens_eval/Leaderboard.py +150 -0
  9. trulens_eval-0.33.0/trulens_eval/__init__.py +111 -0
  10. trulens_eval-0.33.0/trulens_eval/app.py +1533 -0
  11. trulens_eval-0.33.0/trulens_eval/appui.py +457 -0
  12. trulens_eval-0.33.0/trulens_eval/database/__init__.py +0 -0
  13. trulens_eval-0.33.0/trulens_eval/database/base.py +292 -0
  14. trulens_eval-0.33.0/trulens_eval/database/exceptions.py +65 -0
  15. trulens_eval-0.33.0/trulens_eval/database/legacy/migration.py +406 -0
  16. trulens_eval-0.33.0/trulens_eval/database/migrations/__init__.py +120 -0
  17. trulens_eval-0.33.0/trulens_eval/database/migrations/alembic.ini +104 -0
  18. trulens_eval-0.33.0/trulens_eval/database/migrations/data.py +192 -0
  19. trulens_eval-0.33.0/trulens_eval/database/migrations/env.py +99 -0
  20. trulens_eval-0.33.0/trulens_eval/database/migrations/versions/1_first_revision.py +78 -0
  21. trulens_eval-0.33.0/trulens_eval/database/orm.py +389 -0
  22. trulens_eval-0.33.0/trulens_eval/database/sqlalchemy.py +883 -0
  23. trulens_eval-0.33.0/trulens_eval/database/utils.py +234 -0
  24. trulens_eval-0.33.0/trulens_eval/feedback/__init__.py +43 -0
  25. trulens_eval-0.33.0/trulens_eval/feedback/embeddings.py +204 -0
  26. trulens_eval-0.33.0/trulens_eval/feedback/feedback.py +1227 -0
  27. trulens_eval-0.33.0/trulens_eval/feedback/groundtruth.py +328 -0
  28. trulens_eval-0.33.0/trulens_eval/feedback/prompts.py +168 -0
  29. trulens_eval-0.33.0/trulens_eval/feedback/provider/__init__.py +34 -0
  30. trulens_eval-0.33.0/trulens_eval/feedback/provider/base.py +1242 -0
  31. trulens_eval-0.33.0/trulens_eval/feedback/provider/bedrock.py +290 -0
  32. trulens_eval-0.33.0/trulens_eval/feedback/provider/cortex.py +113 -0
  33. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/__init__.py +31 -0
  34. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/base.py +923 -0
  35. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/bedrock.py +244 -0
  36. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/cortex.py +99 -0
  37. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/hugs.py +80 -0
  38. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/langchain.py +64 -0
  39. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/litellm.py +124 -0
  40. trulens_eval-0.33.0/trulens_eval/feedback/provider/endpoint/openai.py +369 -0
  41. trulens_eval-0.33.0/trulens_eval/feedback/provider/hugs.py +760 -0
  42. trulens_eval-0.33.0/trulens_eval/feedback/provider/langchain.py +77 -0
  43. trulens_eval-0.33.0/trulens_eval/feedback/provider/litellm.py +126 -0
  44. trulens_eval-0.33.0/trulens_eval/feedback/provider/openai.py +445 -0
  45. trulens_eval-0.33.0/trulens_eval/feedback/v2/feedback.py +617 -0
  46. trulens_eval-0.33.0/trulens_eval/feedback/v2/provider/base.py +96 -0
  47. trulens_eval-0.33.0/trulens_eval/generate_test_set.py +216 -0
  48. trulens_eval-0.33.0/trulens_eval/guardrails/__init__.py +0 -0
  49. trulens_eval-0.33.0/trulens_eval/guardrails/base.py +67 -0
  50. trulens_eval-0.33.0/trulens_eval/guardrails/langchain.py +122 -0
  51. trulens_eval-0.33.0/trulens_eval/guardrails/llama.py +103 -0
  52. trulens_eval-0.33.0/trulens_eval/instruments.py +1003 -0
  53. trulens_eval-0.33.0/trulens_eval/keys.py +416 -0
  54. trulens_eval-0.33.0/trulens_eval/pages/Apps.py +429 -0
  55. trulens_eval-0.33.0/trulens_eval/pages/Evaluations.py +443 -0
  56. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/__init__.py +80 -0
  57. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/dist/assets/SourceCodePro-Bold-839f42df.ttf +0 -0
  58. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/dist/assets/SourceCodePro-Regular-6e5dd049.ttf +0 -0
  59. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/dist/assets/SourceCodePro-SemiBold-ccfba566.ttf +0 -0
  60. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/dist/assets/index-00b8e16d.css +1 -0
  61. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/dist/assets/index-923e1c7a.js +236 -0
  62. trulens_eval-0.33.0/trulens_eval/react_components/record_viewer/dist/index.html +14 -0
  63. trulens_eval-0.33.0/trulens_eval/requirements.optional.txt +74 -0
  64. trulens_eval-0.33.0/trulens_eval/requirements.txt +43 -0
  65. trulens_eval-0.33.0/trulens_eval/schema/__init__.py +22 -0
  66. trulens_eval-0.33.0/trulens_eval/schema/app.py +278 -0
  67. trulens_eval-0.33.0/trulens_eval/schema/base.py +103 -0
  68. trulens_eval-0.33.0/trulens_eval/schema/feedback.py +537 -0
  69. trulens_eval-0.33.0/trulens_eval/schema/record.py +251 -0
  70. trulens_eval-0.33.0/trulens_eval/schema/types.py +60 -0
  71. trulens_eval-0.33.0/trulens_eval/streamlit.py +237 -0
  72. trulens_eval-0.33.0/trulens_eval/tests/benchmark_frameworks/eval_as_recommendation.py +127 -0
  73. trulens_eval-0.33.0/trulens_eval/tests/test_cases.py +337 -0
  74. trulens_eval-0.33.0/trulens_eval/tru.py +1267 -0
  75. trulens_eval-0.33.0/trulens_eval/tru_basic_app.py +170 -0
  76. trulens_eval-0.33.0/trulens_eval/tru_chain.py +412 -0
  77. trulens_eval-0.33.0/trulens_eval/tru_custom_app.py +544 -0
  78. trulens_eval-0.33.0/trulens_eval/tru_llama.py +539 -0
  79. trulens_eval-0.33.0/trulens_eval/tru_rails.py +454 -0
  80. trulens_eval-0.33.0/trulens_eval/tru_virtual.py +568 -0
  81. trulens_eval-0.33.0/trulens_eval/utils/__init__.py +0 -0
  82. trulens_eval-0.33.0/trulens_eval/utils/asynchro.py +171 -0
  83. trulens_eval-0.33.0/trulens_eval/utils/command_line.py +6 -0
  84. trulens_eval-0.33.0/trulens_eval/utils/containers.py +187 -0
  85. trulens_eval-0.33.0/trulens_eval/utils/display.py +76 -0
  86. trulens_eval-0.33.0/trulens_eval/utils/generated.py +90 -0
  87. trulens_eval-0.33.0/trulens_eval/utils/imports.py +684 -0
  88. trulens_eval-0.33.0/trulens_eval/utils/json.py +392 -0
  89. trulens_eval-0.33.0/trulens_eval/utils/langchain.py +74 -0
  90. trulens_eval-0.33.0/trulens_eval/utils/llama.py +110 -0
  91. trulens_eval-0.33.0/trulens_eval/utils/notebook_utils.py +56 -0
  92. trulens_eval-0.33.0/trulens_eval/utils/pace.py +134 -0
  93. trulens_eval-0.33.0/trulens_eval/utils/pyschema.py +724 -0
  94. trulens_eval-0.33.0/trulens_eval/utils/python.py +838 -0
  95. trulens_eval-0.33.0/trulens_eval/utils/serial.py +1223 -0
  96. trulens_eval-0.33.0/trulens_eval/utils/streamlit.py +30 -0
  97. trulens_eval-0.33.0/trulens_eval/utils/text.py +35 -0
  98. trulens_eval-0.33.0/trulens_eval/utils/threading.py +211 -0
  99. trulens_eval-0.33.0/trulens_eval/utils/trulens.py +33 -0
  100. trulens_eval-0.33.0/trulens_eval/ux/apps.py +29 -0
  101. trulens_eval-0.33.0/trulens_eval/ux/components.py +279 -0
  102. trulens_eval-0.33.0/trulens_eval/ux/page_config.py +74 -0
  103. trulens_eval-0.33.0/trulens_eval/ux/styles.py +143 -0
  104. trulens_eval-0.33.0/trulens_eval/ux/trulens_logo.svg +44 -0
  105. trulens_eval-0.33.0/trulens_eval.egg-info/PKG-INFO +98 -0
  106. trulens_eval-0.33.0/trulens_eval.egg-info/SOURCES.txt +109 -0
  107. trulens_eval-0.33.0/trulens_eval.egg-info/dependency_links.txt +1 -0
  108. trulens_eval-0.33.0/trulens_eval.egg-info/entry_points.txt +2 -0
  109. trulens_eval-0.33.0/trulens_eval.egg-info/requires.txt +28 -0
  110. trulens_eval-0.33.0/trulens_eval.egg-info/top_level.txt +1 -0
@@ -0,0 +1,6 @@
1
+ include trulens_eval/LICENSE
2
+ include trulens_eval/requirements.txt
3
+ include trulens_eval/requirements.optional.txt
4
+ include trulens_eval/ux/trulens_logo.svg
5
+ include trulens_eval/database/migrations/alembic.ini
6
+ recursive-include trulens_eval/react_components/record_viewer/dist *
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.1
2
+ Name: trulens_eval
3
+ Version: 0.33.0
4
+ Summary: Library to systematically track and evaluate LLM based applications.
5
+ Home-page: https://www.trulens.org
6
+ Author: Truera Inc
7
+ Author-email: all@truera.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Requires-Python: >= 3.8, < 3.13
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: numpy>=1.23.5
16
+ Requires-Dist: frozendict>=2.3.8
17
+ Requires-Dist: munch>=3.0.0
18
+ Requires-Dist: dill>=0.3.7
19
+ Requires-Dist: tqdm>=4.66.1
20
+ Requires-Dist: nltk>=3.8.1
21
+ Requires-Dist: requests>=2.31.0
22
+ Requires-Dist: nest-asyncio>=1.5.8
23
+ Requires-Dist: typing_extensions>=4.9.0
24
+ Requires-Dist: psutil>=5.9.8
25
+ Requires-Dist: pip>=24.0
26
+ Requires-Dist: packaging>=23.2
27
+ Requires-Dist: python-dotenv>=1.0.0
28
+ Requires-Dist: pydantic<3,>=2
29
+ Requires-Dist: merkle-json>=1.0.0
30
+ Requires-Dist: langchain>=0.1.14
31
+ Requires-Dist: langchain-core>=0.1.6
32
+ Requires-Dist: langchain-community>=0.0.38
33
+ Requires-Dist: typing-inspect>=0.8.0
34
+ Requires-Dist: millify>=0.1.1
35
+ Requires-Dist: humanize>=4.6.0
36
+ Requires-Dist: streamlit>=1.33.0
37
+ Requires-Dist: streamlit-aggrid==0.3.4
38
+ Requires-Dist: streamlit-extras>=0.4.0
39
+ Requires-Dist: streamlit-pills>=0.3.0
40
+ Requires-Dist: rich>=13.6.0
41
+ Requires-Dist: sqlalchemy>=2.0.19
42
+ Requires-Dist: alembic>=1.11.2
43
+
44
+ <!---
45
+ start of docs/trulens_eval/intro.md
46
+ NOTE: This content is from docs/trulens_eval/intro.md and is merged into
47
+ trulens_eval/README.md . If you are editing README.md, your changes will be overwritten.
48
+ -->
49
+ # Welcome to TruLens-Eval!
50
+
51
+ ![TruLens](https://www.trulens.org/assets/images/Neural_Network_Explainability.png)
52
+
53
+ **Don't just vibe-check your llm app!** Systematically evaluate and track your
54
+ LLM experiments with TruLens. As you develop your app including prompts, models,
55
+ retreivers, knowledge sources and more, *TruLens-Eval* is the tool you need to
56
+ understand its performance.
57
+
58
+ Fine-grained, stack-agnostic instrumentation and comprehensive evaluations help
59
+ you to identify failure modes & systematically iterate to improve your
60
+ application.
61
+
62
+ Read more about the core concepts behind TruLens including [Feedback Functions](https://www.trulens.org/trulens_eval/getting_started/core_concepts/feedback_functions/),
63
+ [The RAG Triad](https://www.trulens.org/trulens_eval/getting_started/core_concepts/rag_triad/),
64
+ and [Honest, Harmless and Helpful Evals](https://www.trulens.org/trulens_eval/getting_started/core_concepts/honest_harmless_helpful_evals/).
65
+
66
+ ## TruLens in the development workflow
67
+
68
+ Build your first prototype then connect instrumentation and logging with
69
+ TruLens. Decide what feedbacks you need, and specify them with TruLens to run
70
+ alongside your app. Then iterate and compare versions of your app in an
71
+ easy-to-use user interface 👇
72
+
73
+ ![Architecture
74
+ Diagram](https://www.trulens.org/assets/images/TruLens_Architecture.png)
75
+
76
+ ## Installation and Setup
77
+
78
+ Install the trulens-eval pip package from PyPI.
79
+
80
+ ```bash
81
+ pip install trulens-eval
82
+ ```
83
+
84
+ ## Quick Usage
85
+
86
+ Walk through how to instrument and evaluate a RAG built from scratch with
87
+ TruLens.
88
+
89
+ [![Open In
90
+ Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/truera/trulens/blob/main/trulens_eval/examples/quickstart/quickstart.ipynb)
91
+
92
+ ### 💡 Contributing
93
+
94
+ Interested in contributing? See our [contributing
95
+ guide](https://www.trulens.org/trulens_eval/contributing/) for more details.
96
+ <!---
97
+ end of docs/trulens_eval/intro.md
98
+ -->
@@ -0,0 +1,55 @@
1
+ <!---
2
+ start of docs/trulens_eval/intro.md
3
+ NOTE: This content is from docs/trulens_eval/intro.md and is merged into
4
+ trulens_eval/README.md . If you are editing README.md, your changes will be overwritten.
5
+ -->
6
+ # Welcome to TruLens-Eval!
7
+
8
+ ![TruLens](https://www.trulens.org/assets/images/Neural_Network_Explainability.png)
9
+
10
+ **Don't just vibe-check your llm app!** Systematically evaluate and track your
11
+ LLM experiments with TruLens. As you develop your app including prompts, models,
12
+ retreivers, knowledge sources and more, *TruLens-Eval* is the tool you need to
13
+ understand its performance.
14
+
15
+ Fine-grained, stack-agnostic instrumentation and comprehensive evaluations help
16
+ you to identify failure modes & systematically iterate to improve your
17
+ application.
18
+
19
+ Read more about the core concepts behind TruLens including [Feedback Functions](https://www.trulens.org/trulens_eval/getting_started/core_concepts/feedback_functions/),
20
+ [The RAG Triad](https://www.trulens.org/trulens_eval/getting_started/core_concepts/rag_triad/),
21
+ and [Honest, Harmless and Helpful Evals](https://www.trulens.org/trulens_eval/getting_started/core_concepts/honest_harmless_helpful_evals/).
22
+
23
+ ## TruLens in the development workflow
24
+
25
+ Build your first prototype then connect instrumentation and logging with
26
+ TruLens. Decide what feedbacks you need, and specify them with TruLens to run
27
+ alongside your app. Then iterate and compare versions of your app in an
28
+ easy-to-use user interface 👇
29
+
30
+ ![Architecture
31
+ Diagram](https://www.trulens.org/assets/images/TruLens_Architecture.png)
32
+
33
+ ## Installation and Setup
34
+
35
+ Install the trulens-eval pip package from PyPI.
36
+
37
+ ```bash
38
+ pip install trulens-eval
39
+ ```
40
+
41
+ ## Quick Usage
42
+
43
+ Walk through how to instrument and evaluate a RAG built from scratch with
44
+ TruLens.
45
+
46
+ [![Open In
47
+ Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/truera/trulens/blob/main/trulens_eval/examples/quickstart/quickstart.ipynb)
48
+
49
+ ### 💡 Contributing
50
+
51
+ Interested in contributing? See our [contributing
52
+ guide](https://www.trulens.org/trulens_eval/contributing/) for more details.
53
+ <!---
54
+ end of docs/trulens_eval/intro.md
55
+ -->
@@ -0,0 +1,20 @@
1
+ [metadata]
2
+ name = trulens_eval
3
+ version = attr: trulens_eval.__version__
4
+ url = https://www.trulens.org
5
+ license = MIT
6
+ author = Truera Inc
7
+ author_email = all@truera.com
8
+ description = Library to systematically track and evaluate LLM based applications.
9
+ long_description = file: README.md
10
+ long_description_content_type = text/markdown
11
+ classifiers =
12
+ Programming Language :: Python :: 3
13
+ Operating System :: OS Independent
14
+ Development Status :: 3 - Alpha
15
+ License :: OSI Approved :: MIT License
16
+
17
+ [egg_info]
18
+ tag_build =
19
+ tag_date = 0
20
+
@@ -0,0 +1,72 @@
1
+ """
2
+ # _TruLens-Eval_ build script
3
+
4
+ To build:
5
+
6
+ ```bash
7
+ python setup.py bdist_wheel
8
+ ```
9
+
10
+ TODO: It is more standard to configure a lot of things we configure
11
+ here in a setup.cfg file instead. It is unclear whether we can do everything
12
+ with a config file though so we may need to keep this script or parts of it.
13
+ """
14
+
15
+ import os
16
+
17
+ from pip._internal.req import parse_requirements
18
+ from setuptools import find_namespace_packages
19
+ from setuptools import setup
20
+ from setuptools.command.build import build
21
+ from setuptools.logging import logging
22
+
23
+ required_packages = list(
24
+ map(
25
+ lambda pip_req: str(pip_req.requirement),
26
+ parse_requirements("trulens_eval/requirements.txt", session=None)
27
+ )
28
+ )
29
+ optional_packages = list(
30
+ map(
31
+ lambda pip_req: str(pip_req.requirement),
32
+ parse_requirements(
33
+ "trulens_eval/requirements.optional.txt", session=None
34
+ )
35
+ )
36
+ )
37
+
38
+
39
+ class BuildJavascript(build):
40
+
41
+ def run(self):
42
+ """Custom build command to run npm commands before building the package.
43
+
44
+ This builds the record timeline component for the dashboard.
45
+ """
46
+
47
+ logging.info("running npm i")
48
+ os.system("npm i --prefix trulens_eval/react_components/record_viewer")
49
+ logging.info("running npm run build")
50
+ os.system(
51
+ "npm run --prefix trulens_eval/react_components/record_viewer build"
52
+ )
53
+ build.run(self)
54
+
55
+
56
+ setup(
57
+ name="trulens_eval",
58
+ cmdclass={
59
+ 'build': BuildJavascript,
60
+ },
61
+ include_package_data=True, # includes things specified in MANIFEST.in
62
+ packages=find_namespace_packages(
63
+ include=["trulens_eval", "trulens_eval.*"]
64
+ ),
65
+ python_requires='>= 3.8, < 3.13',
66
+ entry_points={
67
+ 'console_scripts': [
68
+ 'trulens-eval=trulens_eval.utils.command_line:main'
69
+ ],
70
+ },
71
+ install_requires=required_packages
72
+ )
@@ -0,0 +1,172 @@
1
+ import os
2
+
3
+ os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
4
+
5
+ from langchain.chains import ConversationalRetrievalChain
6
+ from langchain.memory import ConversationSummaryBufferMemory
7
+ import numpy as np
8
+ import streamlit as st
9
+
10
+ from trulens_eval import feedback
11
+ from trulens_eval import Select
12
+ from trulens_eval import tru
13
+ from trulens_eval import tru_chain
14
+ from trulens_eval.feedback import Feedback
15
+ from trulens_eval.keys import check_keys
16
+ from trulens_eval.utils.imports import OptionalImports
17
+ from trulens_eval.utils.imports import REQUIREMENT_PINECONE
18
+
19
+ with OptionalImports(messages=REQUIREMENT_PINECONE) as opt:
20
+ from langchain.embeddings.openai import OpenAIEmbeddings
21
+ import langchain_community
22
+ from langchain_community.callbacks import get_openai_callback
23
+ from langchain_community.llms import OpenAI
24
+ import pinecone
25
+
26
+ opt.assert_installed(mods=[pinecone, langchain_community, OpenAIEmbeddings])
27
+
28
+ check_keys("OPENAI_API_KEY", "PINECONE_API_KEY", "PINECONE_ENV")
29
+
30
+ # Set up GPT-3 model
31
+ model_name = "gpt-3.5-turbo"
32
+
33
+ app_id = "TruBot"
34
+ # app_id = "TruBot_langprompt"
35
+ # app_id = "TruBot_relevance"
36
+
37
+ # Pinecone configuration.
38
+ pinecone_client = pinecone.Pinecone(
39
+ api_key=os.environ.get("PINECONE_API_KEY"), # find at app.pinecone.io
40
+ environment=os.environ.get("PINECONE_ENV") # next to api key in console
41
+ )
42
+
43
+ identity = lambda h: h
44
+
45
+ hugs = feedback.Huggingface()
46
+ openai = feedback.OpenAI()
47
+
48
+ # Language match between question/answer.
49
+ f_lang_match = Feedback(hugs.language_match).on_input_output()
50
+ # By default this will evaluate feedback on main app input and main app output.
51
+
52
+ # Question/answer relevance between overall question and answer.
53
+ f_qa_relevance = Feedback(openai.relevance).on_input_output()
54
+ # By default this will evaluate feedback on main app input and main app output.
55
+
56
+ # Question/statement relevance between question and each context chunk.
57
+ f_qs_relevance = feedback.Feedback(openai.qs_relevance).on_input().on(
58
+ Select.Record.app.combine_docs_chain._call.args.inputs.input_documents[:].
59
+ page_content
60
+ ).aggregate(np.min)
61
+
62
+ # First feedback argument is set to main app input, and the second is taken from
63
+ # the context sources as passed to an internal `combine_docs_chain._call`.
64
+
65
+
66
+ # @st.cache_data
67
+ def generate_response(prompt):
68
+ # Embedding needed for Pinecone vector db.
69
+ embedding = OpenAIEmbeddings(model='text-embedding-ada-002') # 1536 dims
70
+
71
+ # TODO: Check updated usage here.
72
+ docsearch = pinecone_client.from_existing_index(
73
+ index_name="llmdemo", embedding=embedding
74
+ )
75
+ retriever = docsearch.as_retriever()
76
+
77
+ # LLM for completing prompts, and other tasks.
78
+ llm = OpenAI(temperature=0, max_tokens=128)
79
+
80
+ # Conversation memory.
81
+ memory = ConversationSummaryBufferMemory(
82
+ max_token_limit=650,
83
+ llm=llm,
84
+ memory_key="chat_history",
85
+ output_key='answer'
86
+ )
87
+
88
+ # Conversational chain puts it all together.
89
+ chain = ConversationalRetrievalChain.from_llm(
90
+ llm=llm,
91
+ retriever=retriever,
92
+ return_source_documents=True,
93
+ memory=memory,
94
+ get_chat_history=identity,
95
+ max_tokens_limit=4096
96
+ )
97
+
98
+ # Language mismatch fix:
99
+ if "langprompt" in app_id:
100
+ chain.combine_docs_chain.llm_chain.prompt.template = \
101
+ "Use the following pieces of CONTEXT to answer the question at the end " \
102
+ "in the same language as the question. If you don't know the answer, " \
103
+ "just say that you don't know, don't try to make up an answer.\n" \
104
+ "\n" \
105
+ "CONTEXT: {context}\n" \
106
+ "\n" \
107
+ "Question: {question}\n" \
108
+ "Helpful Answer: "
109
+
110
+ elif "relevance" in app_id:
111
+ # Contexts fix
112
+ chain.combine_docs_chain.llm_chain.prompt.template = \
113
+ "Use only the relevant contexts to answer the question at the end " \
114
+ ". Some pieces of context may not be relevant. If you don't know the answer, " \
115
+ "just say that you don't know, don't try to make up an answer.\n" \
116
+ "\n" \
117
+ "Contexts: \n" \
118
+ "{context}\n" \
119
+ "\n" \
120
+ "Question: {question}\n" \
121
+ "Helpful Answer: "
122
+
123
+ # space is important
124
+
125
+ chain.combine_docs_chain.document_prompt.template = "\tContext: {page_content}"
126
+
127
+ # Trulens instrumentation.
128
+ tc_recorder = tru_chain.TruChain(chain, app_id=app_id)
129
+ with tc_recorder as recording:
130
+ resp = chain(dict(question=prompt))
131
+ tru_record = recording.records[0]
132
+ return tc_recorder, (resp, tru_record)
133
+
134
+
135
+ # Set up Streamlit app
136
+ st.title("TruBot")
137
+ user_input = st.text_input("Ask a question about TruEra")
138
+
139
+ if user_input:
140
+ # Generate GPT-3 response
141
+ prompt_input = user_input
142
+ # add context manager to capture tokens and cost of the chain
143
+
144
+ with get_openai_callback() as cb:
145
+ chain, (response, record) = generate_response(prompt_input)
146
+ total_tokens = cb.total_tokens
147
+ total_cost = cb.total_cost
148
+
149
+ answer = response['answer']
150
+
151
+ # Display response
152
+ st.write(answer)
153
+
154
+ record_id = tru.add_data(
155
+ app_id=app_id,
156
+ prompt=prompt_input,
157
+ response=answer,
158
+ record=record,
159
+ tags='dev',
160
+ total_tokens=total_tokens,
161
+ total_cost=total_cost
162
+ )
163
+
164
+ # Run feedback function and get value
165
+ feedbacks = tru.run_feedback_functions(
166
+ app=app,
167
+ record=record,
168
+ feedback_functions=[f_lang_match, f_qa_relevance, f_qs_relevance]
169
+ )
170
+
171
+ # Add value to database
172
+ tru.add_feedback(record_id, feedbacks)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Truera, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,150 @@
1
+ import asyncio
2
+ import json
3
+ import math
4
+
5
+ # https://github.com/jerryjliu/llama_index/issues/7244:
6
+ asyncio.set_event_loop(asyncio.new_event_loop())
7
+
8
+ from millify import millify
9
+ import streamlit as st
10
+ from streamlit_extras.switch_page_button import switch_page
11
+
12
+ from trulens_eval import Tru
13
+ from trulens_eval.database import base as mod_db
14
+ from trulens_eval.database.legacy.migration import MIGRATION_UNKNOWN_STR
15
+ from trulens_eval.utils.streamlit import init_from_args
16
+ from trulens_eval.ux import styles
17
+ from trulens_eval.ux.components import draw_metadata
18
+ from trulens_eval.ux.page_config import set_page_config
19
+ from trulens_eval.ux.styles import CATEGORY
20
+
21
+ if __name__ == "__main__":
22
+ # If not imported, gets args from command line and creates Tru singleton
23
+ init_from_args()
24
+
25
+
26
+ def leaderboard():
27
+ """Render the leaderboard page."""
28
+
29
+ set_page_config(page_title="Leaderboard")
30
+
31
+ tru = Tru(
32
+ ) # get singletone whether this file was imported or executed from command line.
33
+
34
+ lms = tru.db
35
+
36
+ # Set the title and subtitle of the app
37
+ st.title("App Leaderboard")
38
+ st.write(
39
+ "Average feedback values displayed in the range from 0 (worst) to 1 (best)."
40
+ )
41
+ df, feedback_col_names = lms.get_records_and_feedback([])
42
+ feedback_defs = lms.get_feedback_defs()
43
+ feedback_directions = {
44
+ (
45
+ row.feedback_json.get("supplied_name", "") or
46
+ row.feedback_json["implementation"]["name"]
47
+ ): row.feedback_json.get("higher_is_better", True)
48
+ for _, row in feedback_defs.iterrows()
49
+ }
50
+
51
+ if df.empty:
52
+ st.write("No records yet...")
53
+ return
54
+
55
+ df = df.sort_values(by="app_id")
56
+
57
+ if df.empty:
58
+ st.write("No records yet...")
59
+
60
+ apps = list(df.app_id.unique())
61
+ st.markdown("""---""")
62
+
63
+ for app in apps:
64
+ app_df = df.loc[df.app_id == app]
65
+ if app_df.empty:
66
+ continue
67
+ app_str = app_df["app_json"].iloc[0]
68
+ app_json = json.loads(app_str)
69
+ metadata = app_json.get("metadata")
70
+ # st.text('Metadata' + str(metadata))
71
+ st.header(app, help=draw_metadata(metadata))
72
+ app_feedback_col_names = [
73
+ col_name for col_name in feedback_col_names
74
+ if not app_df[col_name].isna().all()
75
+ ]
76
+ col1, col2, col3, col4, *feedback_cols, col99 = st.columns(
77
+ 5 + len(app_feedback_col_names)
78
+ )
79
+ latency_mean = (
80
+ app_df["latency"].
81
+ apply(lambda td: td if td != MIGRATION_UNKNOWN_STR else None).mean()
82
+ )
83
+
84
+ # app_df_feedback = df.loc[df.app_id == app]
85
+
86
+ col1.metric("Records", len(app_df))
87
+ col2.metric(
88
+ "Average Latency (Seconds)",
89
+ (
90
+ f"{millify(round(latency_mean, 5), precision=2)}"
91
+ if not math.isnan(latency_mean) else "nan"
92
+ ),
93
+ )
94
+ col3.metric(
95
+ "Total Cost (USD)",
96
+ f"${millify(round(sum(cost for cost in app_df.total_cost if cost is not None), 5), precision = 2)}",
97
+ )
98
+ col4.metric(
99
+ "Total Tokens",
100
+ millify(
101
+ sum(
102
+ tokens for tokens in app_df.total_tokens
103
+ if tokens is not None
104
+ ),
105
+ precision=2
106
+ ),
107
+ )
108
+
109
+ for i, col_name in enumerate(app_feedback_col_names):
110
+ mean = app_df[col_name].mean()
111
+
112
+ st.write(
113
+ styles.stmetricdelta_hidearrow,
114
+ unsafe_allow_html=True,
115
+ )
116
+
117
+ higher_is_better = feedback_directions.get(col_name, True)
118
+
119
+ if "distance" in col_name:
120
+ feedback_cols[i].metric(
121
+ label=col_name,
122
+ value=f"{round(mean, 2)}",
123
+ delta_color="normal"
124
+ )
125
+ else:
126
+ cat = CATEGORY.of_score(mean, higher_is_better=higher_is_better)
127
+ feedback_cols[i].metric(
128
+ label=col_name,
129
+ value=f"{round(mean, 2)}",
130
+ delta=f"{cat.icon} {cat.adjective}",
131
+ delta_color=(
132
+ "normal" if cat.compare(
133
+ mean, CATEGORY.PASS[cat.direction].threshold
134
+ ) else "inverse"
135
+ ),
136
+ )
137
+
138
+ with col99:
139
+ if st.button("Select App", key=f"app-selector-{app}"):
140
+ st.session_state.app = app
141
+ switch_page("Evaluations")
142
+
143
+ # with st.expander("Model metadata"):
144
+ # st.markdown(draw_metadata(metadata))
145
+
146
+ st.markdown("""---""")
147
+
148
+
149
+ if __name__ == "__main__":
150
+ leaderboard()