From 4f1a19b4afc349027e5586bac1bd5f6bca4f06ca Mon Sep 17 00:00:00 2001 From: allen Date: Mon, 10 Feb 2025 11:45:33 +0800 Subject: [PATCH] Add files via upload --- multi-agent/agent-supervisor/README.md | 7 ++ .../agent-supervisor/agent-supervisor.png | Bin 0 -> 44999 bytes multi-agent/agent-supervisor/leader.go | 76 +++++++++++++ multi-agent/agent-supervisor/main.go | 106 ++++++++++++++++++ multi-agent/agent-supervisor/qa.go | 23 ++++ multi-agent/agent-supervisor/rd.go | 95 ++++++++++++++++ 6 files changed, 307 insertions(+) create mode 100644 multi-agent/agent-supervisor/README.md create mode 100644 multi-agent/agent-supervisor/agent-supervisor.png create mode 100644 multi-agent/agent-supervisor/leader.go create mode 100644 multi-agent/agent-supervisor/main.go create mode 100644 multi-agent/agent-supervisor/qa.go create mode 100644 multi-agent/agent-supervisor/rd.go diff --git a/multi-agent/agent-supervisor/README.md b/multi-agent/agent-supervisor/README.md new file mode 100644 index 0000000..56db6eb --- /dev/null +++ b/multi-agent/agent-supervisor/README.md @@ -0,0 +1,7 @@ +### Multi-Agent + +Multi-agent systems consist of multiple decision-making agents that interact in a shared environment to achieve common or conflicting goals. + +- [agent-supervisor](./main.go): An example of a multi-agent system with an agent supervisor to help delegate tasks. In the example, the Leader delegates tasks to RD (Research and Development) and QA (Quality Assurance), if the code doesn’t pass the test, it is sent back to RD for rewriting and then tested again, and the Leader makes corresponding decisions based on feedback, finally returning the tested code. + + \ No newline at end of file diff --git a/multi-agent/agent-supervisor/agent-supervisor.png b/multi-agent/agent-supervisor/agent-supervisor.png new file mode 100644 index 0000000000000000000000000000000000000000..dcfd42bc323bafbca96e694fa7debbd5e1a37a04 GIT binary patch literal 44999 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 literal 0 HcmV?d00001 diff --git a/multi-agent/agent-supervisor/leader.go b/multi-agent/agent-supervisor/leader.go new file mode 100644 index 0000000..bab1f49 --- /dev/null +++ b/multi-agent/agent-supervisor/leader.go @@ -0,0 +1,76 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/Rovanta/rmodel/community/processor/go_code_tester" + "github.com/Rovanta/rmodel/processor" +) + +const ( + memKeyDemand = "demand" + memKeyResponse = "response" + memKeyTask = "task" + memKeyFeedback = "feedback" + memKeyDecision = "decision" +) + +func LeaderProcess(b processor.BrainContext) error { + // if it has no task, disassemble task from demand + if !b.ExistMemory(memKeyTask) { + task := rephraseTaskFromDemand(b.GetMemory(memKeyDemand).(string)) + _ = b.SetMemory(memKeyTask, task) + _ = b.SetMemory(memKeyDecision, DecisionRD) + + return nil + } + switch b.GetMemory(memKeyFeedback).(string) { + case FeedBackRD: // feedback from RD + _ = b.SetMemory(memKeyDecision, DecisionQA) // pass to QA + case FeedBackQA: // feedback from QA + ok := readTestReport(b.GetMemory(memKeyGoTestResult).(string)) + if !ok { + // test result not ok, resend to RD + _ = b.SetMemory(memKeyDecision, DecisionRD) + } else { + // pretty response from codes + resp := genResponse(b) + _ = b.SetMemory(memKeyResponse, resp) + _ = b.SetMemory(memKeyDecision, DecisionResponse) + } + default: + return fmt.Errorf("unknown feedback: %v\n", b.GetMemory(memKeyFeedback)) + } + + return nil +} + +func rephraseTaskFromDemand(demand string) string { + // TODO maybe use completion LLM to rephrase demand to task + task := demand + + return task +} + +func readTestReport(testResult string) bool { + return !strings.Contains(testResult, "FAIL") +} + +func genResponse(b processor.BrainContextReader) string { + codes := b.GetMemory(memKeyCodes).(*go_code_tester.Codes).String() + testReport := b.GetMemory(memKeyGoTestResult).(string) + + var builder strings.Builder + builder.WriteString("Dear Boss: \n") + builder.WriteString("After the efforts of our RD team and QA team, the final codes and test report are produced as follows:\n\n") + builder.WriteString("==========\n\nCodes:\n\n") + builder.WriteString(codes) + builder.WriteString("==========\n\nTest Report:\n\n") + builder.WriteString("```shell\n") + builder.WriteString(testReport) + builder.WriteString("```") + builder.WriteString("\n") + + return builder.String() +} diff --git a/multi-agent/agent-supervisor/main.go b/multi-agent/agent-supervisor/main.go new file mode 100644 index 0000000..1a0b3b3 --- /dev/null +++ b/multi-agent/agent-supervisor/main.go @@ -0,0 +1,106 @@ +package main + +import ( + "fmt" + + "github.com/Rovanta/rmodel" + "github.com/Rovanta/rmodel/brainlocal" + "github.com/Rovanta/rmodel/processor" +) + +var ( + FeedBackRD = "RD" + FeedBackQA = "QA" + DecisionRD = "RD" + DecisionQA = "QA" + DecisionResponse = "Response" +) + +func main() { + bp := rModel.NewBlueprint() + + neuronLeader := bp.AddNeuron(LeaderProcess) + neuronQA := bp.AddNeuron(QAProcess) + neuronRD := bp.AddNeuronWithProcessor(NewRDProcessor()) + + _, _ = bp.AddEntryLinkTo(neuronLeader) + // leader out-link + rdLink, _ := bp.AddLink(neuronLeader, neuronRD) + qaLink, _ := bp.AddLink(neuronLeader, neuronQA) + endLink, _ := bp.AddEndLinkFrom(neuronLeader) + + // leader in-link + _, _ = bp.AddLink(neuronRD, neuronLeader) + _, _ = bp.AddLink(neuronQA, neuronLeader) + + _ = neuronLeader.AddCastGroup(DecisionRD, rdLink) + _ = neuronLeader.AddCastGroup(DecisionQA, qaLink) + _ = neuronLeader.AddCastGroup(DecisionResponse, endLink) + neuronLeader.BindCastGroupSelectFunc(func(bcr processor.BrainContextReader) string { + return bcr.GetMemory(memKeyDecision).(string) + }) + + brain := brainlocal.BuildBrain(bp) + _ = brain.EntryWithMemory(memKeyDemand, "Help me write a function `func Add (x, y int) int` with golang to implement addition, and implement unit test in a separate _test .go file, at least 3 test cases are required") + brain.Wait() + fmt.Printf("Response: %s\n", brain.GetMemory(memKeyResponse).(string)) + + /* + Response: Dear Boss: + After the efforts of our RD team and QA team, the final codes and test report are produced as follows: + + ========== + + Codes: + + **add.go** + + ```go + package main + + func Add(x, y int) int { + return x + y + } + ``` + + **add_test.go** + + ```go + package main + + import "testing" + + func TestAdd(t *testing.T) { + cases := []struct { + x, y, expected int + }{ + {1, 2, 3}, + {-1, 1, 0}, + {0, 0, 0}, + } + + for _, c := range cases { + result := Add(c.x, c.y) + if result != c.expected { + t.Errorf("Add(%d, %d) == %d, expected %d", c.x, c.y, result, c.expected) + } + } + } + ``` + + ========== + + Test Report: + + ```shell + #go test -v -run . + === RUN TestAdd + --- PASS: TestAdd (0.00s) + PASS + ok gocodetester 0.411s + + ``` + + + */ +} diff --git a/multi-agent/agent-supervisor/qa.go b/multi-agent/agent-supervisor/qa.go new file mode 100644 index 0000000..72a554a --- /dev/null +++ b/multi-agent/agent-supervisor/qa.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/Rovanta/rmodel/community/processor/go_code_tester" + "github.com/Rovanta/rmodel/processor" +) + +const ( + memKeyGoTestResult = "go_test_result" +) + +func QAProcess(b processor.BrainContext) error { + p := go_code_tester.NewProcessor().WithTestCodeKeep(true) + if err := p.Process(b); err != nil { + return err + } + + if err := b.SetMemory(memKeyFeedback, b.GetCurrentNeuronID()); err != nil { + return err + } + + return nil +} diff --git a/multi-agent/agent-supervisor/rd.go b/multi-agent/agent-supervisor/rd.go new file mode 100644 index 0000000..a6657c4 --- /dev/null +++ b/multi-agent/agent-supervisor/rd.go @@ -0,0 +1,95 @@ +package main + +import ( + "fmt" + "os" + + "github.com/sashabaranov/go-openai" + "github.com/Rovanta/rmodel/community/processor/go_code_tester" + "github.com/Rovanta/rmodel/community/processor/openai_structured_output" + "github.com/Rovanta/rmodel/processor" +) + +var ( + memKeyCodes = (&go_code_tester.Codes{}).FunctionName() +) + +func NewRDProcessor() *CoderProcessor { + return &CoderProcessor{ + clientConfig: openai.DefaultConfig(os.Getenv("OPENAI_API_KEY")), + requestConfig: openai_structured_output.RequestConfig{ + Model: openai.GPT3Dot5Turbo0125, + Temperature: 0.7, + Stream: false, + }, + } +} + +type CoderProcessor struct { + clientConfig openai.ClientConfig + client *openai.Client + requestConfig openai_structured_output.RequestConfig +} + +func (p *CoderProcessor) Process(b processor.BrainContext) error { + var prompt string + if !b.ExistMemory(memKeyCodes) { + // read task, write code + prompt = fmt.Sprintf(`{{.%s}}`, memKeyTask) + } else { + // read task, old code and test result, write code + prompt = fmt.Sprintf(`{{.%s}} + +My code is as follows: + +%s + +test result is as follows: + +%s + +Help me correct my code. +`, memKeyTask, b.GetMemory(memKeyCodes).(*go_code_tester.Codes).String(), memKeyGoTestResult) + } + + structuredOutput := p.newStructuredOutputProcessor(prompt) + if err := structuredOutput.Process(b); err != nil { + return err + } + + if err := b.SetMemory(memKeyFeedback, b.GetCurrentNeuronID()); err != nil { + return err + } + + return nil +} + +func (p *CoderProcessor) Clone() processor.Processor { + return &CoderProcessor{ + requestConfig: p.requestConfig, + clientConfig: p.clientConfig, + client: nil, + } +} + +func (p *CoderProcessor) WithClientConfig(clientConfig openai.ClientConfig) *CoderProcessor { + p.clientConfig = clientConfig + return p +} + +func (p *CoderProcessor) WithClient(client *openai.Client) *CoderProcessor { + p.client = client + return p +} + +func (p *CoderProcessor) WithRequestConfig(requestConfig openai_structured_output.RequestConfig) *CoderProcessor { + p.requestConfig = requestConfig + return p +} + +func (p *CoderProcessor) newStructuredOutputProcessor(prompt string) *openai_structured_output.OpenAIStructuredOutputProcessor { + proc := openai_structured_output.NewProcessor() + _ = proc.WithPromptTemplate(prompt) + _ = proc.WithOutputStructDefinition(go_code_tester.Codes{}, (go_code_tester.Codes{}).FunctionName(), (go_code_tester.Codes{}).FunctionDescription()) + return proc.WithClientConfig(p.clientConfig).WithRequestConfig(p.requestConfig) +}