tmc / langchaingo

LangChain for Go, the easiest way to write LLM-based programs in Go
https://tmc.github.io/langchaingo/
MIT License
3.78k stars 523 forks source link

Split functionality between `llms` and `schema` packages #753

Closed eliben closed 2 months ago

eliben commented 3 months ago

Looking at the recently added tool / function calling example in https://github.com/tmc/langchaingo/blob/main/examples/openai-function-call-example/openai_function_call_example.go#L56, we see code like:

// updateMessageHistory updates the message history with the assistant's response.
func updateMessageHistory(messageHistory []llms.MessageContent, resp *llms.ContentResponse) []llms.MessageContent {
    assistantResponse := llms.MessageContent{
        Role: schema.ChatMessageTypeAI,
    }
    for _, tc := range resp.Choices[0].ToolCalls {
        assistantResponse.Parts = append(assistantResponse.Parts, llms.ToolCall{
            ID:   tc.ID,
            Type: tc.Type,
            FunctionCall: &schema.FunctionCall{
                Name:      tc.FunctionCall.Name,
                Arguments: tc.FunctionCall.Arguments,
            },
        })
    }
    return append(messageHistory, assistantResponse)
}

This needs to happen to translate schema.ToolCall to llms.ToolCall, which have pretty much the same contents. The reason for this is that we have split functionality between the schema and llms packages. This is not a great thing to impose on application writers.

I propose moving things like ToolCall into llms and removing from schema, thus avoiding this split and duplication. This will help us get rid of quite a bit of code and also make examples simpler.

devalexandre commented 3 months ago

moving it to llms, wouldn't it imply that all integrations are supported?

eliben commented 3 months ago

moving it to llms, wouldn't it imply that all integrations are supported?

Sorry, I don't understand what you mean.

eliben commented 3 months ago

Please see #757 for a sketch of this refactoring. It will prevent this kind of duplication, since there will only be one ToolCall, no need to translate between its schema and llms variant.

One thing we can add is forwarding aliases from moved schema types to llms types - this will prevent users' code breaking.

A separate PR will follow updating examples.

devalexandre commented 3 months ago

moving it to llms, wouldn't it imply that all integrations are supported?

Sorry, I don't understand what you mean. Why move to LLMs if not all LLM use it?

eliben commented 3 months ago

Why move to LLMs if not all LLM use it?

The llms package contains shared types and interfaces for LLM providers; this includes features that only some of the providers implement. Tools/functions are supported by more than one provider already, and my plan was to add additional providers support - for Google AI providers. https://github.com/tmc/langchaingo/issues/748 is talking about the same thing.

The schema package is similar - it's for code shared across langchaingo, but with tool calls specifically it ended up with duplication since llms imports schema, schema can't import llms back and instead types are duplicated as the original post in this issue specifies.