feat: enhance scientific paper writer with detailed role instructions

This commit is contained in:
2025-07-07 23:21:23 +00:00
parent 68dc5820b0
commit 33047b4667
+353 -15
View File
@@ -39,7 +39,7 @@ context:
format: null
other: null
brainstorming_summary: null
vetting_sources: null
vetting_sources: []
table_of_contents: null
deep_research_sources: null
core_content_progress:
@@ -343,7 +343,10 @@ agents:
model: gpt-4-turbo
role: |
You are a creative partner for brainstorming. Engage in a conversation to refine the high-level idea and key
arguments. Summarize the the current brainstormed idea with each response.
arguments. Be careful not to respond with anything that describes the actual sections of the document
explicitly. We will define the structure later. Focus only on summarizing, in paragraph and bullet list form,
the content and ideas to write about, and not the order or structure. Summarize the the current brainstormed
idea with each response in full, repeating the relevant content from previous responses when still relevant.
The paper must be written to meet the following requirements:
- The topic of the paper must be: {{ context.paper_details.topic | tojson }}
@@ -354,19 +357,291 @@ agents:
- The paper must meet the following additional requirements: {{ context.paper_details.other | tojson }}
# --- Vetting Stage ---
# vetting_agent:
# type: llm
# config:
# provider: google
# model: gemini-2.5-pro
# web_search: true
# role: |
# You are a research assistant. Perform a high-level search on the topic. The user was asked how many
# sources they want, based on his response research the specified number of high-quality, peer-reviewed sources.
# For each source, provide a full citation, a retrieval link, and a complete one-page summary. Compile this into a
# clear list. Once this is provided engage in a conversation with the user to help refine the list of sources further
# as needed and requested by the user. Every time you respond during the conversation be sure to include all the
# detailed from your previous response, in addition to any changes the user requested.
#
# The paper must be written to meet the following requirements:
# - The topic of the paper must be: {{ context.paper_details.topic | tojson }}
# - The length of the paper must be no more than: {{ context.paper_details.length | tojson }} words
# - The paper must be written for the following audience: {{ context.paper_details.audience | tojson }}
# - The paper must be written with the intention of submitting it to the following publication: {{ context.paper_details.publication | tojson }}
# - The paper must be written in the following file format: {{ context.paper_details.format | tojson }}
# - The paper must meet the following additional requirements: {{ context.paper_details.other | tojson }}
#
# A high-level summary and intent for the content of the paper is the following:
#
# {{ context.brainstorming_summary | tojson }}
# --- Vetting Stage ---
vetting_agent:
type: composite
config:
strategy: route
route: vetting_router
vetting_conversation_agent:
type: llm
config:
provider: google
model: gemini-2.5-pro
role: |
You are a scientific expert research assistant. Your job is to discuss and plan out the research that will ultimately be used
throughout the writing of this document. Your purpose is to create a list of useful citations that would be
useful across the entire paper while keeping in mind after we define the structure and sections of the paper
we will also collect sources specific to each section and sub section, so we only want to compile sources that
are likely to be useful across multiple sections of this paper. Your job is to talk to the user and help refine
the list of cited sources that will be the basis for this paper.
When the user has clearly stated changes to the sources that are desired (adding new sources, removing or
changing existing sources, etc.) then reply only with "CHANGE_SOURCES: " followed by a summary of the changes
requested by the user. be detailed and be sure to include not only the nature of the changes, or which sources
are to be removed or added, but also how many new sources are needed of a particular kind. Otherwise interact
with the user conversationally and work with the user to determine how we can improve the list or sources we
have already found in our research.
The paper must be written to meet the following requirements:
- The topic of the paper must be: {{ context.paper_details.topic | tojson }}
- The length of the paper must be no more than: {{ context.paper_details.length | tojson }} words
- The paper must be written for the following audience: {{ context.paper_details.audience | tojson }}
- The paper must be written with the intention of submitting it to the following publication: {{ context.paper_details.publication | tojson }}
- The paper must be written in the following file format: {{ context.paper_details.format | tojson }}
- The paper must meet the following additional requirements: {{ context.paper_details.other | tojson }}
A high-level summary and intent for the content of the paper is the following:
{{ context.brainstorming_summary | tojson }}
The current sources we are considering are the following (in JSON format):
{{ context.vetting_sources | tojson }}
vetting_action_processor:
type: tool
config:
tools:
- name: vetting_action_processor
code: |
import json
error_occurred = False
if 'vetting_expanded_plan' not in context:
try:
original_plan = json.loads(message)
if not isinstance(original_plan, list):
raise ValueError("Plan is not a list")
expanded_plan = []
for action in original_plan:
action_type = action.get('action')
count = action.get('count', 1)
if action_type in ['find', 'change'] and count > 1:
for _ in range(count):
single_action = action.copy()
single_action['count'] = 1
expanded_plan.append(single_action)
else:
expanded_plan.append(action)
context['vetting_expanded_plan'] = expanded_plan
context['vetting_plan_index'] = 0
except (json.JSONDecodeError, ValueError) as e:
result = f"ERROR: Invalid plan format: {e}. Returning to conversation."
error_occurred = True
if not error_occurred:
plan = context.get('vetting_expanded_plan', [])
index = context.get('vetting_plan_index', 0)
if index >= len(plan):
context.pop('vetting_expanded_plan', None)
context.pop('vetting_plan_index', None)
context.pop('current_vetting_action', None)
result = "GOTO_VETTING_CONVERSATION"
else:
action = plan[index]
context['vetting_plan_index'] = index + 1
context['current_vetting_action'] = action
action_type = action.get('action', '').upper()
result = f"GOTO_VETTING_{action_type}"
vetting_find_agent:
type: llm
config:
provider: google
model: gemini-1.5-pro
web_search: true
json_mode:
schema:
type: object
properties:
citation: { type: string, description: "Full citation (e.g., APA, MLA)." }
link: { type: string, description: "Direct URL to the source PDF or page." }
summary: { type: string, description: "A detailed summary of the source, at least one full page in length." }
required: [citation, link, summary]
role: |
You are a research assistant. Perform a high-level search on the topic. You already asked the user how many
sources they want, based on his response research the specified number of high-quality, peer-reviewed sources.
For each source, provide a full citation, a retrieval link, and a one-page summary. Compile this into a clear
list. Once this is provided engage in a conversation with the user to help refine the list of sources further
as needed and requested by the user.
You are a master researcher. Your task is to find one single high-quality, peer-reviewed source.
The source MUST be relevant to the following instructions:
"{{ context.current_vetting_action.instructions }}"
You MUST provide a detailed summary of the source that is at least one full page long.
You MUST respond with a single JSON object conforming to the provided schema. Do NOT respond with an array.
vetting_remove_agent:
type: llm
config:
provider: openai
model: gpt-4-turbo
role: |
You are a librarian's assistant. Your task is to select sources for removal from a bibliography.
Here is the current list of sources:
{{ context.vetting_sources | tojson }}
You MUST identify {{ context.current_vetting_action.count }} sources to remove based on this instruction:
"{{ context.current_vetting_action.instructions }}"
You MUST respond with ONLY a JSON array containing the exact 'citation' strings of the sources to be removed.
Example response: ["Author, A. (Year). Title of work. Publisher.", "Another, B. (Year). Another title. Journal."]
vetting_change_agent:
type: llm
config:
provider: openai
model: gpt-4-turbo
json_mode:
schema:
type: object
properties:
citation: { type: string, description: "The exact, original citation of the source to be updated." }
new_summary: { type: string, description: "The new, revised summary for the source." }
required: [citation, new_summary]
role: |
You are a professional editor. Your task is to revise the summary of a single source from a bibliography.
Here is the current list of sources:
{{ context.vetting_sources | tojson }}
You MUST identify one source to update based on this instruction:
"{{ context.current_vetting_action.instructions }}"
After identifying the source, you must write a new, improved summary for it.
You MUST respond with ONLY a single JSON object containing two keys: 'citation' (the exact citation of the source to update) and 'new_summary' (the revised summary). Do NOT respond with an array.
vetting_update_agent:
type: tool
config:
tools:
- name: vetting_update_agent
code: |
import json
action = context.get('current_vetting_action', {}).get('action')
sources = context.get('vetting_sources', [])
if not isinstance(sources, list):
sources = []
try:
update_data = json.loads(message)
if action == 'find':
if isinstance(update_data, dict):
sources.append(update_data)
elif action == 'change':
if isinstance(update_data, dict):
citation_to_change = update_data.get('citation')
new_summary = update_data.get('new_summary')
if citation_to_change and new_summary:
for source in sources:
if source.get('citation') == citation_to_change:
source['summary'] = new_summary
break
elif action == 'remove':
if isinstance(update_data, list):
citations_to_remove = set(update_data)
sources = [s for s in sources if s.get('citation') not in citations_to_remove]
context['vetting_sources'] = sources
except json.JSONDecodeError:
pass
result = "CONTINUE_PLAN"
vetting_plan_agent:
type: llm
config:
provider: google
model: gemini-2.5-pro
web_search: true
json_mode:
schema:
type: array
items:
type: object
required: [action, count, instructions]
properties:
action:
type: string
enum: ["remove", "find", "change"]
description: Indicates if the user wants to find new sources, remove existing sources, or change the summary describing a source.
count:
type: integer
description: a non-zero positive integer indicating how many sources that match the user's instructions are to be added (when action is find) or removed (When action is remove), or changed (when the action is change).
instructions:
type: string
description: Instructions given by the user that explains the action to be performed.
role: |
You are a parsing tool. Your job is to take in a description of some changes to be made to a bibliography of
cited sources being compiled to write a new scientific article of the highest caliber. Your job is to take
a description of changes to be made to a list of researched citations, and turn it into JSON format. You will
break it down into a list of changes to be made. Each change will describe either something to be removed from
the citations list, or it will describe new sources the user wants to find and add to the list, or it will be
a request to change the summary of one or more of the sources in some way. The JSON you produce will be an array
of such changes. Each item in the array will have three properties:
- action, which will be "remove", "find" or "change" representing one of the three kinds of actions.
- count, which is the number of times that actions should be performed, for example if the action is "find" and
count is 3 then 3 new sources of the kind described are being requested.
- instructions, which describes the details of the action indicated
You are simply asked to take the message given to you and do your best to convert it into this format while
still preserving all the information in the original message.
The paper must be written to meet the following requirements:
- The topic of the paper must be: {{ context.paper_details.topic | tojson }}
- The length of the paper must be no more than: {{ context.paper_details.length | tojson }} words
- The paper must be written for the following audience: {{ context.paper_details.audience | tojson }}
- The paper must be written with the intention of submitting it to the following publication: {{ context.paper_details.publication | tojson }}
- The paper must be written in the following file format: {{ context.paper_details.format | tojson }}
- The paper must meet the following additional requirements: {{ context.paper_details.other | tojson }}
A high-level summary and intent for the content of the paper is the following:
{{ context.brainstorming_summary | tojson }}
The current sources we are considering are the following (in JSON format):
{{ context.vetting_sources | tojson }}
# --- Structure Stage ---
structure_agent:
type: llm
config:
provider: openai
model: gpt-4-turbo
role: |
You are an expert academic writer. Based on the users input, requirements, summary and vetted
sources, create a complete, logical table of contents. For each section/subsection, write a 1-2 sentence
description of its purpose.
The user may then have feedback or additional directions, engage in a conversation and modify your proposed
table of contents accordingly. Each time you respond make sure you respond with a complete updated version of
the table of contents along with the descriptions of each sentence. Never give a partial answer that only
describes the additions or changes without providing the complete updated table of contents.
The paper must be written to meet the following requirements:
- The topic of the paper must be: {{ context.paper_details.topic | tojson }}
@@ -379,14 +654,10 @@ agents:
A high-level summary and intent for the content of the paper is the following:
{{ context.brainstorming_summary | tojson }}
# --- Structure Stage ---
structure_agent:
type: llm
config:
provider: openai
model: gpt-4-turbo
role: "You are an expert academic writer. Based on the brainstormed summary and vetted sources, create a complete, logical table of contents. For each section/subsection, write a 1-2 sentence description of its purpose."
The vetted sources we have so far are the following:
{{ context.vetting_sources | tojson }}
# --- Deep Research Stage ---
deep_research_agent:
@@ -581,6 +852,15 @@ routes:
Please specify the topic this paper should be on, you can be vague as we will refine this later during the brainstorming stage.
to: output
- from: command_handler
condition: "context['writing_stage'] == 'vetting'"
transform: |
{{ message }}
You are now chatting with your AI Research Specialist. Their job is to compile some initial relevant sources for
the paper your writing. Give your Research Specialist some instructions to kick off the process.
to: output
- from: command_handler
to: output
@@ -600,6 +880,7 @@ routes:
- from: structure_agent
to: output
context: '{ "table_of_contents": {{ message | tojson }} }'
- from: core_content_handler
to: output
@@ -607,6 +888,63 @@ routes:
- from: formatting_handler
to: output
vetting_router:
# Entry point is the conversational agent
- from: input
to: vetting_conversation_agent
# If the user is just chatting, send the agent's response to the output
- from: vetting_conversation_agent
to: output
condition: "'CHANGE_SOURCES:' not in message"
# If the user requests changes, start the planning and execution flow
- from: vetting_conversation_agent
to: vetting_plan_agent
condition: "'CHANGE_SOURCES:' in message"
transform: '{{ message | replace("CHANGE_SOURCES:", "") | trim }}'
# The plan agent's JSON output goes to the action processor
- from: vetting_plan_agent
to: vetting_action_processor
# The action processor dispatches to the correct action agent
- from: vetting_action_processor
to: vetting_find_agent
condition: "'GOTO_VETTING_FIND' in message"
- from: vetting_action_processor
to: vetting_remove_agent
condition: "'GOTO_VETTING_REMOVE' in message"
- from: vetting_action_processor
to: vetting_change_agent
condition: "'GOTO_VETTING_CHANGE' in message"
# When the plan is done, go back to the conversational agent
- from: vetting_action_processor
to: vetting_conversation_agent
condition: "'GOTO_VETTING_CONVERSATION' in message"
transform: "The requested changes to the sources have been completed. Here is the updated list. What would you like to do next?"
# If the action processor encounters an error, report it to the user
- from: vetting_action_processor
to: output
condition: "'ERROR:' in message"
# The output of find/remove/change agents goes to the updater tool
- from: vetting_find_agent
to: vetting_update_agent
- from: vetting_remove_agent
to: vetting_update_agent
- from: vetting_change_agent
to: vetting_update_agent
# After the updater tool runs, route back to the action processor to continue the plan
- from: vetting_update_agent
to: vetting_action_processor
condition: "'CONTINUE_PLAN' in message"
discovery_router:
- from: input
to: ask_topic