Documentation Index
Fetch the complete documentation index at: https://docs.langchain.com/llms.txt
Use this file to discover all available pages before exploring further.
This notebook covers how to get started with the Tilores tools.
For a more complex example you can checkout our customer insights chatbot example.
Overview
Integration details
| Class | Package | Serializable | JS support | Version |
|---|
TiloresTools | tilores-langchain | ❌ | ❌ |  |
Setup
The integration requires the following packages:
pip install --quiet -U tilores-langchain langchain
Credentials
To access Tilores, you need to create and configure an instance. If you prefer to test out Tilores first, you can use the read-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 tilores import TiloresAPI
from tilores_langchain import 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 the tilores_search tool are dependent on the configured schema within Tilores. The following examples will use the schema for the demo instance with generated data.
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 entity in result["data"]["search"]["entities"]:
print("Number of records:", len(entity["records"]))
print(
"Email Addresses:",
[record["email"] for record in entity["records"] if record.get("email")],
)
print(
"Phone Numbers:",
[record["phone"] for record in 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 the edge 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']
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 a tool-calling model and then calling it:
# | output: false
# | echo: false
# !pip install -qU langchain langchain-openai
from langchain.chat_models import init_chat_model
model = init_chat_model(model="gpt-5.4", model_provider="openai")
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import 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.
model_with_tools = model.bind_tools([search_tool], tool_choice=search_tool.name)
model_chain = prompt | model_with_tools
@chain
def tool_chain(user_input: str, config: RunnableConfig):
input_ = {"user_input": user_input}
ai_msg = model_chain.invoke(input_, config=config)
tool_msgs = search_tool.batch(ai_msg.tool_calls, config=config)
return model_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: docs.tilotech.io/tilores/