Adding custom tools to tutors

OpenAI assistants and Ollama and Anthropic chats have, when instructed how, the capability to request function calls to be performed. Tutors mirror that capability.

To use it, we first need to define the function.

tool := GtLlmFunctionTool new
		name: 'lookupDocumentationPage';
		parameters: {'pageName'};
		description: 'Looks up a documentation page by name and returns its content in Markdown format. `pageName` may be a substring. If multiple pages are found, only the first one will be returned.';
		block: [ :arguments | 
			LeDatabase gtBook pages
				detect: [ :aPage | aPage title includesSubstring: arguments first caseSensitive: false ]
				ifFound: #asMarkdownPage
				ifNone: 'No page found' ]
  

We can then add it to the tutor’s provider. Please note that due to a technical limitation, tools and structured outputs do not play well together with Ollama tutors [1], and Anthropic does not formally support structured outputs [2]. Otherwise, both providers are equivalent.

tutor := GtLlmTutor new
		description: 'You are an assistant that answers questions about Glamorous Toolkit (also: GToolkit or GT) by referring to the GToolkit book through tool search.';
		providerStencil: [ :anInstructionFormat | 
			GtOpenAIAssistantProvider withApiKeyFromFile
				format: anInstructionFormat asJsonSchema;
				assistantMessageClass: GtOpenAIActionMessage;
				userMessageClass: GtOpenAIActionMessage;
				addTool: tool;
				instructions: anInstructionFormat asInstructionPiece instructionString ].

tutor
  

Finally, we can use the chat as before.

chat := tutor createChat.
chat sendChatRequest: 'Tell me about gt4llm.'
  

[1] This is because OpenAI uses a signal to interrupt the conversation to request a tool call and then resumes answering the question. In Ollama, the tool call is embedded in the answer, thus it’s an in-band communication channel.

[2] It is however usually able to adhere to the format even when not forced to.