This commit is contained in:
lujingxuan
2023-12-26 17:54:01 +08:00
parent 9dd6da65e6
commit fbc4ed6c9e
5 changed files with 32 additions and 22 deletions
+3
View File
@@ -0,0 +1,3 @@
package agents
var agentScratchpad = "agent_scratchpad"
+2
View File
@@ -20,6 +20,8 @@ var (
// ErrInvalidChainReturnType is returned if the internal chain of the agent returns a value in the
// "text" filed that is not a string.
ErrInvalidChainReturnType = errors.New("agent chain did not return a string")
// ErrInvalidLLMGenerationsMessageReturn is returned if the internal llm of the agent returns a value generations message is nil.
ErrInvalidLLMGenerationsMessageReturn = errors.New("agent llm did not return valid generations message")
)
// ParserErrorHandler is the struct used to handle parse errors from the agent in the executor. If
+6 -3
View File
@@ -2,7 +2,6 @@ package agents_test
import (
"context"
"github.com/tmc/langchaingo/prompts"
"os"
"strings"
"testing"
@@ -11,6 +10,7 @@ import (
"github.com/tmc/langchaingo/agents"
"github.com/tmc/langchaingo/chains"
"github.com/tmc/langchaingo/llms/openai"
"github.com/tmc/langchaingo/prompts"
"github.com/tmc/langchaingo/schema"
"github.com/tmc/langchaingo/tools"
"github.com/tmc/langchaingo/tools/serpapi"
@@ -124,12 +124,15 @@ func TestExecutorWithOpenAIFunctionAgent(t *testing.T) {
[]tools.Tool{searchTool, calculator},
agents.OpenAIFunctionAgentDescription,
agents.OpenAIOption.WithSystemMessage("you are a helpful assistant"),
agents.OpenAIOption.WithExtraMessages([]prompts.MessageFormatter{prompts.NewHumanMessagePromptTemplate("please be strict", nil)}),
agents.OpenAIOption.WithExtraMessages([]prompts.MessageFormatter{
prompts.NewHumanMessagePromptTemplate("please be strict", nil),
}),
)
require.NoError(t, err)
result, err := chains.Run(context.Background(), a, "what is HK singer Eason Chan's years old?") //nolint:lll
require.NoError(t, err)
require.True(t, strings.Contains(result, "47") || strings.Contains(result, "49"), "correct answer 47 or 49 not in response")
require.True(t, strings.Contains(result, "47") || strings.Contains(result, "49"),
"correct answer 47 or 49 not in response")
}
+19 -18
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/tmc/langchaingo/callbacks"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/prompts"
@@ -84,7 +85,7 @@ func (o *OpenAIFunctionsAgent) Plan(
for key, value := range inputs {
fullInputs[key] = value
}
fullInputs["agent_scratchpad"] = o.constructScratchPad(intermediateSteps)
fullInputs[agentScratchpad] = o.constructScratchPad(intermediateSteps)
var stream func(ctx context.Context, chunk []byte) error
@@ -106,7 +107,6 @@ func (o *OpenAIFunctionsAgent) Plan(
llms.WithFunctions(o.functions()),
llms.WithStreamingFunc(stream),
)
if err != nil {
return nil, nil, err
}
@@ -120,7 +120,7 @@ func (o *OpenAIFunctionsAgent) GetInputKeys() []string {
// Remove inputs given in plan.
agentInput := make([]string, 0, len(chainInputs))
for _, v := range chainInputs {
if v == "agent_scratchpad" {
if v == agentScratchpad {
continue
}
agentInput = append(agentInput, v)
@@ -138,7 +138,7 @@ func createOpenAIFunctionPrompt(opts CreationOptions) prompts.ChatPromptTemplate
messageFormatters = append(messageFormatters, opts.extraMessages...)
messageFormatters = append(messageFormatters, prompts.NewHumanMessagePromptTemplate("{{.input}}", []string{"input"}))
messageFormatters = append(messageFormatters, prompts.MessagesPlaceholder{
VariableName: "agent_scratchpad",
VariableName: agentScratchpad,
})
tmpl := prompts.NewChatPromptTemplate(messageFormatters)
@@ -146,26 +146,26 @@ func createOpenAIFunctionPrompt(opts CreationOptions) prompts.ChatPromptTemplate
}
func (o *OpenAIFunctionsAgent) constructScratchPad(steps []schema.AgentStep) []schema.ChatMessage {
if len(steps) <= 0 {
if len(steps) == 0 {
return nil
}
var messages []schema.ChatMessage
if len(steps) > 0 {
for _, step := range steps {
messages = append(messages, schema.FunctionChatMessage{
Name: step.Action.Tool,
Content: step.Observation,
})
}
for _, step := range steps {
messages = append(messages, schema.FunctionChatMessage{
Name: step.Action.Tool,
Content: step.Observation,
})
}
return messages
}
func (o *OpenAIFunctionsAgent) ParseOutput(llmResult llms.LLMResult) ([]schema.AgentAction, *schema.AgentFinish, error) {
func (o *OpenAIFunctionsAgent) ParseOutput(llmResult llms.LLMResult) (
[]schema.AgentAction, *schema.AgentFinish, error) {
if llmResult.Generations[0][0] == nil || llmResult.Generations[0][0].Message == nil {
return nil, nil, fmt.Errorf("wrong llmResult from OpenAIFunctionsAgent")
return nil, nil, fmt.Errorf("%w: %s", ErrInvalidLLMGenerationsMessageReturn,
"wrong llmResult from OpenAIFunctionsAgent")
}
// finish
@@ -188,11 +188,12 @@ func (o *OpenAIFunctionsAgent) ParseOutput(llmResult llms.LLMResult) ([]schema.A
return nil, nil, err
}
var toolInput string
toolInput := toolInputStr
if arg1, ok := toolInputMap["__arg1"]; ok {
toolInput = arg1.(string)
} else {
toolInput = toolInputStr
toolInputCheck, ok := arg1.(string)
if ok {
toolInput = toolInputCheck
}
}
contentMsg := "\n"
+2 -1
View File
@@ -2,6 +2,7 @@ package prompts
import (
"fmt"
"github.com/tmc/langchaingo/schema"
)
@@ -111,7 +112,7 @@ type MessagesPlaceholder struct {
VariableName string
}
// FormatMessages formats the messages from the values by variable name
// FormatMessages formats the messages from the values by variable name.
func (p MessagesPlaceholder) FormatMessages(values map[string]any) ([]schema.ChatMessage, error) {
value, ok := values[p.VariableName]
if !ok {