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 Package latest TiloresTools tilores-langchain ❌ ❌ SetupThe 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 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']
Invoke with ToolCall
We can also invoke the tool with a model-generated ToolCall, in which case a ToolMessage will be returned:
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:
pip install -qU "langchain[google-genai]"
import getpass
import os
if not os.environ.get("GOOGLE_API_KEY"):
os.environ["GOOGLE_API_KEY"] = getpass.getpass("Enter API key for Google Gemini: ")
from langchain.chat_models import init_chat_model
llm = init_chat_model("gemini-2.5-flash", model_provider="google_genai")
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}"),
]
)
llm_with_tools = llm.bind_tools([search_tool], tool_choice=search_tool.name)
llm_chain = prompt | llm_with_tools
@chain
def tool_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/
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4