### Install Dependencies with Extras Source: https://github.com/biocypher/biochatter/blob/main/DEVELOPER.md Install specific optional dependencies (extras) for desired functionalities. Use '--all-extras' to install all optional dependencies. ```bash poetry install -E ``` ```bash poetry install --all-extras ``` -------------------------------- ### Install Dependencies with Poetry Source: https://github.com/biocypher/biochatter/blob/main/DEVELOPER.md Use this command to install project dependencies from the lock file. Ensure Poetry is installed and the environment is set up. ```bash poetry install ``` -------------------------------- ### Setup BioCypherPromptEngine Source: https://github.com/biocypher/biochatter/blob/main/docs/features/rag.md Initialize the BioCypherPromptEngine by providing the path to the schema configuration or information file. This sets up the conversation for LLM-powered query generation. ```python from biochatter.prompts import BioCypherPromptEngine prompt_engine = BioCypherPromptEngine( schema_config_or_info_path="test/schema_info.yaml" ) ``` -------------------------------- ### Define Query Prompt for Structured Output Source: https://github.com/biocypher/biochatter/blob/main/docs/features/api.md Create a prompt that guides the LLM to extract sufficient context to fill the API parameters. Include API documentation and examples for better results. ```python NewAPI_QUERY_PROMPT = """ You are a world class algorithm for creating queries in structured formats. Your task is to use OncoKB Web APIs to answer genomic questions. API DOCUMENTATION AND EXAMPLES""" ``` -------------------------------- ### Install Biochatter with Xinference support Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Install the necessary package for Xinference integration. Ensure Xinference software is running on port 9997. ```bash pip install "biochatter[xinference]" ``` -------------------------------- ### Start BioChatter Services with Docker Compose Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Start the backend and frontend services for BioChatter Next using Docker Compose. Ensure your environment is configured correctly. ```bash docker-compose up -d ``` -------------------------------- ### Install BioChatter Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Install the BioChatter package using pip. This is the first step for Python developers. ```bash pip install biochatter ``` -------------------------------- ### Install Biochatter with Ollama support Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Install the necessary package for Ollama integration. Ensure Ollama software is running on port 11434. ```bash pip install "biochatter[ollama]" ``` -------------------------------- ### Deploy Project Planning Tool with Docker Compose Source: https://github.com/biocypher/biochatter/blob/main/docs/vignettes/custom-bclight-advanced.md These bash commands demonstrate how to clone the project-planning repository and deploy the tool using a password-protected Docker Compose configuration. Ensure you have Docker and Docker Compose installed. ```bash git clone https://github.com/biocypher/project-planning.git docker-compose -f project-planning/docker-compose-password.yml up -d ``` -------------------------------- ### OncoKB API Integration Example Source: https://github.com/biocypher/biochatter/blob/main/docs/features/api.md This example shows how to set up and use the API agent for OncoKB to query oncologically relevant genomic information. The execute method manages the full query lifecycle. ```python from biochatter.llm_connect import GptConversation from biochatter.api_agent.base.api_agent import APIAgent from biochatter.api_agent.web.oncokb import OncoKBQueryBuilder, OncoKBFetcher, OncoKBInterpreter # Set up a conversation factory (you might need to adjust this based on your setup) def conversation_factory(): return GptConversation(model_name="gpt-4", prompts={}, correct=False) # Create an API agent for OncoKB oncokb_agent = APIAgent( conversation_factory=conversation_factory, query_builder=OncoKBQueryBuilder(), fetcher=OncoKBFetcher(), interpreter=OncoKBInterpreter() ) # Execute a query question = "What is the oncogenic potential of BRAF V600E mutation?" result = oncokb_agent.execute(question) print(result) ``` -------------------------------- ### Integrate MCP Tools into Chat Source: https://github.com/biocypher/biochatter/blob/main/docs/features/tool_chat.md Load MCP tools and integrate them into a LangChain conversation. This example shows how to set up the client session, load tools, and query the model with tool-enabled conversation. ```python # import the needed libraries from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from langchain_mcp_adapters.tools import load_mcp_tools from pathlib import Path import sys #patch event loop if running in a notebook if 'ipykernel' in sys.modules: import nest_asyncio nest_asyncio.apply() # define the path to the math_server.py file server_path = Path('your_path_here') # define the server parameters server_params = StdioServerParameters( command="python", args=[server_path/"math_server.py"] ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: # Initialize the connection await session.initialize() # define the question question = "What is 2 times 2?" # Get tools tools = await load_mcp_tools(session) # define the conversation convo = LangChainConversation( model_provider="google_genai", model_name="gemini-2.0-flash", prompts={}, tools=tools, mcp=True ) # set the API key convo.set_api_key() # invoke the model convo.query(question) ``` -------------------------------- ### Complete Example Script for Sequential Queries and Structured Output Source: https://github.com/biocypher/biochatter/blob/main/docs/features/structured_outputs.md This script demonstrates a full workflow: initializing a conversation, querying for a ChEMBL ID, fetching mechanisms of action, and finally consolidating all gathered information into a DrugTargetsOutput Pydantic model. It also shows how to parse and print the structured results. ```python # --- Step 3: Initialize Conversation --- # Assuming LangChainConversation is already initialized and API key is set # For a self-contained script, you'd do: convo = LangChainConversation( model_provider="google_genai", # Replace with your provider e.g. "openai" model_name="gemini-2.0-flash", # Replace with your model e.g. "gpt-4-turbo-preview" prompts={} ) # Using default prompts # Set API key (read from environment variables) convo.set_api_key() # --- Step 4: Sequential Queries --- # 4.1. Query to find ChEMBL ID drug_name = "imatinib" # Example drug query1_result = convo.query( f'Get the ChEMBL ID for the drug "{drug_name}"', tools=[get_chembl_id] ) # 4.2. Get the mechanisms of action and targets # The LLM should use the ChEMBL ID from the previous turn's tool_result query2_result = convo.query( f'Now get its mechanisms of action and targets using the previously found ChEMBL ID.', tools=[get_mechanisms_of_action] ) # 4.3. Get the structured output # The LLM will use the conversation history (drug name, ChEMBL ID, mechanism data) # to populate the DrugTargetsOutput model. results = convo.query( "Consolidate all the information gathered about imatinib, including its ChEMBL ID, " "and its mechanisms of action and targets, into the predefined structure. ", structured_model=DrugTargetsOutput, ) # --- Step 5: Parse and Use the Structured Output --- # Parse the JSON string into the Pydantic model # Convert the JSON string to a Python dictionary drug_data = json.loads(results[0]) # Print the structured information print(f"Drug Name: {drug_data['drug_name_queried']}") print(f"ChEMBL ID: {drug_data['chembl_id_found']}") print("\nMechanisms of Action and Targets:") for i, mechanism in enumerate(drug_data['mechanisms_and_targets'], 1): print(f"\n{i}. Mechanism: {mechanism['mechanism_of_action']}") print(f" Target: {mechanism['target_name']}") print(" Associated Targets:") for target in mechanism['targets']: print(f" - {target['approved_symbol']} (ID: {target['target_id']})") if drug_data['error_message']: print(f"\nError: {drug_data['error_message']}") ``` -------------------------------- ### Complete Example Script Source: https://github.com/biocypher/biochatter/blob/main/docs/features/structured_outputs.md A full script demonstrating the integration of tools for gathering drug information (ChEMBL ID, mechanisms of action) and using Pydantic models for structured output. Includes necessary imports and tool definitions. ```python import requests from biochatter.llm_connect import LangChainConversation from pydantic import BaseModel, Field from langchain_core.tools import tool from typing import List, Dict, Any, Optional import json from pprint import pprint # --- Step 1: Define the Tools --- @tool def get_chembl_id(drug_name: str) -> str: """ Given a drug name, look up and return its ChEMBL ID using the ChEMBL API. Example: get_chembl_id(drug_name="aspirin") """ url = "https://www.ebi.ac.uk/chembl/api/data/chembl_id_lookup/search.json" params = {"q": drug_name} headers = {"Accept": "application/json"} try: resp = requests.get(url, params=params, headers=headers, timeout=10) resp.raise_for_status() data = resp.json() hits = data.get("chembl_id_lookups", []) if not hits: return f"Unable to find ChEMBL ID for {drug_name}" return hits[0].get("chembl_id", f"No ChEMBL ID found in hit for {drug_name}") except requests.RequestException as e: return f"Error querying ChEMBL API for {drug_name}: {str(e)}" except ValueError: # If JSON parsing fails return f"Invalid JSON received from ChEMBL API for {drug_name}" _GRAPHQL_QUERY = """ query MechanismsOfActionSectionQuery($chemblId: String!) { drug(chemblId: $chemblId) { id mechanismsOfAction { rows { mechanismOfAction targetName targets { id approvedSymbol } } } } } """ @tool def get_mechanisms_of_action(chembl_id: str) -> Dict[str, Any]: """ Fetch mechanisms of action and target information for a given drug (by ChEMBL ID) using the OpenTargets GraphQL API. Example: get_mechanisms_of_action(chembl_id="CHEMBL25") """ endpoint = "https://api.platform.opentargets.org/api/v4/graphql" payload = {"query": _GRAPHQL_QUERY, "variables": {"chemblId": chembl_id}} try: resp = requests.post(endpoint, json=payload, headers={"Content-Type": "application/json"}, timeout=15) resp.raise_for_status() data = resp.json() if "errors" in data: return {"error": f"GraphQL errors for {chembl_id}: {data['errors']}"} return data.get("data", {}) except requests.RequestException as e: return {"error": f"Error querying OpenTargets API for {chembl_id}: {str(e)}"} except ValueError: # If JSON parsing fails return {"error": f"Invalid JSON received from OpenTargets API for {chembl_id}"} # --- Step 2: Define the Pydantic Model for Structured Output --- class TargetDetail(BaseModel): approved_symbol: Optional[str] = Field(None, description="The approved symbol of the target (e.g., gene symbol).") target_id: Optional[str] = Field(None, description="The ID of the target (e.g., Ensembl ID).") class ActionMechanism(BaseModel): mechanism_of_action: Optional[str] = Field(None, description="Description of the mechanism of action.") target_name: Optional[str] = Field(None, description="The name of the target associated with this mechanism.") targets: List[TargetDetail] = Field(default_factory=list, description="List of specific targets involved in this mechanism.") class DrugTargetsOutput(BaseModel): drug_name_queried: str = Field(description="The original drug name queried.") chembl_id_found: Optional[str] = Field(None, description="The ChEMBL ID found for the drug.") mechanisms_and_targets: List[ActionMechanism] = Field(default_factory=list, description="List of mechanisms of action and associated targets.") error_message: Optional[str] = Field(None, description="Any error message encountered during the process.") # --- Step 5: parse and use the structured output --- # The final step is to parse the JSON string received from the LLM back into our Pydantic model. # This allows us to easily access the data in a type-safe way. # Parse the JSON string into the Pydantic model # Convert the JSON string to a Python dictionary # drug_data = json.loads(results[0]) # Assuming 'results' is a list containing the JSON string # Print the structured information (example usage) # print(f"Drug Name: {drug_data['drug_name_queried']}") # print(f"ChEMBL ID: {drug_data['chembl_id_found']}") # print("\nMechanisms of Action and Targets:") # for i, mechanism in enumerate(drug_data['mechanisms_and_targets'], 1): # print(f"\n{i}. Mechanism: {mechanism['mechanism_of_action']}") # print(f" Target: {mechanism['target_name']}") # print(" Associated Targets:") # for target in mechanism['targets']: # print(f" - {target['approved_symbol']} (ID: {target['target_id']})") # if drug_data['error_message']: # print(f"\nError: {drug_data['error_message']}") # This multi-step approach demonstrates how to: # 1. Use tools to gather information over several conversational turns. # 2. Leverage structured outputs to consolidate and format the gathered information according to a predefined schema. ``` -------------------------------- ### Initial Prompts for KG Query Generation Source: https://github.com/biocypher/biochatter/blob/main/docs/features/reflexion-agent.md Defines the system prompts used to guide the LLM in generating knowledge graph queries. Includes placeholders for time and instructions, and specifies that only the query should be generated. ```python ( "system", ( "As a senior biomedical researcher and graph database expert, " f"your task is to generate '{query_lang}' queries to extract data from our graph database based on the user's question. " "Current time {time}. {instruction}" ), ), ( "system", "Only generate query according to the user's question above.", ) ``` -------------------------------- ### Deploy and Query Xinference Model via Python Client Source: https://github.com/biocypher/biochatter/blob/main/docs/features/open-llm.md Deploy a model using the Xinference Python client and interact with it through chat. This example shows launching a 'chatglm2' model and querying it. ```python from xinference.client import Client client = Client("http://localhost:9997") model_uid = client.launch_model(model_name="chatglm2") # download model from HuggingFace and deploy model = client.get_model(model_uid) chat_history = [] prompt = "What is the largest animal?" model.chat( prompt, chat_history, generate_config={"max_tokens": 1024} ) ``` -------------------------------- ### Example KG Schema Source: https://github.com/biocypher/biochatter/blob/main/docs/vignettes/custom-decider-use-case.md This is the schema of our KG, illustrating the relationships between entities like Patient, SequenceVariant, Gene, and BiologicalProcess. ```mermaid graph TD; Patient[Patient] -->|PatientToSequenceVariantAssociation| SequenceVariant[SequenceVariant] Patient[Patient] -->|PatientToCopyNumberAlterationAssociation| CopyNumberAlteration[CopyNumberAlteration] SequenceVariant[SequenceVariant] -->|SequenceVariantToGeneAssociation| Gene[Gene] CopyNumberAlteration[CopyNumberAlteration] -->|CopyNumberAlterationToGeneAssociation| Gene[Gene] Gene[Gene] -->|GeneToBiologicalProcessAssociation| BiologicalProcess[BiologicalProcess] Gene[Gene] -->|GeneDruggabilityAssociation| Drug[Drug] ``` -------------------------------- ### Figure Setup and Data Aggregation for Plotting Source: https://github.com/biocypher/biochatter/blob/main/benchmark/Longevity_Data_Analysis.ipynb Initializes a matplotlib figure and grid specification for plotting. It also aggregates data by model and system prompt to prepare for detailed analysis. ```python sns.set_style(style = "whitegrid") fig = plt.figure(figsize=(20, 17)) gs = gridspec.GridSpec(ncols = 8, nrows = 5, figure=fig) axs = [ fig.add_subplot(gs[0, 1:7]), fig.add_subplot(gs[1, 1:7]), fig.add_subplot(gs[2, 1:7]), fig.add_subplot(gs[3, 1:7]), fig.add_subplot(gs[4, 1:7]), ] bplt_dfs = [] for model, pretty_model in model_mapping.items(): dfs = [] for sys_prompt, pretty_prompt in prompt_mapping.items(): df_helper = score_helper(df = df[ (df["model_name"] == model) & (df["subtask"].str.contains(sys_prompt)) & (df["subtask"].str.startswith("longevity")) ])[3].copy() df_helper["system_prompt"] = sys_prompt dfs.append(df_helper) bplt_dfs.append(pd.concat(dfs, ignore_index = True)) bplt_df = pd.concat(bplt_dfs, ignore_index = True) bplt_df = map_columns(df = bplt_df, model_mapping = model_mapping, prompt_mapping = prompt_mapping) bplt_df.reset_index(drop = True) ``` -------------------------------- ### Combinatorial RAG Interpretation Test Case with Prompt Variations Source: https://github.com/biocypher/biochatter/blob/main/docs/benchmark/developer.md Illustrates how to define a test case that can be combinatorially expanded into multiple tests by providing variations for input data, such as different prompt engineering strategies. This is useful for testing LLM sensitivity to prompt setup. ```yaml rag_interpretation: # test simple irrelevance judgement - case: explicit_relevance_no input: prompt: Which molecular pathways are associated with cancer? system_messages: simple: [ "You will receive a text fragment to help answer the user's question. Your task is to judge this text fragment for relevance to the user's question, and return either 'yes' or 'no'! Here is the fragment: ", "The earth is a globe.", ] more_explicit: [ "You will receive a text fragment to help answer the user's question. Your task is to judge this text fragment for relevance to the user's question, and return either 'yes' or 'no'; only respond with one word, do not offer explanation or justification! Here is the fragment: ", "The earth is a globe.", ] repeat_instruction: [ "You will receive a text fragment to help answer the user's question. You should only respond with 'yes' or 'no' without additional words. Your task is to judge this text fragment for relevance to the user's question, and return either 'yes' or 'no'; only respond with one word, do not offer explanation or justification! Here is the fragment: ", "The earth is a globe.", ] expected: answer: "no" ``` -------------------------------- ### Podcast Generation Workflow Source: https://github.com/biocypher/biochatter/blob/main/docs/features/podcast.md Load a document, initialize the podcaster, and generate the podcast. Optionally, convert the podcast to an audio file using specified text-to-speech models. ```python from biochatter.podcast import Podcaster from biochatter.vectorstore import DocumentReader # Load document reader = DocumentReader() document = reader.load_document("test/dcn.pdf") # Initialise podcaster podcaster = Podcaster(document) # Generate podcast (LLM task) podcaster.generate_podcast(characters_per_paragraph=5000) # Employ text-to-speech to generate audio file (optional) podcaster.podcast_to_file("test/test.mp3", model="tts-1-hd", voice="alloy") ``` -------------------------------- ### Initialize BioCypherQueryHandler Source: https://github.com/biocypher/biochatter/blob/main/docs/features/rag.md Sets up the query handler with the generated query, query language, knowledge graph information, and the original question for context-aware interaction. ```python from biochatter.query_interaction import BioCypherQueryHandler query_handler = BioCypherQueryHandler( query=query, query_lang="Cypher", kg_selected={ entities: ["Gene", "Disease"], relationships: ["GeneToDiseaseAssociation"], properties: {"Disease": ["name", "ICD10", "DSM5"]} }, question="Which genes are associated with mucoviscidosis?" ) ``` -------------------------------- ### Initialize KGQueryReflexionAgent Source: https://github.com/biocypher/biochatter/blob/main/docs/features/reflexion-agent.md Set up the KGQueryReflexionAgent by providing connection arguments for the graph database and a factory function to create conversation instances. Ensure the OPENAI_API_KEY environment variable is set. ```python import os from biochatter.llm_connect import GptConversation from biochatter.kg_langgraph_agent import KGQueryReflexionAgent def create_conversation(): conversation = GptConversation(model_name="gpt-3.5-turbo", prompts={}) conversation.set_api_key(os.getenv("OPENAI_API_KEY"), user="my_user") return conversation connection_args = { "host": "127.0.0.1", "port": "7687", } agent = KGQueryReflexionAgent( connection_args=connection_args, conversation_factory=create_conversation, ) ``` -------------------------------- ### Configure Benchmarked Models Source: https://github.com/biocypher/biochatter/blob/main/docs/benchmark/developer.md Set the benchmark to use only OpenAI models by assigning OPENAI_MODEL_NAMES to BENCHMARKED_MODELS. This simplifies setup for initial development. ```python BENCHMARKED_MODELS = OPENAI_MODEL_NAMES ``` -------------------------------- ### Build and Deploy BioChatter Light KG Source: https://github.com/biocypher/biochatter/blob/main/docs/vignettes/custom-bclight-simple.md Clone the BioCypher Pole KG repository and use docker-compose to build and deploy the KG along with the BioChatter Light web app with only the KG tab enabled. ```bash git clone https://github.com/biocypher/pole cd pole docker-compose up -d ``` -------------------------------- ### Disable Git LFS Smudge Globally Source: https://github.com/biocypher/biochatter/blob/main/README.md Configure Git LFS to skip downloading large files for all repositories. This is a one-time setup. ```bash git lfs install --skip-smudge git clone https://github.com/biocypher/biochatter.git ``` -------------------------------- ### Vector Database Integration for RAG Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Integrate with a vector database for semantic search and RAG capabilities. This example shows loading, embedding, and searching documents. ```python from biochatter.vectorstore import DocumentReader, DocumentEmbedder from langchain_openai import OpenAIEmbeddings # Initialize document reader and embedder reader = DocumentReader() # Create embedder with Milvus as vector store embedder = DocumentEmbedder( embedding_collection_name="your_embeddings", metadata_collection_name="your_metadata", connection_args={"host": "localhost", "port": "19530"} ) embedder.connect() # Load and embed a document document = reader.load_document("path/to/your/document.pdf") # Supports PDF and TXT doc_id = embedder.save_document(document) # Perform similarity search results = embedder.similarity_search( query="Your search query here", k=3 # Number of results to return ) # Clean up when needed embedder.remove_document(doc_id) ``` -------------------------------- ### Query with Additional Tool Instructions Source: https://github.com/biocypher/biochatter/blob/main/docs/features/tool_chat.md Provide additional instructions for tool usage directly within the `query` method. These instructions will override any provided during the conversation's initialization. ```python convo = LangChainConversation( model_provider="ollama", model_name="gemma3:27b", prompts={}, tools=#[your tool list here] ) #set the API key convo.set_api_key() #define the question question = "...Here your question..." #run the conversation convo.query(question,additional_tools_instructions="...Here your additional instructions...") ``` -------------------------------- ### Count Total Crimes Source: https://github.com/biocypher/biochatter/blob/main/docs/vignettes/kg.md Use this query to get the total number of crime nodes in the graph. This is useful for understanding the overall scale of crime data. ```cypher MATCH (c:Crime) RETURN count(c) AS numberOfCrimes ``` -------------------------------- ### Initialize Conversation with Additional Tool Instructions Source: https://github.com/biocypher/biochatter/blob/main/docs/features/tool_chat.md Provide additional instructions for tool usage directly in the class constructor when initializing the conversation. This sets the default instructions for the session. ```python convo = LangChainConversation( model_provider="ollama", model_name="gemma3:27b", prompts={}, tools=#[your tool list here], additional_tools_instructions="...Here your additional instructions..." ) #set the API key convo.set_api_key() #define the question question = "...Here your question..." #run the conversation convo.query(question,) ``` -------------------------------- ### Filter and Prepare Longevity Data Source: https://github.com/biocypher/biochatter/blob/main/benchmark/Longevity_Data_Analysis.ipynb Filters a DataFrame to include only rows where the 'subtask' column starts with 'longevity'. Creates a copy to avoid SettingWithCopyWarning. Requires pandas. ```python df_pathologies = df[df["subtask"].str.startswith("longevity")].copy() ``` -------------------------------- ### Clone BioChatter Next Repository Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Clone the BioChatter Next repository to start building your frontend application. This is the first step for the REST API/Next.js developer profile. ```bash git clone https://github.com/biocypher/biochatter-next ``` -------------------------------- ### API Agent for Biological Databases Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Connect to biological databases like OncoKB using the API Agent. This example demonstrates building, fetching, and interpreting API responses. ```python from biochatter.api_agent.base.api_agent import APIAgent from biochatter.api_agent.web.oncokb import OncoKBQueryBuilder, OncoKBFetcher, OncoKBInterpreter from biochatter.llm_connect import GptConversation # Create a conversation factory function def create_conversation(): conversation = GptConversation( model_name="gpt-3.5-turbo", # or your preferred model prompts={}, correct=False ) conversation.set_api_key(api_key="your-api-key") return conversation # Create API agent with OncoKB components agent = APIAgent( conversation_factory=create_conversation, # Function to create new conversations query_builder=OncoKBQueryBuilder(), # Builds queries for OncoKB API fetcher=OncoKBFetcher(), # Handles API requests interpreter=OncoKBInterpreter() # Interprets API responses ) # Execute query - this will: # 1. Build an appropriate OncoKB query # 2. Fetch results from the OncoKB API # 3. Interpret the results using the LLM result = agent.execute("What is the oncogenic potential of BRAF V600E mutation?") ``` -------------------------------- ### Import Libraries for Data Analysis Source: https://github.com/biocypher/biochatter/blob/main/benchmark/Data_Analysis.ipynb Imports necessary libraries for data manipulation, numerical operations, plotting, statistical analysis, and a specific library 'pingouin'. Ensure these libraries are installed before running. ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.stats import shapiro import pingouin as pg import matplotlib as mpl ``` -------------------------------- ### Run All Benchmarks Source: https://github.com/biocypher/biochatter/blob/main/docs/features/benchmark.md Execute all benchmark tests, including those already run. Use this to ensure a complete re-evaluation. ```bash poetry run pytest benchmark --run-all ``` -------------------------------- ### Run Podcast Script from Command Line Source: https://github.com/biocypher/biochatter/blob/main/docs/features/podcast.md Execute the podcast generation script from the command line. Specify input document and output file paths. If the output file has an .mp3 extension, audio will be generated using the OpenAI API. ```bash poetry run python scripts/podcast_single_document.py test/dcn.pdf test/test.mp3 ``` -------------------------------- ### Get ChEMBL ID Tool Source: https://github.com/biocypher/biochatter/blob/main/docs/features/structured_outputs.md A tool to retrieve the ChEMBL ID for a given drug name by querying the ChEMBL API. Includes error handling for request exceptions and invalid JSON. ```python @tool def get_chembl_id(drug_name: str) -> str: """ Given a drug name, look up and return its ChEMBL ID using the ChEMBL API. Example: get_chembl_id(drug_name="aspirin") """ url = "https://www.ebi.ac.uk/chembl/api/data/chembl_id_lookup/search.json" params = {"q": drug_name} headers = {"Accept": "application/json"} try: resp = requests.get(url, params=params, headers=headers, timeout=10) resp.raise_for_status() data = resp.json() hits = data.get("chembl_id_lookups", []) if not hits: return f"Unable to find ChEMBL ID for {drug_name}" return hits[0].get("chembl_id", f"No ChEMBL ID found in hit for {drug_name}") except requests.RequestException as e: return f"Error querying ChEMBL API for {drug_name}: {str(e)}" except ValueError: # If JSON parsing fails return f"Invalid JSON received from ChEMBL API for {drug_name}" ``` -------------------------------- ### Provide Tools for Entire Conversation Source: https://github.com/biocypher/biochatter/blob/main/docs/features/tool_chat.md Pass tools during initialization to make them available throughout the conversation. Ensure tools are defined and gathered into a list before creating the LangChainConversation instance. ```python #import the conversation class from biochatter.llm_connect import LangChainConversation # Tools definition is recycled from the previous section # Define the question question = "What is 334*54? And what about 345+123?" # Gather the tools into a list tools = [multiply, add] # Define the conversation convo = LangChainConversation( model_provider="google_genai", model_name="gemini-2.0-flash", prompts={}, tools=tools #<------ ) # Set the API key (read from the environment variable, based on the model provider) convo.set_api_key() # Run the conversation convo.query(question) ``` -------------------------------- ### Get Mechanisms of Action Tool Source: https://github.com/biocypher/biochatter/blob/main/docs/features/structured_outputs.md A tool to fetch mechanisms of action and target information for a drug using its ChEMBL ID via the OpenTargets GraphQL API. Handles API request errors and GraphQL errors. ```graphql _GRAPHQL_QUERY = """ query MechanismsOfActionSectionQuery($chemblId: String!) { drug(chemblId: $chemblId) { id mechanismsOfAction { rows { mechanismOfAction targetName targets { id approvedSymbol } } } } } """ ``` ```python @tool def get_mechanisms_of_action(chembl_id: str) -> Dict[str, Any]: """ Fetch mechanisms of action and target information for a given drug (by ChEMBL ID) using the OpenTargets GraphQL API. Example: get_mechanisms_of_action(chembl_id="CHEMBL25") """ endpoint = "https://api.platform.opentargets.org/api/v4/graphql" payload = {"query": _GRAPHQL_QUERY, "variables": {"chemblId": chembl_id}} try: resp = requests.post(endpoint, json=payload, headers={"Content-Type": "application/json"}, timeout=15) resp.raise_for_status() data = resp.json() if "errors" in data: return {"error": f"GraphQL errors for {chembl_id}: {data['errors']}"} return data.get("data", {}) except requests.RequestException as e: return {"error": f"Error querying OpenTargets API for {chembl_id}: {str(e)}"} except ValueError: # If JSON parsing fails return {"error": f"Invalid JSON received from OpenTargets API for {chembl_id}"} ``` -------------------------------- ### Run BioChatter Light with Docker Source: https://github.com/biocypher/biochatter/blob/main/docs/quickstart.md Use this command to run the BioChatter Light Docker image. Ensure port 8501 is available. ```bash docker run -d -p 8501:8501 biocypher/biochatter-light --env-file .env ``` -------------------------------- ### Select Entities for Query Source: https://github.com/biocypher/biochatter/blob/main/docs/features/rag.md Initiates the entity selection process based on the user's question, utilizing schema configuration files. Returns a boolean indicating success. ```python success = prompt_engine._select_entities( question="Which genes are associated with mucoviscidosis?" ) ``` -------------------------------- ### Request Structured Output for Gene Information Source: https://github.com/biocypher/biochatter/blob/main/docs/features/structured_outputs.md Initialize a LangChainConversation and query the LLM, passing a Pydantic model to the `structured_model` parameter to receive structured JSON output. This example demonstrates setting up the conversation, making the query, and accessing the structured response. ```python from biochatter.llm_connect import LangChainConversation from pydantic import BaseModel import json # Define your Pydantic model class GeneInfo(BaseModel): gene_symbol: str full_name: str summary: str chromosome_location: str | None = None # Initialize the conversation convo = LangChainConversation( model_provider="google_genai", # Or any other supported provider model_name="gemini-2.0-flash", # Ensure model supports structured output or use fallback prompts={}, ) # Set API key if required convo.set_api_key() # Make the query, passing the Pydantic model question = "Provide information about the human gene TP53, including its full name and a summary of its function." convo.query(question, structured_model=GeneInfo) # Access the structured output # The last AI message will contain the JSON string of the structured output structured_response_json = convo.messages[-1].content print(structured_response_json) # You can then parse this JSON string back into your Pydantic model gene_data = json.loads(structured_response_json) my_gene_info = GeneInfo(**gene_data) print(f"Gene Symbol: {my_gene_info.gene_symbol}") print(f"Full Name: {my_gene_info.full_name}") print(f"Summary: {my_gene_info.summary}") if my_gene_info.chromosome_location: print(f"Location: {my_gene_info.chromosome_location}") ``` -------------------------------- ### Data Preparation for Performance Visualization Source: https://github.com/biocypher/biochatter/blob/main/benchmark/Longevity_Data_Analysis.ipynb Prepares and categorizes data for plotting LLM performance. It involves filtering, mapping model and prompt names, and setting categorical orders for system prompts and model names. ```python #from cmcrameri import cm import matplotlib.gridspec as gridspec frames = [] for sys_prompt, pretty_prompt in prompt_mapping.items(): dfs = [] for subtask, pretty_subtask in subtask_mapping.items(): df_helper = score_helper(df[(df["subtask"].str.contains(sys_prompt)) & (df["subtask"].str.contains(subtask)) & (df["subtask"].str.startswith("longevity"))])[3] df_helper["system_prompt"] = sys_prompt df_helper["subtask"] = subtask dfs.append(df_helper) frames.append(pd.concat(dfs, ignore_index = True)) df_strip = pd.concat(frames, ignore_index = True) df_strip = map_columns(df = df_strip, model_mapping = model_mapping, prompt_mapping = prompt_mapping, subtask_mapping = subtask_mapping) custom_prompt_order = ["Minimal", "Specific", "Role Encouraging", "Req. specific", "Req. explicit"] custom_model_order = ["Llama 3.2 3B", "Qwen 2.5 14B", "DSR Llama 70B", "GPT-4o", "o3 mini", "GPT-4o mini"] df_strip["system_prompt"] = pd.Categorical(df_strip["system_prompt"], categories = custom_prompt_order, ordered = True) df_strip["model_name"] = pd.Categorical(df_strip["model_name"], categories = custom_model_order, ordered = True) ``` -------------------------------- ### Configure BioChatter Light Docker Container Source: https://github.com/biocypher/biochatter/blob/main/docs/vignettes/custom-bclight-simple.md Customize the BioChatter Light Docker container by setting environment variables in the `docker-compose.yml` file. This example disables chat, prompt engineering, RAG, and correcting agent tabs while enabling the Knowledge Graph tab. ```yaml services: ## ... build, import, and deploy the KG ... app: image: biocypher/biochatter-light:0.6.10 container_name: app ports: - "8501:8501" networks: - biochatter depends_on: import: condition: service_completed_successfully environment: - OPENAI_API_KEY=${OPENAI_API_KEY} - DOCKER_COMPOSE=true - CHAT_TAB=false - PROMPT_ENGINEERING_TAB=false - RAG_TAB=false - CORRECTING_AGENT_TAB=false - KNOWLEDGE_GRAPH_TAB=true ``` -------------------------------- ### Color and Mapping Definitions for Longevity Data Analysis Source: https://github.com/biocypher/biochatter/blob/main/benchmark/Longevity_Data_Analysis.ipynb Defines color palettes and mappings for various categories used in analyzing longevity data, such as model names, metrics, prompt types, subtasks, and age groups. This setup is crucial for consistent data visualization. ```python colours = { "Comprehensiveness": "#7d6274", "Correctness": "#b0a6bf", "Usefulness": "#644c5f", "Interpr./Expl.": "#513846", "Consideration of Toxicity": "#000000", "Minimal": "#eaaacc", "Specific": "#e492b6", "Role Encouraging": "#e58996", "Req. specific": "#db6480", "Req. explicit": "#701f62", "Young": "#a0d6b4", "Mid-Age\nPregeriatric": "#5f9ea0", "Geriatric": "#317873", "Short": "#ff835a", "Verbose": "#ffb69e", "List Style": "#a989c4", "Paragraph Style": "#5f447b", "No Distractor": "#b58174", "Distractor": "#7b5146", "cautious": "#e30744", "definitive": "#6db7c6", "Llama 3.2 3B": "#b0ccdf", "Qwen 2.5 14B": "#bb71b2", "DSR Llama 70B": "#726699", "GPT-4o": "#d26161", "GPT-4o mini": "#c0c0c0", "o3 mini": "#4fa883", } model_mapping = { "llama-3.2-3b-instruct": "Llama 3.2 3B", "qwen2.5-14b-instruct": "Qwen 2.5 14B", "deepseek-r1-distill-llama-70b": "DSR Llama 70B", "gpt-4o-2024-11-20": "GPT-4o", "gpt-4o-mini-2024-07-18": "GPT-4o mini", "o3-mini": "o3 mini", } metric_mapping = { "correctness": "Correctness", "comprehensiveness": "Comprehensiveness", "usefulness": "Usefulness", "interpretability_explainability": "Interpr./Expl.", "toxicity": "Consideration of Toxicity", } prompt_mapping = { "minimal": "Minimal", "specific": "Specific", "role_encouraging": "Role Encouraging", "requirements_specific": "Req. specific", "requirements_explicit": "Req. explicit", } # prompt_mapping = { # "minimal": "Minimal", # ":specific": "Specific", # "role_encouraging": "Role Encouraging", # ":requirements_specific": "Req. specific", # ":requirements_explicit": "Req. explicit", # } subtask_mapping = { "short": "Short", "verbose": "Verbose", "no_distractor": "No Distractor", ":distractor": "Distractor", "list": "List Style", ":paragraph": "Paragraph Style", } age_mapping = { "young": "Young", "geriatric": "Geriatric", "mid-aged/pregeriatric": "Mid-Age\nPregeriatric", } intervention_mapping = { "caloric_restriction": "CR", "caloric_restriction_and_exercise": "CR + Exercise", "intermittent_fasting": "IF", "exercise": "Exercise", "epicatechin": "Epicatechin", "fisetin": "Fisetin", "spermidine": "Spermidine", "rapamycin": "Rapamycin", } ``` -------------------------------- ### Generate Query with Individual Steps Source: https://github.com/biocypher/biochatter/blob/main/docs/features/rag.md Constructs a database query by explicitly providing the question, selected entities, relationships, properties, and the target database language. ```python query = prompt_engine._generate_query( question="Which genes are associated with mucoviscidosis?", entities=["Gene", "Disease"], relationships=["GeneToDiseaseAssociation"], properties={"Disease": ["name", "ICD10", "DSM5"]}, database_language="Cypher", ) ``` -------------------------------- ### Print Default Tool Interpretation Prompts Source: https://github.com/biocypher/biochatter/blob/main/docs/features/tool_chat.md Access and print the default prompts used for general and additional tool interpretation from the conversation object. ```python print(convo.general_instructions_tool_interpretation) print(convo.additional_instructions_tool_interpretation) ``` -------------------------------- ### Run Specific Benchmarks Source: https://github.com/biocypher/biochatter/blob/main/docs/features/benchmark.md Execute the benchmark suite. By default, it checks for and runs only unexecuted test cases. ```bash poetry run pytest benchmark ``` -------------------------------- ### Implement NewAPI Fetcher Source: https://github.com/biocypher/biochatter/blob/main/docs/features/api.md Create a class inheriting from BaseFetcher to handle data retrieval from the target API. Configure request headers if API tokens are needed and implement logic to construct the full URL and execute the API call. ```python from biochatter.api_agent.base.agent_abc import BaseFetcher class NewAPIFetcher(BaseFetcher): def __init__(self,): self.headers = { } self.base_url = "https://api.new.org/api/" def fetch_results( self, query_model: NewAPIQueryParameters, retries: int = 3, ) -> str: #implement your logic here return results_response.text ``` -------------------------------- ### Implement NewAPI Query Builder Source: https://github.com/biocypher/biochatter/blob/main/docs/features/api.md Create a class inheriting from BaseQueryBuilder to handle query parameterization. This involves creating a runnable object for structured output and invoking it to generate API parameters from a user question. ```python from biochatter.api_agent.base.agent_abc import BaseQueryBuilder class NewAPIQueryBuilder(BaseQueryBuilder): def create_runnable(self, query_parameters: NewAPIQueryParameters, conversation: Conversation ) -> Callable: # Implement method to create a runnable query object return create_structured_output_runnable( output_schema=query_parameters, llm=conversation.chat, prompt=self.structured_output_prompt, ) def parameterise_query( self, question: str, conversation: Conversation ) -> NewAPIQueryParameters: # Implement method to generate API parameters from a question runnable = self.create_runnable( query_parameters=NewAPIQueryParameters, conversation=conversation, ) NewAPI_call_obj = runnable.invoke( {"input": f"Answer:\n{question} based on:\n {NewAPI_QUERY_PROMPT}"} ) NewAPI_call_obj.question_uuid = str(uuid.uuid4()) return NewAPI_call_obj ```