Skip to content

Commit a9fd638

Browse files
committed
WIP
1 parent de259ea commit a9fd638

File tree

2 files changed

+82
-56
lines changed

2 files changed

+82
-56
lines changed

llms_wrapper/llms.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,49 @@ def make_tooling(functions: Union[Callable, List[Callable]]) -> List[Dict]:
337337
"""
338338
Automatically create the tooling descriptions for a function or list of functions, based on the
339339
function(s) documentation strings.
340+
341+
The documentation string for each of the functions should be in in a format supported
342+
by the docstring_parser package (Google, Numpy, or ReST).
343+
344+
The description of the function should be given in detail and in a way that will
345+
be useful to the LLM. The same goes for the description of each of the arguments for
346+
the function.
347+
348+
With the ReST docustring format, use :param argname: description followed by
349+
a new line, then the type of the argument specified via :type argname: type.
350+
Specify the description of the return value via :returns: description followed
351+
by a new line, then the type of the return value specified via :rtype: type.
352+
The description should have one summary line, followed by a blank line then
353+
followed by the detailed description text.
354+
355+
IMPORTANT: the standard python type names are not supported, instead use the json
356+
schema types: string, number, integer, boolean, array, object, null. object can be
357+
used to specify a dictionary type.
358+
If you need to specify complex nested types, avoid using this method and instead
359+
create the tooling descriptions directly, using a nested json schema e.g.
360+
to specify a list of dictionaries with the key 'name' of type string and 'age' of type integer:
361+
```
362+
{
363+
"type": "array",
364+
"items": {
365+
"type": "object",
366+
"properties": {
367+
"name": {"type": "string"},
368+
"age": {"type": "integer"}
369+
},
370+
"required": ["name", "age"]
371+
}
372+
"description": "A list of people with their name and age"
373+
}
374+
```
375+
See https://platform.openai.com/docs/guides/function-calling
376+
377+
Args:
378+
functions: a function or list of functions. The function(s) documentation strings are parsed
379+
to create the tooling descriptions.
380+
381+
Returns:
382+
A list of tool dictionaries, each dictionary describing a tool.
340383
"""
341384
if not isinstance(functions, list):
342385
functions = [functions]
@@ -449,10 +492,12 @@ def query(
449492
Args:
450493
llmalias: the alias/name of the LLM to query
451494
messages: a list of message dictionaries with role and content keys
452-
tools: TBD
495+
tools: a list of tool dictionaries, each dictionary describing a tool.
496+
See https://docs.litellm.ai/docs/completion/function_call for the format.
497+
However, this can be created using the `make_tooling` function.
453498
return_cost: whether or not LLM invocation costs should get returned
454499
return_response: whether or not the complete reponse should get returned
455-
debug: if True, debug logging is enabled
500+
debug: if True, emits debug messages to aid development and debugging
456501
litellm_debug: if True, litellm debug logging is enabled, if False, disabled, if None, use debug setting
457502
kwargs: any additional keyword arguments to pass on to the LLM
458503

notebooks/dev-tooling.ipynb

Lines changed: 35 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@
176176
},
177177
{
178178
"cell_type": "code",
179-
"execution_count": null,
179+
"execution_count": 1,
180180
"id": "a6da6e33-e3dd-45d3-abad-ad48a617b1db",
181181
"metadata": {},
182182
"outputs": [],
@@ -285,7 +285,7 @@
285285
},
286286
{
287287
"cell_type": "code",
288-
"execution_count": 5,
288+
"execution_count": 26,
289289
"id": "4c7f6986-347b-4e50-94bb-31272e798130",
290290
"metadata": {},
291291
"outputs": [],
@@ -299,16 +299,17 @@
299299
" \"country\" and \"since_date\" to limit the returned customer list. The where clause can also \n",
300300
" be followed by a limit clause to limit the number of returned names. \n",
301301
"\n",
302-
" :param string where_clause: the string containing the where and optionally limit clauses in SQL query format\n",
302+
" :param where_clause: the string containing the where and optionally limit clauses in SQL query format\n",
303+
" :type where_clause: string\n",
303304
" :return: a list of matching customer names\n",
304-
" :rtype: list of strings\n",
305+
" :rtype: array\n",
305306
" \"\"\"\n",
306307
" return [\"Monica Schmidt\", \"Harald Mueller\"]\n"
307308
]
308309
},
309310
{
310311
"cell_type": "code",
311-
"execution_count": 6,
312+
"execution_count": 27,
312313
"id": "0cbe8851",
313314
"metadata": {},
314315
"outputs": [
@@ -330,7 +331,7 @@
330331
},
331332
{
332333
"cell_type": "code",
333-
"execution_count": 7,
334+
"execution_count": 28,
334335
"id": "4722fb91",
335336
"metadata": {},
336337
"outputs": [
@@ -340,7 +341,7 @@
340341
"['Monica Schmidt', 'Harald Mueller']"
341342
]
342343
},
343-
"execution_count": 7,
344+
"execution_count": 28,
344345
"metadata": {},
345346
"output_type": "execute_result"
346347
}
@@ -351,7 +352,7 @@
351352
},
352353
{
353354
"cell_type": "code",
354-
"execution_count": 8,
355+
"execution_count": 29,
355356
"id": "b49ca6c6-e5ef-4a92-81b2-307c4c01143a",
356357
"metadata": {},
357358
"outputs": [
@@ -367,7 +368,7 @@
367368
" 'required': ['where_clause']}}}]"
368369
]
369370
},
370-
"execution_count": 8,
371+
"execution_count": 29,
371372
"metadata": {},
372373
"output_type": "execute_result"
373374
}
@@ -379,7 +380,7 @@
379380
},
380381
{
381382
"cell_type": "code",
382-
"execution_count": 9,
383+
"execution_count": 30,
383384
"id": "b2b274f9-a160-4074-a022-3d377fdc82fa",
384385
"metadata": {},
385386
"outputs": [
@@ -389,7 +390,7 @@
389390
"True"
390391
]
391392
},
392-
"execution_count": 9,
393+
"execution_count": 30,
393394
"metadata": {},
394395
"output_type": "execute_result"
395396
}
@@ -400,7 +401,7 @@
400401
},
401402
{
402403
"cell_type": "code",
403-
"execution_count": 10,
404+
"execution_count": 31,
404405
"id": "07928eb2",
405406
"metadata": {},
406407
"outputs": [
@@ -410,7 +411,7 @@
410411
"False"
411412
]
412413
},
413-
"execution_count": 10,
414+
"execution_count": 31,
414415
"metadata": {},
415416
"output_type": "execute_result"
416417
}
@@ -421,7 +422,7 @@
421422
},
422423
{
423424
"cell_type": "code",
424-
"execution_count": 11,
425+
"execution_count": 32,
425426
"id": "930d815e-d4fc-4a2e-aba0-4d4593900f50",
426427
"metadata": {},
427428
"outputs": [
@@ -432,7 +433,7 @@
432433
" 'role': 'user'}]"
433434
]
434435
},
435-
"execution_count": 11,
436+
"execution_count": 32,
436437
"metadata": {},
437438
"output_type": "execute_result"
438439
}
@@ -444,61 +445,33 @@
444445
},
445446
{
446447
"cell_type": "code",
447-
"execution_count": 12,
448+
"execution_count": 33,
448449
"id": "338e3b72-2ccc-47a0-9248-c422a232fdd4",
449450
"metadata": {},
450451
"outputs": [
451-
{
452-
"name": "stdout",
453-
"output_type": "stream",
454-
"text": [
455-
"DEBUG: cost for this call 0.0007250000000000001\n",
456-
"DEBUG: checking for tool_calls: Message(content=None, role='assistant', tool_calls=[ChatCompletionMessageToolCall(function=Function(arguments='{\"where_clause\":\"city = \\'New York\\' AND since_date <= \\'2023-01-01\\'\"}', name='query_names'), id='call_QW2BQE2zqPZq0w7AG5FK7DwW', type='function')], function_call=None, provider_specific_fields={'refusal': None}, annotations=[]), have tools: True\n",
457-
"DEBUG: got 1 tool calls:\n",
458-
"DEBUG: ChatCompletionMessageToolCall(function=Function(arguments='{\"where_clause\":\"city = \\'New York\\' AND since_date <= \\'2023-01-01\\'\"}', name='query_names'), id='call_QW2BQE2zqPZq0w7AG5FK7DwW', type='function')\n",
459-
"DEBUG: appending response message: Message(content=None, role='assistant', tool_calls=[ChatCompletionMessageToolCall(function=Function(arguments='{\"where_clause\":\"city = \\'New York\\' AND since_date <= \\'2023-01-01\\'\"}', name='query_names'), id='call_QW2BQE2zqPZq0w7AG5FK7DwW', type='function')], function_call=None, provider_specific_fields={'refusal': None}, annotations=[])\n",
460-
"DEBUG: tool call query_names\n",
461-
"DEBUG: calling query_names with args {'where_clause': \"city = 'New York' AND since_date <= '2023-01-01'\"}\n",
462-
"DEBUG: got response ['Monica Schmidt', 'Harald Mueller']\n",
463-
"DEBUG: recursively calling query with messages:\n",
464-
"DEBUG: Message 0: {'content': 'Give me the names of customers in New York which have been customers since 2023 or longer', 'role': 'user'}\n",
465-
"DEBUG: Message 1: Message(content=None, role='assistant', tool_calls=[ChatCompletionMessageToolCall(function=Function(arguments='{\"where_clause\":\"city = \\'New York\\' AND since_date <= \\'2023-01-01\\'\"}', name='query_names'), id='call_QW2BQE2zqPZq0w7AG5FK7DwW', type='function')], function_call=None, provider_specific_fields={'refusal': None}, annotations=[])\n",
466-
"DEBUG: Message 2: {'tool_call_id': 'call_QW2BQE2zqPZq0w7AG5FK7DwW', 'role': 'tool', 'name': 'query_names', 'content': '[\"Monica Schmidt\", \"Harald Mueller\"]'}\n",
467-
"DEBUG: recursively_call_info is {'start': 1745344687.546055, 'cost': 0.0007250000000000001, 'n_completion_tokens': 33, 'n_prompt_tokens': 158, 'n_total_tokens': 191}\n"
468-
]
469-
},
470452
{
471453
"name": "stderr",
472454
"output_type": "stream",
473455
"text": [
474456
"/home/johann/software/anaconda/envs/llms_wrapper/lib/python3.11/site-packages/pydantic/main.py:463: UserWarning: Pydantic serializer warnings:\n",
475-
" PydanticSerializationUnexpectedValue(Expected `ChatCompletionMessageToolCall` - serialized value may not be as expected [input_value={'function': {'arguments'...wW', 'type': 'function'}, input_type=dict])\n",
457+
" PydanticSerializationUnexpectedValue(Expected `ChatCompletionMessageToolCall` - serialized value may not be as expected [input_value={'function': {'arguments'...xq', 'type': 'function'}, input_type=dict])\n",
476458
" return self.__pydantic_serializer__.to_python(\n"
477459
]
478460
},
479-
{
480-
"name": "stdout",
481-
"output_type": "stream",
482-
"text": [
483-
"DEBUG: cost for this call 0.00083\n",
484-
"DEBUG: checking for tool_calls: Message(content='Here are the names of customers in New York who have been customers since 2023 or longer:\\n\\n1. Monica Schmidt\\n2. Harald Mueller', role='assistant', tool_calls=None, function_call=None, provider_specific_fields={'refusal': None}, annotations=[]), have tools: True\n",
485-
"DEBUG: got 0 tool calls:\n"
486-
]
487-
},
488461
{
489462
"data": {
490463
"text/plain": [
491-
"('Here are the names of customers in New York who have been customers since 2023 or longer:\\n\\n1. Monica Schmidt\\n2. Harald Mueller',\n",
464+
"('The customers in New York who have been customers since 2023 or longer are:\\n\\n- Monica Schmidt\\n- Harald Mueller',\n",
492465
" '')"
493466
]
494467
},
495-
"execution_count": 12,
468+
"execution_count": 33,
496469
"metadata": {},
497470
"output_type": "execute_result"
498471
}
499472
],
500473
"source": [
501-
"ret = llms.query(\"openai/gpt-4o\", messages=msgs, tools=tools, debug=True, return_cost=True)\n",
474+
"ret = llms.query(\"openai/gpt-4o\", messages=msgs, tools=tools, return_cost=True)\n",
502475
"ret[\"answer\"], ret[\"error\"]"
503476
]
504477
},
@@ -511,13 +484,13 @@
511484
{
512485
"data": {
513486
"text/plain": [
514-
"{'elapsed_time': 0.8021302223205566,\n",
515-
" 'cost': 0.0008800000000000001,\n",
516-
" 'n_completion_tokens': 27,\n",
517-
" 'n_prompt_tokens': 244,\n",
518-
" 'n_total_tokens': 271,\n",
487+
"{'elapsed_time': 1.8553009033203125,\n",
488+
" 'cost': 0.0015425,\n",
489+
" 'n_completion_tokens': 63,\n",
490+
" 'n_prompt_tokens': 365,\n",
491+
" 'n_total_tokens': 428,\n",
519492
" 'finish_reason': 'stop',\n",
520-
" 'answer': 'The customers in New York who have been with us since 2023 or longer are:\\n\\n- Monica Schmidt\\n- Harald Mueller',\n",
493+
" 'answer': 'Here are the names of customers in New York who have been customers since 2023 or longer:\\n\\n1. Monica Schmidt\\n2. Harald Mueller',\n",
521494
" 'error': '',\n",
522495
" 'ok': True}"
523496
]
@@ -546,6 +519,14 @@
546519
"metadata": {},
547520
"outputs": [],
548521
"source": []
522+
},
523+
{
524+
"cell_type": "code",
525+
"execution_count": null,
526+
"id": "aeec211c",
527+
"metadata": {},
528+
"outputs": [],
529+
"source": []
549530
}
550531
],
551532
"metadata": {

0 commit comments

Comments
 (0)