Hi! I’ve been trying to use the Langchain library in Palantir. However, the only method I’ve found requires the use of an personal Open API key, using external resource method in Palantir.
Is there a way to utilize our company’s Palantir AIP tokens instead?
To use langchain in a transform, you could use a Palantir-provided model in a transform and wrap that in a small wrapper in langchain: https://python.langchain.com/v0.2/docs/how_to/custom_llm/
Thank you for your feedback.
I tried my best but only palantir_llm.invoke(question) option I made is feasible.
My purpose of applying langchain is that using various option including pipeline but not working with small wrapping.
from transforms.api import transform, Input, Output
from palantir_models.transforms import OpenAiGptChatLanguageModelInput
from palantir_models.models import OpenAiGptChatLanguageModel
from language_model_service_api.languagemodelservice_api_completion_v3 import GptChatCompletionRequest
from language_model_service_api.languagemodelservice_api import ChatMessage, ChatMessageRole
import pandas as pd
import logging
from typing import Optional, List, Any, Tuple
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class LLM:
"""Base class for Language Models."""
def _call(self, prompt: str, stop: Optional[List[str]] = None, **kwargs: Any) -> str:
raise NotImplementedError
@property
def _llm_type(self) -> str:
raise NotImplementedError
class PalantirLLM(LLM):
"""A custom LLM wrapper for Palantir-provided language models."""
def __init__(self, model: OpenAiGptChatLanguageModel):
self.model = model
logger.info("PalantirLLM initialized with model: %s", model)
def invoke(
self,
prompt: str,
stop: Optional[List[str]] = None,
**kwargs: Any,
) -> str:
"""Run the LLM on the given input."""
logger.info("Generating response for prompt: %s", prompt)
system_prompt = "Answer the following question"
request = GptChatCompletionRequest(
[ChatMessage(ChatMessageRole.SYSTEM, system_prompt), ChatMessage(ChatMessageRole.USER, prompt)]
)
try:
resp = self.model.create_chat_completion(request)
logger.info("Response received: %s", resp.choices[0].message.content)
return resp.choices[0].message.content
except Exception as e:
logger.error("Error during API call: %s", e)
return "Error generating response"
@property
def _llm_type(self) -> str:
"""Get the type of language model used by this chat model. Used for logging purposes only."""
return "palantir"
@transform(
model=OpenAiGptChatLanguageModelInput("ri.language-model-service..language-model.gpt-4-o"),
output=Output("ri.foundry.main.dataset.83708b87-7551-44f3-8579-bce00edb67e5"),
)
def compute_answer(ctx, model: OpenAiGptChatLanguageModel, output):
logger.info("Starting compute_answer transform")
question = "ChatGPT에 대해 설명 해 주세요"
palantir_llm = PalantirLLM(model)
answer = palantir_llm.invoke(question)
logger.info("Generated answer: %s", answer)
# Assuming you want to save the answer to a dataset
try:
answer_df = pd.DataFrame({"question": [question], "answer": [answer]})
spark_df = ctx.spark_session.createDataFrame(answer_df)
output.write_dataframe(spark_df)
logger.info("Answer saved to dataset")
except Exception as e:
logger.error("Error saving to dataset: %s", e)
Are you getting an error? You could try using the debugger to inspect it and make sure it’s behaving like you expect.
There is no error but I cannot use full Langchain option with that wrapping code…
Hi Jacob,
My team was also interested in getting Langchain to work with the palantir_models (https://www.palantir.com/docs/foundry/integrate-models/language-models-transforms-inputs#openaigptchatlanguagemodelinput) library. Through looking at your code and Langchain custom LLM class documentation (https://python.langchain.com/docs/how_to/custom_llm/), here is how I wrapped the Palantir model to get it to run in a 1) Jupyter code repository and 2) Python transforms repository. You’ll have to modify the code slightly for your use case. Hope this helps!
1) Jupyter code repository
from typing import Any, Dict, Iterator, List, Mapping, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM
from langchain_core.outputs import GenerationChunk
class CustomLLM(LLM):
"""A custom chat model that echoes the first `n` characters of the input.
When contributing an implementation to LangChain, carefully document
the model including the initialization parameters, include
an example of how to initialize the model and include any relevant
links to the underlying models documentation or API.
Example:
.. code-block:: python
model = CustomChatModel(n=2)
result = model.invoke([HumanMessage(content="hello")])
result = model.batch([[HumanMessage(content="hello")],
[HumanMessage(content="world")]])
"""
model: OpenAiGptChatLanguageModel
"""The number of characters from the last message of the prompt to be echoed."""
def _call(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> str:
"""Run the LLM on the given input.
Override this method to implement the LLM logic.
Args:
prompt: The prompt to generate from.
stop: Stop words to use when generating. Model output is cut off at the
first occurrence of any of the stop substrings.
If stop tokens are not supported consider raising NotImplementedError.
run_manager: Callback manager for the run.
**kwargs: Arbitrary additional keyword arguments. These are usually passed
to the model provider API call.
Returns:
The model output as a string. Actual completions SHOULD NOT include the prompt.
"""
system_prompt = "Answer the following question"
request = GptChatCompletionRequest(
[ChatMessage(ChatMessageRole.SYSTEM, system_prompt), ChatMessage(ChatMessageRole.USER, prompt)]
)
try:
resp = self.model.create_chat_completion(request)
return resp.choices[0].message.content
except Exception as e:
return "Error generating response"
def _stream(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> Iterator[GenerationChunk]:
"""Stream the LLM on the given prompt.
This method should be overridden by subclasses that support streaming.
If not implemented, the default behavior of calls to stream will be to
fallback to the non-streaming version of the model and return
the output as a single chunk.
Args:
prompt: The prompt to generate from.
stop: Stop words to use when generating. Model output is cut off at the
first occurrence of any of these substrings.
run_manager: Callback manager for the run.
**kwargs: Arbitrary additional keyword arguments. These are usually passed
to the model provider API call.
Returns:
An iterator of GenerationChunks.
"""
for char in prompt[: self.n]:
chunk = GenerationChunk(text=char)
if run_manager:
run_manager.on_llm_new_token(chunk.text, chunk=chunk)
yield chunk
@property
def _identifying_params(self) -> Dict[str, Any]:
"""Return a dictionary of identifying parameters."""
return {
# The model name allows users to specify custom token counting
# rules in LLM monitoring applications (e.g., in LangSmith users
# can provide per token pricing for their model and monitor
# costs for the given LLM.)
"model_name": "CustomChatModel",
}
@property
def _llm_type(self) -> str:
"""Get the type of language model used by this chat model. Used for logging purposes only."""
return "custom"
model = OpenAiGptChatLanguageModel.get("GPT_4o")
llm = CustomLLM(model=model)
print(llm)
from langchain_core.prompts import PromptTemplate
llm.invoke("How are you doing?")
2. Python transforms repository
from typing import Any, Dict, Iterator, List, Mapping, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM
from langchain_core.outputs import GenerationChunk
from pyspark.sql import DataFrame
from transforms.api import Input, Output, transform
from palantir_models.transforms import OpenAiGptChatLanguageModelInput
from palantir_models.models import OpenAiGptChatLanguageModel
from language_model_service_api.languagemodelservice_api_completion_v3 import GptChatCompletionRequest
from language_model_service_api.languagemodelservice_api import ChatMessage, ChatMessageRole
import pandas as pd
from myproject.datasets import utils
class CustomLLM(LLM):
"""A custom chat model that echoes the first `n` characters of the input.
When contributing an implementation to LangChain, carefully document
the model including the initialization parameters, include
an example of how to initialize the model and include any relevant
links to the underlying models documentation or API.
Example:
.. code-block:: python
model = CustomChatModel(n=2)
result = model.invoke([HumanMessage(content="hello")])
result = model.batch([[HumanMessage(content="hello")],
[HumanMessage(content="world")]])
"""
model: OpenAiGptChatLanguageModel
"""The number of characters from the last message of the prompt to be echoed."""
def _call(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> str:
"""Run the LLM on the given input.
Override this method to implement the LLM logic.
Args:
prompt: The prompt to generate from.
stop: Stop words to use when generating. Model output is cut off at the
first occurrence of any of the stop substrings.
If stop tokens are not supported consider raising NotImplementedError.
run_manager: Callback manager for the run.
**kwargs: Arbitrary additional keyword arguments. These are usually passed
to the model provider API call.
Returns:
The model output as a string. Actual completions SHOULD NOT include the prompt.
"""
system_prompt = "Answer the following question"
request = GptChatCompletionRequest(
[ChatMessage(ChatMessageRole.SYSTEM, system_prompt), ChatMessage(ChatMessageRole.USER, prompt)]
)
try:
resp = self.model.create_chat_completion(request)
return resp.choices[0].message.content
except Exception as e:
print("Error during API call: %s", e)
return "Error generating response"
def _stream(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> Iterator[GenerationChunk]:
"""Stream the LLM on the given prompt.
This method should be overridden by subclasses that support streaming.
If not implemented, the default behavior of calls to stream will be to
fallback to the non-streaming version of the model and return
the output as a single chunk.
Args:
prompt: The prompt to generate from.
stop: Stop words to use when generating. Model output is cut off at the
first occurrence of any of these substrings.
run_manager: Callback manager for the run.
**kwargs: Arbitrary additional keyword arguments. These are usually passed
to the model provider API call.
Returns:
An iterator of GenerationChunks.
"""
for char in prompt[: self.n]:
chunk = GenerationChunk(text=char)
if run_manager:
run_manager.on_llm_new_token(chunk.text, chunk=chunk)
yield chunk
@property
def _identifying_params(self) -> Dict[str, Any]:
"""Return a dictionary of identifying parameters."""
return {
# The model name allows users to specify custom token counting
# rules in LLM monitoring applications (e.g., in LangSmith users
# can provide per token pricing for their model and monitor
# costs for the given LLM.)
"model_name": "CustomChatModel",
}
@property
def _llm_type(self) -> str:
"""Get the type of language model used by this chat model. Used for logging purposes only."""
return "custom"
@transform(
model=OpenAiGptChatLanguageModelInput("ri.language-model-service..language-model.gpt-4-o"),
output=Output("insert-your-output-rid-here")
)
def compute_answer(ctx, model: OpenAiGptChatLanguageModel, output):
import numpy as np
question = "Why is the sky blue?"
wrapped_llm = CustomLLM(model=model)
answer = wrapped_llm.invoke(question)
try:
answer_df = pd.DataFrame({"question": [question], "answer": [answer]})
spark_df = ctx.spark_session.createDataFrame(answer_df)
output.write_dataframe(spark_df)
except Exception as e:
print(f"Error saving to dataset: {e}")
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.