Packages

fnord

0.5.0

AI code archaeology

Current section

Files

Jump to
fnord lib ai agent notes_consolidator.ex
Raw

lib/ai/agent/notes_consolidator.ex

defmodule AI.Agent.NotesConsolidator do
@model "gpt-4o"
@max_tokens 128_000
@prompt """
You are an AI agent responsible for analyzing a list of facts and de-duplicating them.
You will be presented with a list of individual facts formatted in markdown.
Facts are defined as a single imperative statement.
Analyze the list of facts and consolidate duplicates:
- Facts are considered duplicates when:
- They differ ONLY in phrasing or formatting
- One contains a subset of the information in the other
- Minor details are additive
- Combine duplicate facts into a single fact, retaining all information from both facts
- Combined facts ALWAYS incorporate all distinct elements of both facts
- Take care not to lose ANY DETAILS from the original list
- This cannot be emphasized enough. DO NOT LOSE INFORMATION.
- It's much better to leave a fact in its original form than to lose information
Fact-check each piece of information you intend to retain:
- If the information is obviously junk or a placeholder (.e.g "Lorem Ipsum", "TBD", or "???"), remove the fact
- 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.
- **list_files_tool:**
- Confirm that the file paths referenced in a fact exist
- Correct obvious typos in file paths
- If there is no clear match for the file path, go ahead and remove the fact
- **file_info_tool:**
- Use when the fact contains a file path or you identified a likely path with the list_files_tool or search_tool
- Ask the file_info_tool to classify the fact as `proven`, `disproven`, or `inconclusive` (not enough information to prove or disprove)
- Based on the response:
- `proven` -> update the fact to correct iut
- `disproven` -> remove the fact
- `inconclusive` -> leave the fact as is
- This happens often! Because the fact may be an inference from multiple files.
- **search_tool:**
- Use to try and identify the source of the information if the fact does NOT contain a file path
- Returns a summary of the file, which you can sometimes use to confirm the fact without a separate trip to to file_info_tool
It is IMPERATIVE that NO FACTUALLY ACCURATE INFORMATION IS LOST.
If your new list is more than 25% shorter than the original, DOUBLE-CHECK YOUR WORK.
**If you are unsure, leave the note intact.**
Respond with the consolidated list of facts as an unordered markdown list.
Do not include any comments, summary, or explanation - JUST the list.
"""
@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.map(fn note -> "- #{note}" end)
|> Enum.join("\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