Compare commits
10 Commits
e0430c62bd
...
d0eb4b7468
Author | SHA1 | Date | |
---|---|---|---|
d0eb4b7468 | |||
b926215e94 | |||
91da21defb | |||
d7598e7c90 | |||
917c00c23a | |||
1ed6023a14 | |||
d102e52dfc | |||
9810ffdeb8 | |||
02583c7e0e | |||
0ff90a313f |
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,3 +2,6 @@ cache/
|
|||||||
context.db
|
context.db
|
||||||
context.db-shm
|
context.db-shm
|
||||||
context.db-wal
|
context.db-wal
|
||||||
|
data.ms
|
||||||
|
/output.txt
|
||||||
|
/ctxGPT.exe
|
||||||
|
2
.idea/dataSources.xml
generated
2
.idea/dataSources.xml
generated
@ -2,7 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
<data-source source="LOCAL" name="context" uuid="0ca49717-2151-402a-b9b6-d8177360de1a">
|
<data-source source="LOCAL" name="context" uuid="0ca49717-2151-402a-b9b6-d8177360de1a">
|
||||||
<driver-ref>sqlite.xerial</driver-ref>
|
<driver-ref>deb3aec9-bcff-4dad-9d3a-a86d8508caa5</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||||
<jdbc-url>jdbc:sqlite:C:\Users\gomas\src\ctxGPT\context.db</jdbc-url>
|
<jdbc-url>jdbc:sqlite:C:\Users\gomas\src\ctxGPT\context.db</jdbc-url>
|
||||||
|
145
LLMMapper/llmMapper.go
Normal file
145
LLMMapper/llmMapper.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package LLMMapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkoukk/tiktoken-go"
|
||||||
|
"github.com/sashabaranov/go-openai"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const encodingName = "gpt-4"
|
||||||
|
|
||||||
|
// const model = openai.GPT4Turbo
|
||||||
|
const model = "o3-mini"
|
||||||
|
|
||||||
|
// const model = openai.GPT4TurboPreview
|
||||||
|
const maxTokens = 100000
|
||||||
|
|
||||||
|
//const maxTokens = 4096
|
||||||
|
|
||||||
|
// const maxTokens = 128000
|
||||||
|
const temperature = 0.7
|
||||||
|
|
||||||
|
func GetTokenCount(input string) (int, error) {
|
||||||
|
tke, err := tiktoken.EncodingForModel(encodingName) // cached in "TIKTOKEN_CACHE_DIR"
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("error getting encoding: %w", err)
|
||||||
|
}
|
||||||
|
token := tke.Encode(input, nil, nil)
|
||||||
|
return len(token), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SinglePromptInteraction calls openai chat endpoint with just a system prompt and a user prompt and returns the response
|
||||||
|
func SinglePromptInteraction(systemPrompt, prompt string) (openai.ChatCompletionResponse, error) {
|
||||||
|
return singlePromptInteraction(systemPrompt, prompt, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// singlePromptInteraction calls openai chat endpoint with just a system prompt and a user prompt and returns the response
|
||||||
|
// it also attempts 5 retries spaced 5 seconds apart in the case of rate limiting errors
|
||||||
|
func singlePromptInteraction(systemPrompt, prompt string, retries int) (openai.ChatCompletionResponse, error) {
|
||||||
|
|
||||||
|
client := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
|
||||||
|
|
||||||
|
messages := []openai.ChatCompletionMessage{
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleSystem,
|
||||||
|
Content: systemPrompt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleUser,
|
||||||
|
Content: prompt,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
previousTokenCount, err := GetPreviousTokenUsage(messages)
|
||||||
|
if err != nil {
|
||||||
|
return openai.ChatCompletionResponse{}, fmt.Errorf("error getting previous token usage: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageTokenSize := maxTokens - previousTokenCount
|
||||||
|
|
||||||
|
resp, err := client.CreateChatCompletion(
|
||||||
|
context.Background(),
|
||||||
|
openai.ChatCompletionRequest{
|
||||||
|
Model: model, // switch to the configured Model
|
||||||
|
Messages: messages,
|
||||||
|
MaxCompletionTokens: messageTokenSize, // might want to think about how to reduce this
|
||||||
|
//Temperature: temperature,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
// if 429, wait and try again
|
||||||
|
if strings.Contains(err.Error(), "429") && retries > 0 {
|
||||||
|
seconds := (1 / float64(retries)) * 60 // back off for each retry e.g. 12, 15, 20, 30, 60
|
||||||
|
fmt.Printf("429 error, waiting %v seconds...\n", seconds)
|
||||||
|
time.Sleep(time.Duration(seconds) * time.Second)
|
||||||
|
return singlePromptInteraction(systemPrompt, prompt, retries-1)
|
||||||
|
}
|
||||||
|
return openai.ChatCompletionResponse{}, fmt.Errorf("ChatCompletion request error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPreviousTokenUsage(messages []openai.ChatCompletionMessage) (int, error) {
|
||||||
|
|
||||||
|
messagesRaw, err := json.Marshal(messages)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("error marshalling messages: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
length, err := GetTokenCount(string(messagesRaw))
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("error getting token count: %w", err)
|
||||||
|
}
|
||||||
|
//fmt.Printf("Token Count: %v\n", length)
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendPrompt calls openai chat endpoint with a list of messages and returns the response
|
||||||
|
func SendPrompt(messages []openai.ChatCompletionMessage) (openai.ChatCompletionResponse, error) {
|
||||||
|
return sendPrompt(messages, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendPrompt(messages []openai.ChatCompletionMessage, retries int) (openai.ChatCompletionResponse, error) {
|
||||||
|
config := openai.DefaultConfig(os.Getenv("OPENAI_API_KEY"))
|
||||||
|
if os.Getenv("OPENAI_BASE_URL") != "" {
|
||||||
|
config.BaseURL = os.Getenv("OPENAI_BASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := openai.NewClientWithConfig(config)
|
||||||
|
|
||||||
|
previousTokenCount, err := GetPreviousTokenUsage(messages)
|
||||||
|
if err != nil {
|
||||||
|
return openai.ChatCompletionResponse{}, fmt.Errorf("error getting previous token usage: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageTokenSize := maxTokens - previousTokenCount
|
||||||
|
fmt.Println("messageTokenSize: ", messageTokenSize)
|
||||||
|
|
||||||
|
resp, err := client.CreateChatCompletion(
|
||||||
|
context.Background(),
|
||||||
|
openai.ChatCompletionRequest{
|
||||||
|
Model: model, // switch to the configured Model
|
||||||
|
Messages: messages,
|
||||||
|
MaxCompletionTokens: messageTokenSize,
|
||||||
|
//Temperature: temperature,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
// if 429, wait and try again
|
||||||
|
if strings.Contains(err.Error(), "429") && retries > 0 {
|
||||||
|
seconds := (1 / float64(retries)) * 60 // back off for each retry e.g. 12, 15, 20, 30, 60
|
||||||
|
fmt.Printf("429 error, waiting %v seconds...\n", seconds)
|
||||||
|
time.Sleep(time.Duration(seconds) * time.Second)
|
||||||
|
return sendPrompt(messages, retries-1)
|
||||||
|
}
|
||||||
|
return openai.ChatCompletionResponse{}, fmt.Errorf("ChatCompletion request error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
16
LLMMapper/llmMapper_test.go
Normal file
16
LLMMapper/llmMapper_test.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package LLMMapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_retryMath(t *testing.T) {
|
||||||
|
retries := 5
|
||||||
|
for retries > 0 {
|
||||||
|
seconds := (1 / float64(retries)) * 60
|
||||||
|
fmt.Println(seconds, retries)
|
||||||
|
retries = retries - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
146
cmd/chat/chat.go
Normal file
146
cmd/chat/chat.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"ctxGPT/LLMMapper"
|
||||||
|
"ctxGPT/promptBuilder"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/sashabaranov/go-openai"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
fmt.Println("Go CLI Chat App")
|
||||||
|
fmt.Println("---------------------")
|
||||||
|
|
||||||
|
systemPrompt := ""
|
||||||
|
//systemPrompt := "You are Mixtral, a locally hosted AI assistant."
|
||||||
|
|
||||||
|
messages := []openai.ChatCompletionMessage{
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleSystem,
|
||||||
|
Content: systemPrompt,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
fmt.Print("You: ")
|
||||||
|
text, _ := reader.ReadString('\n')
|
||||||
|
text = strings.TrimSpace(text) // Remove leading and trailing whitespace
|
||||||
|
|
||||||
|
// Check if the user wants to exit.
|
||||||
|
if text == "exit" {
|
||||||
|
fmt.Println("Exiting chat...")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
messages = append(messages, openai.ChatCompletionMessage{
|
||||||
|
Role: openai.ChatMessageRoleUser,
|
||||||
|
Content: text,
|
||||||
|
})
|
||||||
|
|
||||||
|
resp, err := LLMMapper.SendPrompt(messages)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Choices) == 0 {
|
||||||
|
fmt.Println("No choices returned")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("AI: ", resp.Choices[0].Message.Content)
|
||||||
|
file, err := os.OpenFile("output.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error opening file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
if _, err := file.WriteString(resp.Choices[0].Message.Content + "\n"); err != nil {
|
||||||
|
fmt.Println("Error writing to file:", err)
|
||||||
|
}
|
||||||
|
messages = append(messages, resp.Choices[0].Message)
|
||||||
|
|
||||||
|
currLength := estimateTokenCount(messages)
|
||||||
|
|
||||||
|
if currLength > 95000 {
|
||||||
|
fmt.Println("Token count exceeded 95000, summarizing context")
|
||||||
|
summarized, err := summarizeChatSoFar(messages)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("error summarizing chat so far | %v\n", err)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Summarized: %v\n", summarized)
|
||||||
|
}
|
||||||
|
// reset messages to the system prompt and the summarized prompt
|
||||||
|
messages = []openai.ChatCompletionMessage{
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleSystem,
|
||||||
|
Content: systemPrompt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleAssistant,
|
||||||
|
Content: summarized,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func estimateTokenCount(messages []openai.ChatCompletionMessage) int {
|
||||||
|
messagesRaw, err := json.Marshal(messages)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("error marshalling messages for token size estimation | %v\n", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
length, err := LLMMapper.GetTokenCount(string(messagesRaw))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("error getting token count | %v\n", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
fmt.Printf("Token Count: %v\n", length)
|
||||||
|
return length
|
||||||
|
}
|
||||||
|
|
||||||
|
func summarizeChatSoFar(messages []openai.ChatCompletionMessage) (string, error) {
|
||||||
|
messagesRaw, err := json.Marshal(messages)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error marshalling messages for token size estimation | %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
summarizeConvoPrompt, err := promptBuilder.BuildPrompt("summarize.tmpl", struct{ WordLimit int }{WordLimit: 100})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error building prompt for summarization | %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := LLMMapper.SendPrompt([]openai.ChatCompletionMessage{
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleSystem,
|
||||||
|
Content: summarizeConvoPrompt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Role: openai.ChatMessageRoleUser,
|
||||||
|
Content: string(messagesRaw),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error summarizing conversation | %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Choices) == 0 {
|
||||||
|
return "", fmt.Errorf("no choices returned for summarization")
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Choices[0].Message.Content, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: anything to be stored in the database should be chunked to sizes between 512 and 1024 tokens
|
||||||
|
// it should also overlap with the previous chunk by 100-200 tokens
|
||||||
|
// When the LLM asks for more context, it should be able to use the database to find the most relevant chunks here is how:
|
||||||
|
// We will get the embeddings for each prompt and use those embeddings to search for the closest 6 chunks
|
||||||
|
// we will use a separate LLM prompt to make an attempt to select and sort the chunks based on the user's input
|
||||||
|
// then we will add the best matched chunks to the main prompt as further context for the given prompt
|
31
cmd/rateTest/rate.go
Normal file
31
cmd/rateTest/rate.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Rate struct {
|
||||||
|
RPM int
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := Rate{RPM: 10}
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
go func(j int) {
|
||||||
|
r.RateLimit()
|
||||||
|
fmt.Println("Rate limiting")
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Minute)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rate) RateLimit() {
|
||||||
|
// Lock for the fraction of a minute based on RPM
|
||||||
|
r.mu.Lock()
|
||||||
|
// Unlock after the fraction of a minute
|
||||||
|
time.Sleep(time.Minute / time.Duration(r.RPM))
|
||||||
|
r.mu.Unlock()
|
||||||
|
}
|
@ -9,7 +9,7 @@ import (
|
|||||||
"zombiezen.com/go/sqlite/sqlitex"
|
"zombiezen.com/go/sqlite/sqlitex"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dbLocation = "./context.db"
|
const dbLocation = "./context.db" // TODO: put this in either a config or automatically place in the appData folder
|
||||||
|
|
||||||
var schema = sqlitemigration.Schema{
|
var schema = sqlitemigration.Schema{
|
||||||
// Each element of the Migrations slice is applied in sequence. When you
|
// Each element of the Migrations slice is applied in sequence. When you
|
||||||
|
12
go.mod
12
go.mod
@ -3,17 +3,19 @@ module ctxGPT
|
|||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/pkoukk/tiktoken-go v0.1.6
|
github.com/pkoukk/tiktoken-go v0.1.7
|
||||||
|
github.com/sashabaranov/go-openai v1.36.1
|
||||||
zombiezen.com/go/sqlite v0.13.1
|
zombiezen.com/go/sqlite v0.13.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
golang.org/x/sys v0.5.0 // indirect
|
github.com/stretchr/testify v1.8.3 // indirect
|
||||||
|
golang.org/x/sys v0.8.0 // indirect
|
||||||
modernc.org/libc v1.22.3 // indirect
|
modernc.org/libc v1.22.3 // indirect
|
||||||
modernc.org/mathutil v1.5.0 // indirect
|
modernc.org/mathutil v1.5.0 // indirect
|
||||||
modernc.org/memory v1.5.0 // indirect
|
modernc.org/memory v1.5.0 // indirect
|
||||||
|
23
go.sum
23
go.sum
@ -1,23 +1,36 @@
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
|
github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
|
||||||
github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
|
github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
|
||||||
|
github.com/pkoukk/tiktoken-go v0.1.7 h1:qOBHXX4PHtvIvmOtyg1EeKlwFRiMKAcoMp4Q+bLQDmw=
|
||||||
|
github.com/pkoukk/tiktoken-go v0.1.7/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
github.com/sashabaranov/go-openai v1.17.9 h1:QEoBiGKWW68W79YIfXWEFZ7l5cEgZBV4/Ow3uy+5hNY=
|
||||||
|
github.com/sashabaranov/go-openai v1.17.9/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||||
|
github.com/sashabaranov/go-openai v1.23.0 h1:KYW97r5yc35PI2MxeLZ3OofecB/6H+yxvSNqiT9u8is=
|
||||||
|
github.com/sashabaranov/go-openai v1.23.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||||
|
github.com/sashabaranov/go-openai v1.36.1 h1:EVfRXwIlW2rUzpx6vR+aeIKCK/xylSrVYAx1TMTSX3g=
|
||||||
|
github.com/sashabaranov/go-openai v1.36.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||||
|
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||||
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
|
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
|
||||||
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
|
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
|
||||||
|
35
main.go
35
main.go
@ -1,17 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
|
"ctxGPT/LLMMapper"
|
||||||
"ctxGPT/database"
|
"ctxGPT/database"
|
||||||
|
"ctxGPT/promptBuilder"
|
||||||
"fmt"
|
"fmt"
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/pkoukk/tiktoken-go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const encodingName = "gpt-4"
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
db, err := database.NewDB()
|
db, err := database.NewDB()
|
||||||
@ -33,37 +29,14 @@ func main() {
|
|||||||
// to get text out of PDF, DOC, DOCX, XML, HTML, RTF, ODT pages documents and images to plain text
|
// to get text out of PDF, DOC, DOCX, XML, HTML, RTF, ODT pages documents and images to plain text
|
||||||
// use https://github.com/sajari/docconv
|
// use https://github.com/sajari/docconv
|
||||||
|
|
||||||
summarizeConvoPrompt, err := BuildPrompt("summarize.tmpl", struct{ WordLimit int }{WordLimit: 100})
|
summarizeConvoPrompt, err := promptBuilder.BuildPrompt("summarize.tmpl", struct{ WordLimit int }{WordLimit: 100})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println(summarizeConvoPrompt)
|
fmt.Println(summarizeConvoPrompt)
|
||||||
tokenCount, err := GetTokenCount(summarizeConvoPrompt)
|
tokenCount, err := LLMMapper.GetTokenCount(summarizeConvoPrompt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println(tokenCount)
|
fmt.Println(tokenCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildPrompt(name string, in interface{}) (string, error) {
|
|
||||||
fileLocation := "./prompts/" + name
|
|
||||||
tmpl, err := template.New(name).ParseFiles(fileLocation)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error parsing template: %w", err)
|
|
||||||
}
|
|
||||||
b := bytes.Buffer{}
|
|
||||||
err = tmpl.Execute(&b, in)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error executing template: %w", err)
|
|
||||||
}
|
|
||||||
return b.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTokenCount(input string) (int, error) {
|
|
||||||
tke, err := tiktoken.EncodingForModel(encodingName) // cached in "TIKTOKEN_CACHE_DIR"
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("error getting encoding: %w", err)
|
|
||||||
}
|
|
||||||
token := tke.Encode(input, nil, nil)
|
|
||||||
return len(token), nil
|
|
||||||
}
|
|
||||||
|
BIN
meilisearch.exe
Normal file
BIN
meilisearch.exe
Normal file
Binary file not shown.
21
promptBuilder/promptBuilder.go
Normal file
21
promptBuilder/promptBuilder.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package promptBuilder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildPrompt(name string, in interface{}) (string, error) {
|
||||||
|
fileLocation := "./prompts/" + name
|
||||||
|
tmpl, err := template.New(name).ParseFiles(fileLocation)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error parsing template: %w", err)
|
||||||
|
}
|
||||||
|
b := bytes.Buffer{}
|
||||||
|
err = tmpl.Execute(&b, in)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error executing template: %w", err)
|
||||||
|
}
|
||||||
|
return b.String(), nil
|
||||||
|
}
|
2
prompts/linux-machine-convo-user-prompt.tmpl
Normal file
2
prompts/linux-machine-convo-user-prompt.tmpl
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{{.userPrompt}}
|
||||||
|
Let's think step by step.
|
1
prompts/linux-sys-prompt.tmpl
Normal file
1
prompts/linux-sys-prompt.tmpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
Your job is to take a prompt from the user and generate a bash command or script to search for more context within files stored on the machine. Some previous conversations are stored in `/conversations`. Those conversations will fill in any gaps in your knowledge. Remember these conversations are free form. You'll need to allow for some fuzzy searching rather than using exact phrases. Feel free to use the best Linux tool available. Always respond with a bash command or script.
|
@ -1,5 +1,5 @@
|
|||||||
Your job is to summarize a history of previous messages in a conversation between an AI persona and a human.
|
Your job is to summarize a history of previous messages in a conversation between an AI persona and a human.
|
||||||
The conversation you are given is a from a fixed context window and may not be complete.
|
The conversation you are given is from a fixed context window and may not be complete.
|
||||||
Messages sent by the AI are marked with the 'assistant' role.
|
Messages sent by the AI are marked with the 'assistant' role.
|
||||||
The AI 'assistant' can also make calls to functions, whose outputs can be seen in messages with the 'function' role.
|
The AI 'assistant' can also make calls to functions, whose outputs can be seen in messages with the 'function' role.
|
||||||
Things the AI says in the message content are considered inner monologue and are not seen by the user.
|
Things the AI says in the message content are considered inner monologue and are not seen by the user.
|
||||||
|
67
readme.md
Normal file
67
readme.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# CTXGPT
|
||||||
|
|
||||||
|
Originally based on the idea of MemGPT, this project aims to augment the context of a given interaction with an LLM with a given context. Also, it is written in Golang.
|
||||||
|
|
||||||
|
### How it works
|
||||||
|
|
||||||
|
This project manages the context via various levels of storage.
|
||||||
|
|
||||||
|
The regular conversation between the user and the AI is stored in a full text searchable database. Since the context you can send to any given LLM is limited by number of tokens, the conversation will only contain the most recent messages. The AI has a few functions it can use to help it remember things beyond this limited context.
|
||||||
|
|
||||||
|
First, it has a function that will allow it to search the conversation history for a given string. This allows it to remember things that were said in the past.
|
||||||
|
|
||||||
|
It has a function that allows it to archive specific information in a concept=>definition relationship.
|
||||||
|
|
||||||
|
* I think it would be useful to allow the system to store sub-concepts as well. For example, if I tell the system about a specific person, it should be able to store that person's name, and other information about them. This would allow the system to remember things like "What is the name of the person who works at the coffee shop?".
|
||||||
|
|
||||||
|
It has a function that allows it to search the archived information for a given string. Which will load that information into its context window.
|
||||||
|
|
||||||
|
It can call a function to search the web, or a document database for specific information.
|
||||||
|
|
||||||
|
### Document Database
|
||||||
|
|
||||||
|
The document database is a collection of documents that are stored in a full text searchable database. The AI can search this database for specific information, and load it into its context window.
|
||||||
|
|
||||||
|
The table contains the following fields:
|
||||||
|
|
||||||
|
* source - The source of the document (e.g. file path, wikipedia, or a specific website)
|
||||||
|
* checksum - The checksum of the document (used to determine if the document has changed)
|
||||||
|
* title - The title of the document
|
||||||
|
* content - The content of the document (parsed from the source into plain text)
|
||||||
|
* tags - A list of tags that can be used to search the document
|
||||||
|
* summary - A summary of the document (rolled up via GPT calls to compress the document into a few sentences)
|
||||||
|
* created_at - The date the document was created
|
||||||
|
* updated_at - The date the document was last updated
|
||||||
|
* needs_update - A flag that indicates if the document needs to be updated (e.g. if the source has changed)
|
||||||
|
|
||||||
|
### Conversation Database
|
||||||
|
|
||||||
|
The conversation database is a collection of messages that are stored in a full text searchable database. The AI can search this database for specific information, and load it into its context window.
|
||||||
|
|
||||||
|
The table contains the following fields:
|
||||||
|
|
||||||
|
* source - The source of the message (e.g. user, system, LLM agent, etc.)
|
||||||
|
* content - The content of the message (parsed from the source into plain text)
|
||||||
|
* tags - A list of tags that can be used to search the message
|
||||||
|
* created_at - The date the message was created
|
||||||
|
|
||||||
|
### Concept Database
|
||||||
|
|
||||||
|
The concept database is a collection of concepts that are stored in a full text searchable database. The AI can search this database for specific information, and load it into its context window.
|
||||||
|
|
||||||
|
The table contains the following fields:
|
||||||
|
|
||||||
|
* concept - The concept that is being defined
|
||||||
|
* definition - The definition of the concept
|
||||||
|
* tags - A list of tags that can be used to search the concept
|
||||||
|
* created_at - The date the concept was created
|
||||||
|
* updated_at - The date the concept was last updated
|
||||||
|
|
||||||
|
### TODO
|
||||||
|
|
||||||
|
* [x] Set up a basic Database
|
||||||
|
* [ ] Create initial prompts for the LLM
|
||||||
|
* [ ] Create functions for the LLM to use to interact with the database
|
||||||
|
* [ ] Create conversational input/output handling for user interactions
|
||||||
|
* [ ] Create a way to ingest new documents and data into the database
|
||||||
|
* [ ] Manage rate limiting and errors from the LLM
|
128
transcript.md
Normal file
128
transcript.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
You: Hey here. This is my first time trying a chat with you in my terminal.
|
||||||
|
AI: Welcome! It's great to have you trying out the chat in your terminal. Feel free to ask me questions or tell me what you need assistance with. Whether you're looking for information, technical help, or just a conversation, I'
|
||||||
|
m here to assist you. How can I help you today?
|
||||||
|
You: I am building an authentication application that developers can use to make their applications more secure. What do you think I should do in order to engender trust in the my application so they'll try it out?
|
||||||
|
AI: When building an authentication application that developers will trust and want to use, several key factors come into play. Here's a list of steps and strategies you can employ to build trust and encourage adoption:
|
||||||
|
|
||||||
|
1. **Security First**: Prioritize strong and up-to-date security practices within your application. Use the latest encryption standards, secure coding practices, and regularly audit your codebase for security vulnerabilities.
|
||||||
|
|
||||||
|
2. **Transparency**: Be transparent about your security practices. Publish your security measures, data handling policies, and compliance certifications if any. Openness about how you manage and protect user data can build signif
|
||||||
|
icant trust.
|
||||||
|
|
||||||
|
3. **Compliance**: Ensure that your application complies with relevant industry standards and regulations like GDPR, HIPAA, CCPA, and other data protection laws applicable to your users.
|
||||||
|
|
||||||
|
4. **Third-party Audits and Certifications**: Obtain audits from reputable security firms and pursue industry-recognized certifications to validate your security claims.
|
||||||
|
|
||||||
|
5. **Clear Documentation**: Provide comprehensive, clear, and accessible documentation for developers. Documentation should include integration guides, API references, best practices, and support resources.
|
||||||
|
|
||||||
|
6. **Developer Support**: Offer responsive and helpful support. This can include support tickets, community forums, chat support, and documentation to help resolve any issues quickly.
|
||||||
|
|
||||||
|
7. **
|
||||||
|
You: continue
|
||||||
|
AI: Open Source: If it's feasible for your business model, consider open-sourcing at least parts of your application. This allows developers to inspect the code themselves for security practices, which can significantly increase
|
||||||
|
trust. Transparency in your development process is often well-received within the developer community.
|
||||||
|
|
||||||
|
8. **Case Studies and Testimonials**: Share experiences of other developers and companies that have successfully integrated your authentication application. Real-world examples and endorsements can be powerful in demonstrating th
|
||||||
|
e reliability and benefits of your product.
|
||||||
|
|
||||||
|
9. **Free Tier or Trial Period**: Offering a free tier or a trial period can encourage developers to test your application without any financial commitment. This can help alleviate initial hesitation and allows them to directly a
|
||||||
|
ssess the quality and integration process.
|
||||||
|
|
||||||
|
10. **Easy Integration**: Make the integration process as straightforward as possible. The easier it is to use your application, the more likely developers will try it and stick with it.
|
||||||
|
|
||||||
|
11. **Marketing and Thought Leadership**: Create valuable content for developers – blog posts, whitepapers, webinars, and tutorials – that position you as a thought leader in authentication and security. Show your expertise and s
|
||||||
|
hare knowledge that can help developers beyond just using your service.
|
||||||
|
|
||||||
|
12. **Community Engagement**: Engage with the developer community through social media, tech conferences, meetups
|
||||||
|
You: continue
|
||||||
|
AI: , and hackathons. Being actively involved and visible in the community can help build your reputation and trust. Moreover, listening to feedback and incorporating it into your product's development demonstrates that you valu
|
||||||
|
e user input and are committed to continuous improvement.
|
||||||
|
|
||||||
|
13. **Partnerships**: Form partnerships with other trusted companies and organizations in the tech field. This not just extends your reach but also confers upon you a part of the trust that these entities have already established
|
||||||
|
.
|
||||||
|
|
||||||
|
14. **Reliability**: Ensure your authentication service is highly available and performs consistently. Downtime or performance issues can erode trust quickly, so invest in robust infrastructure and have a solid incident response
|
||||||
|
plan.
|
||||||
|
|
||||||
|
15. **Updates and Communication**: Keep your product up-to-date with the latest security trends and threats. Communicate proactively with your user base about new features, patches, and updates.
|
||||||
|
|
||||||
|
16. **User Authentication Options**: Provide various authentication methods such as multi-factor authentication, single sign-on, biometric verification, etc. Flexibility can make your application more appealing to a broader audie
|
||||||
|
nce.
|
||||||
|
|
||||||
|
17. **Privacy Policy**: Have a clear and concise privacy policy explaining how you handle and protect user data. Privacy is a major concern for many users and being upfront about it can aid in building trust.
|
||||||
|
|
||||||
|
18. **
|
||||||
|
You: it seems like you might have more
|
||||||
|
AI: Business and Pricing Model Clarity: Transparently explain your pricing model and business practices to avoid any hidden charges or surprises. Trust can be quickly eroded if customers feel they've been misled about the cost o
|
||||||
|
r terms of service.
|
||||||
|
|
||||||
|
19. **User Control and Consent**: Empower users with control over their data and require explicit consent where needed. When users feel in control of their data, they are more likely to trust your application.
|
||||||
|
|
||||||
|
20. **Feedback Loops**: Implement a system for users to provide feedback easily and make it clear that their input is valued and considered. This not only helps you improve your service but also demonstrates to users that you are
|
||||||
|
responsive and customer-centric.
|
||||||
|
|
||||||
|
21. **Bounty Programs**: Consider implementing a bug bounty program to encourage ethical hackers to report vulnerabilities in your system. This can help you identify and fix security issues before they are exploited and shows you
|
||||||
|
r commitment to security.
|
||||||
|
|
||||||
|
22. **Incremental Rollouts**: If viable, roll out your application incrementally, starting with beta testers or a limited audience. This allows you to gather initial feedback and make necessary improvements, thereby refining your
|
||||||
|
product before a full-scale launch.
|
||||||
|
|
||||||
|
Trust is essential in the world of security and authentication. By following the above strategies and maintaining a clear focus on quality and transparency, you can
|
||||||
|
You: continue once more
|
||||||
|
AI: build a strong foundation for trust with your customer base. Here are a few more things you can consider to engender trust in your authentication application:
|
||||||
|
|
||||||
|
23. **User Education and Resources**: Educate your users about security best practices and the importance of strong authentication. Provide resources such as guides and articles that explain security concepts in layman's terms. T
|
||||||
|
his can also involve training materials or webinars that teach users how to get the most out of your application.
|
||||||
|
|
||||||
|
24. **Data Breach Response Plan**: Have a clear and tested data breach response plan in place. Being able to react swiftly and transparently in the event of a breach can help maintain trust. It shows customers that you are prepar
|
||||||
|
ed and proactive in dealing with worst-case scenarios.
|
||||||
|
|
||||||
|
25. **Responsible Disclosure**: Encourage responsible disclosure of security issues by stating your policies clearly, including how you handle reports of security vulnerabilities, and possibly offering recognition or rewards for
|
||||||
|
those reports.
|
||||||
|
|
||||||
|
26. **Regular Security Updates and Patch Notes**: Regularly update your application with security patches and provide detailed notes on what was improved. Keeping your system up-to-date and informing users about changes can insti
|
||||||
|
ll confidence in your commitment to their security.
|
||||||
|
|
||||||
|
Remember, building trust is a long-term effort that involves consistent communication, a proactive stance on security, and
|
||||||
|
You:
|
||||||
|
|
||||||
|
|
||||||
|
------------------- Fixed the length issue ----------------------------------
|
||||||
|
|
||||||
|
Building trust in an authentication application is crucial because security is a top concern for developers and their users. Here are several steps you can take to engender trust in your application:
|
||||||
|
|
||||||
|
1. **Security First Design**: Ensure that your application is designed with security as a primary focus. Follow best practices for secure coding, and regularly audit and update your code to address any vulnerabilities.
|
||||||
|
|
||||||
|
2. **Transparency**: Be open about how your application works. Provide detailed documentation that explains the security measures you have implemented and how they protect your users.
|
||||||
|
|
||||||
|
3. **Third-Party Audits and Certifications**: Obtain security certifications from reputable organizations. Having your application's security audited by a third party can provide an unbiased validation of your security claims.
|
||||||
|
|
||||||
|
4. **Compliance with Standards**: Ensure your application complies with relevant security standards and regulations (e.g., OAuth 2.0, OpenID Connect, GDPR, HIPAA, etc.). Compliance demonstrates that you are serious about security
|
||||||
|
and privacy.
|
||||||
|
|
||||||
|
5. **Use of Well-Known Algorithms and Protocols**: Use industry-standard encryption algorithms and authentication protocols. Avoid proprietary or obscure methods that have not been thoroughly vetted by the security community.
|
||||||
|
|
||||||
|
6. **Open Source**: Consider making your application open source. This allows the community to review and contribute to your code, which can improve security and trustworthiness.
|
||||||
|
|
||||||
|
7. **Easy Integration**: Make it easy for developers to integrate your application into their systems. Provide SDKs, APIs, and clear documentation. If developers find it difficult to use your application, they are less likely to
|
||||||
|
trust it.
|
||||||
|
|
||||||
|
8. **Demonstrable Reliability**: Offer a reliable service with high uptime. Reliability is a key component of trust, and if your service is consistently available, developers are more likely to trust it.
|
||||||
|
|
||||||
|
9. **Customer Support**: Provide excellent customer support. Be responsive to inquiries and issues. If developers feel supported, they are more likely to trust your application.
|
||||||
|
|
||||||
|
10. **Case Studies and Testimonials**: Share success stories from other developers who have successfully implemented your application. Testimonials from satisfied users can be very persuasive.
|
||||||
|
|
||||||
|
11. **Free Trial or Freemium Model**: Offer a free trial or a freemium version of your application. This allows developers to test your application and see its benefits firsthand without any financial commitment.
|
||||||
|
|
||||||
|
12. **Marketing and Branding**: Invest in professional marketing and branding. A strong brand can convey trustworthiness and professionalism.
|
||||||
|
|
||||||
|
13. **Community Engagement**: Engage with the developer community through forums, social media, conferences, and hackathons. Building relationships with developers can lead to trust and word-of-mouth recommendations.
|
||||||
|
|
||||||
|
14. **Educational Content**: Provide educational content that helps developers understand security concepts and best practices. This positions you as an expert in the field and builds trust in your application.
|
||||||
|
|
||||||
|
15. **Regular Updates and Communication**: Keep your application up-to-date with the latest security features and communicate these updates to your users. Regular communication about improvements demonstrates your commitment to s
|
||||||
|
ecurity.
|
||||||
|
|
||||||
|
Remember, building trust takes time and consistent effort. By focusing on security, transparency, and user support, you can create a strong foundation of trust for your authentication application.
|
||||||
|
|
Reference in New Issue
Block a user