Packages
fnord
0.5.1
0.9.40
0.9.39
0.9.38
0.9.37
0.9.36
0.9.35
0.9.34
0.9.33
0.9.32
0.9.31
0.9.30
0.9.29
0.9.28
0.9.27
0.9.26
0.9.25
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.14
0.9.13
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.99
0.8.98
0.8.97
0.8.96
0.8.95
0.8.94
0.8.93
0.8.92
0.8.91
0.8.90
0.8.89
0.8.88
0.8.87
0.8.86
0.8.85
0.8.84
0.8.83
0.8.82
0.8.81
0.8.80
0.8.79
0.8.78
0.8.77
0.8.76
0.8.75
0.8.74
0.8.73
0.8.72
0.8.71
0.8.70
0.8.69
0.8.68
0.8.67
0.8.66
0.8.65
0.8.64
0.8.63
0.8.62
0.8.61
0.8.60
0.8.59
0.8.58
0.8.57
0.8.56
0.8.55
0.8.54
0.8.53
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.47
0.8.46
0.8.45
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.1
0.8.0
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
AI code archaeology
Current section
Files
Jump to
Current section
Files
lib/ai/agent/notes_verifier.ex
defmodule AI.Agent.NotesVerifier do
@model "gpt-4o"
@max_tokens 128_000
@prompt """
You are an AI agent responsible for fact-checking a list of notes.
You will be presented with a mess of individual facts and documents.
Input may include mixed formats. It is your job to organize them into a coherent structure.
Investigate each of the claims in each note and attempt to fact-check them.
Process:
1. Use the list_files_tool to get a list of all current files in the project
2. If the fact includes a file path:
2.1. Look up the file in the list_files_tool output
2.2. If the path is no longer valid:
2.2.1. Use the search_tool to try to find the information in another file
2.3. Use the file_info_tool to verify the fact (see below)
3. If the fact does NOT include a file path:
3.1. Use the search_tool to try to find the information in another file or combination of files
3.2. Use the file_info_tool to attempt to verify the fact (see below)
Fact checking with the file_info_tool:
- Instruct the tool to classify the fact as `proven`, `disproven`, or `inconclusive` (not enough information to prove or disprove)
- If the fact is `proven`, update the fact to reflect the correct information
- If the fact is `disproven`, remove the fact
- If the fact is `inconclusive`, leave the fact as is; this **should** happen often because the fact may have been inferred from multiple files
- Do not include this tag in the final output; it is for your reference only
Combine as many tool calls as possible to parallelize your work
- Default concurrency is 8, and is handled by a pool of workers. Go nuts.
- You could totally do a request to the file_info_tool for EVERY fact at once and let the pool worry about it.
If a prior agent left notes prefixed with proven|disproven|inconclusive, go ahead and remove them from the note.
It is ESSENTIAL that NO FACTUALLY ACCURATE INFORMATION IS LOST.
**If you are unsure, leave the note intact (but fix any formatting issues).**
#{AI.Util.notebook_format_prompt()}
"""
@tools [
AI.Tools.FileInfo.spec(),
AI.Tools.ListFiles.spec(),
AI.Tools.Search.spec()
]
# -----------------------------------------------------------------------------
# Behaviour implementation
# -----------------------------------------------------------------------------
@behaviour AI.Agent
@impl AI.Agent
def get_response(ai, opts) do
with {:ok, notes} <- Map.fetch(opts, :notes) do
question =
notes
|> Enum.join("\n-----\n")
|> AI.Util.user_msg()
AI.Completion.get(ai,
max_tokens: @max_tokens,
model: @model,
tools: @tools,
messages: [AI.Util.system_msg(@prompt), question]
)
|> then(fn {:ok, %{response: response}} ->
notes =
response
|> String.split("\n")
|> Enum.map(fn line ->
line
|> String.trim()
|> String.trim_leading("-")
|> String.trim()
end)
|> Enum.join("\n")
{:ok, notes}
end)
end
end
end