Tilores
This notebook covers how to get started with theTilores tools.For a more complex example you can checkout ourcustomer insights chatbot example.
Overview
Integration details
Class | Package | Serializable | JS support | Package latest |
---|---|---|---|---|
TiloresTools | tilores-langchain | ❌ | ❌ |
Setup
The integration requires the following packages:
%pip install--quiet-U tilores-langchain langchain
Note: you may need to restart the kernel to use updated packages.
Credentials
To access Tilores, you need tocreate and configure an instance. If you prefer to test out Tilores first, you can use theread-only demo credentials.
import os
os.environ["TILORES_API_URL"]="<api-url>"
os.environ["TILORES_TOKEN_URL"]="<token-url>"
os.environ["TILORES_CLIENT_ID"]="<client-id>"
os.environ["TILORES_CLIENT_SECRET"]="<client-secret>"
Instantiation
Here we show how to instantiate an instance of the Tilores tools:
from tiloresimport TiloresAPI
from tilores_langchainimport TiloresTools
tilores= TiloresAPI.from_environ()
tilores_tools= TiloresTools(tilores)
search_tool= tilores_tools.search_tool()
edge_tool= tilores_tools.edge_tool()
Invocation
The parameters for thetilores_search
tool are dependent on theconfigured schema within Tilores. The following examples will use the schema for the demo instance with generated data.
Invoke directly with args
The following example searches for a person called Sophie Müller in Berlin. The Tilores data contains multiple such persons and returns their known email addresses and phone numbers.
result= search_tool.invoke(
{
"searchParams":{
"name":"Sophie Müller",
"city":"Berlin",
},
"recordFieldsToQuery":{
"email":True,
"phone":True,
},
}
)
print("Number of entities:",len(result["data"]["search"]["entities"]))
for entityin result["data"]["search"]["entities"]:
print("Number of records:",len(entity["records"]))
print(
"Email Addresses:",
[record["email"]for recordin entity["records"]if record.get("email")],
)
print(
"Phone Numbers:",
[record["phone"]for recordin entity["records"]if record.get("phone")],
)
Number of entities: 3
Number of records: 3
Email Addresses: ['s.mueller@newcompany.de', 'sophie.mueller@email.de']
Phone Numbers: ['30987654', '30987654', '30987654']
Number of records: 5
Email Addresses: ['mueller.sophie@uni-berlin.de', 'sophie.m@newshipping.de', 's.mueller@newfinance.de']
Phone Numbers: ['30135792', '30135792']
Number of records: 2
Email Addresses: ['s.mueller@company.de']
Phone Numbers: ['30123456', '30123456']
If we're interested how the records from the first entity are related, we can use the edge_tool. Note that the Tilores entity resolution engine figured out the relation between those records automatically. Please refer to theedge documentation for more details.
edge_result= edge_tool.invoke(
{"entityID": result["data"]["search"]["entities"][0]["id"]}
)
edges= edge_result["data"]["entity"]["entity"]["edges"]
print("Number of edges:",len(edges))
print("Edges:", edges)
Number of edges: 7
Edges: ['e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6:f2g3h4i5-j6k7-l8m9-n0o1-p2q3r4s5t6u7:L1', 'e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6:g3h4i5j6-k7l8-m9n0-o1p2-q3r4s5t6u7v8:L4', 'e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6:f2g3h4i5-j6k7-l8m9-n0o1-p2q3r4s5t6u7:L2', 'f2g3h4i5-j6k7-l8m9-n0o1-p2q3r4s5t6u7:g3h4i5j6-k7l8-m9n0-o1p2-q3r4s5t6u7v8:L1', 'f2g3h4i5-j6k7-l8m9-n0o1-p2q3r4s5t6u7:g3h4i5j6-k7l8-m9n0-o1p2-q3r4s5t6u7v8:L4', 'e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6:g3h4i5j6-k7l8-m9n0-o1p2-q3r4s5t6u7v8:L1', 'e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6:f2g3h4i5-j6k7-l8m9-n0o1-p2q3r4s5t6u7:L4']
Invoke with ToolCall
We can also invoke the tool with a model-generated ToolCall, in which case a ToolMessage will be returned:
# This is usually generated by a model, but we'll create a tool call directly for demo purposes.
model_generated_tool_call={
"args":{
"searchParams":{
"name":"Sophie Müller",
"city":"Berlin",
},
"recordFieldsToQuery":{
"email":True,
"phone":True,
},
},
"id":"1",
"name": search_tool.name,
"type":"tool_call",
}
search_tool.invoke(model_generated_tool_call)
ToolMessage(content='{"data": {"search": {"entities": [{"id": "9601cf3b-e85f-46ab-aaa8-ffb8b46f1c5b", "hits": {"c3d4e5f6-g7h8-i9j0-k1l2-m3n4o5p6q7r8": ["L1"]}, "records": [{"email": "", "phone": "30123456"}, {"email": "s.mueller@company.de", "phone": "30123456"}]}, {"id": "03da2e11-0aa2-4d17-8aaa-7b32c52decd9", "hits": {"e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6": ["L1"], "g3h4i5j6-k7l8-m9n0-o1p2-q3r4s5t6u7v8": ["L1"]}, "records": [{"email": "s.mueller@newcompany.de", "phone": "30987654"}, {"email": "", "phone": "30987654"}, {"email": "sophie.mueller@email.de", "phone": "30987654"}]}, {"id": "4d896fb5-0d08-4212-a043-b5deb0347106", "hits": {"j6k7l8m9-n0o1-p2q3-r4s5-t6u7v8w9x0y1": ["L1"], "l8m9n0o1-p2q3-r4s5-t6u7-v8w9x0y1z2a3": ["L1"], "m9n0o1p2-q3r4-s5t6-u7v8-w9x0y1z2a3b4": ["L1"], "n0o1p2q3-r4s5-t6u7-v8w9-x0y1z2a3b4c5": ["L1"]}, "records": [{"email": "mueller.sophie@uni-berlin.de", "phone": ""}, {"email": "sophie.m@newshipping.de", "phone": ""}, {"email": "", "phone": "30135792"}, {"email": "", "phone": ""}, {"email": "s.mueller@newfinance.de", "phone": "30135792"}]}]}}}', name='tilores_search', tool_call_id='1')
Chaining
We can use our tool in a chain by first binding it to atool-calling model and then calling it:
pip install -qU "langchain[google-genai]"
import getpass
import os
ifnot os.environ.get("GOOGLE_API_KEY"):
os.environ["GOOGLE_API_KEY"]= getpass.getpass("Enter API key for Google Gemini: ")
from langchain.chat_modelsimport init_chat_model
llm= init_chat_model("gemini-2.0-flash", model_provider="google_genai")
from langchain_core.promptsimport ChatPromptTemplate
from langchain_core.runnablesimport RunnableConfig, chain
prompt= ChatPromptTemplate(
[
("system","You are a helpful assistant."),
("human","{user_input}"),
("placeholder","{messages}"),
]
)
# specifying tool_choice will force the model to call this tool.
llm_with_tools= llm.bind_tools([search_tool], tool_choice=search_tool.name)
llm_chain= prompt| llm_with_tools
@chain
deftool_chain(user_input:str, config: RunnableConfig):
input_={"user_input": user_input}
ai_msg= llm_chain.invoke(input_, config=config)
tool_msgs= search_tool.batch(ai_msg.tool_calls, config=config)
return llm_chain.invoke({**input_,"messages":[ai_msg,*tool_msgs]}, config=config)
tool_chain.invoke("Tell me the email addresses from Sophie Müller from Berlin.")
API reference
For detailed documentation of all Tilores features and configurations head to the official documentation:https://docs.tilotech.io/tilores/
Related
- Toolconceptual guide
- Toolhow-to guides