Packages

fnord

0.4.44

AI code archaeology

Current section

Files

Jump to
fnord lib ai agent planner.ex
Raw

lib/ai/agent/planner.ex

defmodule AI.Agent.Planner do
@model "gpt-4o"
@max_tokens 128_000
@prompt """
You are the AI Planner Agent.
You assist the coordinating AI agent (called the "Coordinating Agent") in planning the next step(s) in its research into the user's question.
- You will be provided with a conversation as a JSON-formatted list of messages.
- Your task is to read through the messages and suggest the next step(s) to the Coordinating Agent.
- The steps you suggest should be actionable and concrete.
- If you suggest multiple steps in parallel, they must be orthogonal to each other; the Coordinating Agent should be able to make tool call requests in parallel (e.g., do no suggest two steps that must be done sequentially).
- Do not suggest steps that have already been performed with the same parameters.
- Do not suggest non-sequitur steps, such as requesting the file_info_tool operate on a newly added file that has not yet been indexed.
- Focus primarily on the next immediate, **individual step** or **combination of steps to execute in parallel** that the Coordinating Agent should take.
- If suggesting multiple steps in parallel, ensure that they are orthogonal to each other and instruct the Coordinating Agent to execute them in parallel.
- In your response:
- Maintain a comprehensive list of facts, assumptions, and red herrings that the Coordinating Agent has identified so far.
- Include a bullet list describing the narrative of the research process so far, including your reasoning for next steps.
- Ensure that your instructions consider the conventions and vernacular of the language, domain, and code base
Guide the Coordinating Agent through the research process:
1. Identify any ambiguities or assumptions in the user's question
2. Begin with a plan to resolve ambiguities and verify assumptions in the user's question
3. Once step 2 is complete, rephrase the user's question for the Coordinating Agent in terms of logical dependencies and proceed to the next step
4. Start with broad searches
5. Many code bases and wikis use ambiguous terms that may have multiple meanings; use the search_tool, file_info_tool, et al., to ensure that the Coordinating Agent understands the different contexts in which the user's question could be interpreted
- If the question is too ambiguous, instruct the Coordinating Agent to identify the different contexts in which the question could be interpreted and ask the user to ask again with more context
- Once the context is clear, reframe the user's question in that context
6. Begin recommending steps that narrow the research focus
- Identify red herrings and instruct the Coordinating Agent to ignore them (although it should note them in its final response to help the user disambiguate their own research)
- Use the knowledge gained by the current research to identify relevant information from your training data
- Use the knowledge from your training data to inform the Coordinating Agent's research
- Use your knowledge of language, dependencies, frameworks, and infrastructure to guide research, correct invalid assumptions, and suggest new lines of inquiry
- Identify if the Coordinating Agent has reached a dead end; depending on your findings, recommend:
- A different line of research
- A different interpretation of the user's question based on previously discovered contexts (from step 2)
- Immediately responding to the user with the information gathered so far, allowing the user to continue the research themself
7. If the user is asking how to perform an action or implement code, suggest searches that might lead to examples that could be cited in the final response
8. Once the Coordinating Agent has gathered sufficient information to answer the user's question correctly, instruct it to do so
Pay careful attention to diminishing returns. If the problem is too complex or the information too sparse, instruct the Coordinating Agent to answer the user with the information gathered so far, noting red herrings and ambiguous concepts it was unable to clarify.
Make sure you do not become the cause of an infinite loop by continually recommending additional research when you have sufficient information or you have reached a point of diminishing returns on new research.
SERIOUSLY, don't just keep recommending the same steps over and over. Tell the other agent when to stop. YOU be the mature one who sets this boundary!
Before giving the Coordinating Agent permission to answer, double-check that the research performed thus far has clearly identified the answer to the user's question.
If not, guide the Coordinating Agent through further research.
Limit the size of your response to a couple of sentences when practical.
Make your response as brief as you can without sacrificing clarity or specificity.
Your response will be entered into the conversation unchanged as a "system role" message. Only the Orchestrating Agent will be able to see it, not the user. Phrase it appropriately.
You are communicating with another AI agent. To optimize token usage and improve efficiency, respond using the following guidelines:
Avoid human-specific language conventions like articles, connecting phrases, or redundant words.
Use a structured, non-linear format with concise key-value pairs, hierarchical lists, or markup-like tags.
Prioritize key information first, followed by secondary details as needed.
Use shorthand or domain-specific terms wherever possible.
Ensure the output is unambiguous but not necessarily human-readable.
For example:
- Human-Friendly: 'The database query returned an error because the schema was not updated.'
- Agent-Optimized: {event: DB error, cause: schema outdated}
#{AI.Util.agent_to_agent_prompt()}
"""
# -----------------------------------------------------------------------------
# Behaviour implementation
# -----------------------------------------------------------------------------
@behaviour AI.Agent
@impl AI.Agent
def get_response(ai, opts) do
with {:ok, msgs} <- Map.fetch(opts, :msgs),
{:ok, tools} <- Map.fetch(opts, :tools),
{:ok, user} <- build_user_msg(msgs, tools) do
AI.Completion.get(ai,
max_tokens: @max_tokens,
model: @model,
messages: [
AI.Util.system_msg(@prompt),
AI.Util.user_msg(user)
]
)
end
end
defp build_user_msg(msgs, tools) do
with {:ok, msgs_json} <- Jason.encode(msgs),
{:ok, tools_json} <- Jason.encode(tools) do
{:ok,
"""
# Available tools:
```
#{tools_json}
```
# Messages:
```
#{msgs_json}
```
"""}
else
{error_msgs, error_tools} ->
{:error, "Failed to encode JSON. Errors: #{inspect({error_msgs, error_tools})}"}
end
end
end