Turns a topic into the questions worth asking, searches each one, and files the findings in Notion with the source behind every line.
Uses
Claude
Jina AINotion
Research a topic question by question
Give it a topic and run it, and the AI breaks it into the specific questions it raises. Each question is searched separately, the search results become numbered extracts, and the AI writes one finding per extract with its number on every line.
What you get is a new page in your Notion database, titled with your topic, holding the questions asked, the findings with a link on every line to its source, and a numbered list of the pages behind them. Nothing unsourced reaches the page: a finding citing a number that was never fetched is discarded, as is any line containing a web address, and at most one finding is kept per source. If the results carry too little text to write from, or every finding is discarded, the run stops and nothing is filed. The page ends with a count of sources used and lines dropped, so a thin run cannot pass for a thorough one.
Each run files a fresh page and touches nothing you already have. The database needs to be shared with your Notion integration.
researchTopic to blank.Set researchTopic to blank.notionDatabaseId to blank.Set notionDatabaseId to blank.titlePropertyName to Name.Set titlePropertyName to Name.maxQuestions to 5.Set maxQuestions to 5.resultsPerQuestion to 4.Set resultsPerQuestion to 4.maxSources to 12.Set maxSources to 12.questionLimit to maxQuestions multiplied by 1.Set questionLimit to maxQuestions multiplied by 1.questionLimit is greater than 20If questionLimit is greater than 20questionLimit to 20.Change questionLimit to 20.sourceLimit to maxSources multiplied by 1.Set sourceLimit to maxSources multiplied by 1.sourceLimit is greater than 30If sourceLimit is greater than 30sourceLimit to 30.Change sourceLimit to 30.resultsWanted to resultsPerQuestion multiplied by 1.Set resultsWanted to resultsPerQuestion multiplied by 1.resultsWanted is greater than 10If resultsWanted is greater than 10resultsWanted to 10.Change resultsWanted to 10.planPrompt to Break the research topic below into the specific questions somebody would have to answer to cover it properly.Set planPrompt to Break the research topic below into the specific questions somebody would have to answer to cover it properly.
Rules:
- Write one question per line and nothing else. No numbering, no bullets, no preamble, no closing remark.
- Every line must end with a question mark. A line that does not is ignored.
- Each question must be answerable from public sources and specific enough to type into a search engine.
- Ask about different parts of the topic rather than rewording one question.
- Write at most maxQuestions questions.
Topic:
researchTopic.planText to blank.Set planText to blank.planErrorIf a step below fails, save the error as planErrorplanPrompt. Save it as plan.Ask Claude: planPrompt. Save it as plan.
Maximum response length: 400plan.response_text and save it as planText.Trim plan.response_text and save it as planText.questions to an empty list.Set questions to an empty list.questionCount to 0.Set questionCount to 0.planLine in planText split by a new line:For each planLine in planText split by a new line:questionCount is greater than or equal to questionLimitIf questionCount is greater than or equal to questionLimitplanLine and save it as candidate.Trim planLine and save it as candidate.candidate doesn't end with ?If candidate doesn't end with ?candidate is less than 8If the length of candidate is less than 8candidate to the end of questions and save it as questions.Add candidate to the end of questions and save it as questions.questionCount.Add 1 to questionCount.questionCount is 0If questionCount is 0sources to an empty list.Set sources to an empty list.sourceUrls to an empty list.Set sourceUrls to an empty list.sourceCount to 0.Set sourceCount to 0.evidenceCharacters to 0.Set evidenceCharacters to 0.question in questions:For each question in questions:sourceCount is greater than or equal to sourceLimitIf sourceCount is greater than or equal to sourceLimitresults to an empty list.Set results to an empty list.searchErrorIf a step below fails, save the error as searchErrorquestion with Jina. Save it as found.Search the web for question with Jina. Save it as found.results to found.results.Change results to found.results.question. The other questions still ran.Show in the output: Could not search for one of the research questions: question. The other questions still ran.result in results:For each result in results:sourceCount is greater than or equal to sourceLimitIf sourceCount is greater than or equal to sourceLimitresult.url and save it as resultUrl.Trim result.url and save it as resultUrl.resultUrl doesn't start with httpIf resultUrl doesn't start with httpsourceUrls contains resultUrlIf sourceUrls contains resultUrlresult.description and save it as resultText.Trim result.description and save it as resultText.resultText is empty or resultText is nullIf resultText is empty or resultText is nullresult.title and save it as resultTitle.Trim result.title and save it as resultTitle.resultTitle is empty or resultTitle is nullIf resultTitle is empty or resultTitle is nullresultTitle to Untitled page.Change resultTitle to Untitled page.sourceCount.Add 1 to sourceCount.resultUrl to the end of sourceUrls and save it as sourceUrls.Add resultUrl to the end of sourceUrls and save it as sourceUrls.sources and save it as sources.Add a record of number, title, url, and snippet to the end of sources and save it as sources.evidenceCharacters to evidenceCharacters plus the length of resultText.Change evidenceCharacters to evidenceCharacters plus the length of resultText.sourceCount is 0If sourceCount is 0evidenceCharacters is less than 200If evidenceCharacters is less than 200evidenceLines to an empty list.Set evidenceLines to an empty list.source in sources:For each source in sources:headLine to [source.number] source.title.Set headLine to [source.number] source.title.headLineAdd headLine
source.snippet to the end of evidenceLines and save it as evidenceLines.evidenceLines with a blank line and save it as evidenceText.Join evidenceLines with a blank line and save it as evidenceText.questions with a new line and save it as questionText.Join questions with a new line and save it as questionText.synthesisPrompt to You are writing up research findings from extracts that were fetched for you. Use only those extracts.Set synthesisPrompt to You are writing up research findings from extracts that were fetched for you. Use only those extracts.
Rules:
- Write one finding per line and nothing else. No preamble, no headings, no closing remark.
- Each line must be exactly: the extract's number, a vertical bar, then one sentence. For example:
3|Two thirds of the councils surveyed took more than a week to respond.
- The sentence must say what that one extract says. Do not merge two extracts into one line, and do not conclude anything the extract does not state.
- Never write a web address. Cite by number only. A line containing an address is discarded.
- A line whose number is not one of the extracts below is discarded, so do not invent numbers.
- Leave out an extract that says nothing useful about the topic rather than filling the gap from memory.
- Write at most one line per extract.
Topic:
researchTopic
Questions asked:
questionText.synthesisPrompt to synthesisPromptChange synthesisPrompt to synthesisPrompt
Extracts:
evidenceText.findingsText to blank.Set findingsText to blank.synthesisErrorIf a step below fails, save the error as synthesisErrorsynthesisPrompt. Save it as synthesis.Ask Claude: synthesisPrompt. Save it as synthesis.
Maximum response length: 1500synthesis.response_text and save it as findingsText.Trim synthesis.response_text and save it as findingsText.findingBlocks to an empty list.Set findingBlocks to an empty list.acceptedCount to 0.Set acceptedCount to 0.droppedCount to 0.Set droppedCount to 0.findingLine in findingsText split by a new line:For each findingLine in findingsText split by a new line:acceptedCount is greater than or equal to sourceCountIf acceptedCount is greater than or equal to sourceCountfindingLine and save it as rawLine.Trim findingLine and save it as rawLine.rawLine is emptyIf rawLine is emptyrawLine doesn't contain |If rawLine doesn't contain |droppedCount.Add 1 to droppedCount.rawLine by | and save it as lineParts.Split rawLine by | and save it as lineParts.lineParts with [ replaced by with ] replaced by with . replaced by and save it as citedNumber.Trim the first item of lineParts with [ replaced by with ] replaced by with . replaced by and save it as citedNumber.lineParts joined by | and save it as findingText.Trim the items from index 1 onward of lineParts joined by | and save it as findingText.findingText is emptyIf findingText is emptydroppedCount.Add 1 to droppedCount.findingText contains http (ignoring case)If findingText contains http (ignoring case)droppedCount.Add 1 to droppedCount.citedUrl to blank.Set citedUrl to blank.candidateSource in sources:For each candidateSource in sources:candidateSource.number is citedNumberIf candidateSource.number is citedNumbercitedUrl to candidateSource.url.Change citedUrl to candidateSource.url.citedUrl is emptyIf citedUrl is emptydroppedCount.Add 1 to droppedCount.acceptedCount.Add 1 to acceptedCount.findingBlocks and save it as findingBlocks.Add a record of object, type, and paragraph to the end of findingBlocks and save it as findingBlocks.acceptedCount is 0If acceptedCount is 0researchTopic to 90 characters and save it as pageTitle.Shorten researchTopic to 90 characters and save it as pageTitle.page to nothing.Set page to nothing.pageId to blank.Set pageId to blank.notionErrorIf a step below fails, save the error as notionErrorpageTitle in notionDatabaseId. Save it as page.Create the page pageTitle in notionDatabaseId. Save it as page.page.id and save it as pageId.Trim page.id and save it as pageId.pageId is empty or pageId is nullIf pageId is empty or pageId is nullquestionBlocks to an empty list.Set questionBlocks to an empty list.askedQuestion in questions:For each askedQuestion in questions:questionBlocks and save it as questionBlocks.Add a record of object, type, and bulleted list item to the end of questionBlocks and save it as questionBlocks.sourceBlocks to an empty list.Set sourceBlocks to an empty list.citedSource in sources:For each citedSource in sources:sourceLabel to [citedSource.number] citedSource.title - .Set sourceLabel to [citedSource.number] citedSource.title - .sourceBlocks and save it as sourceBlocks.Add a record of object, type, and bulleted list item to the end of sourceBlocks and save it as sourceBlocks.coverageNote to Written from sourceCount sources found across questionCount research questions.Set coverageNote to Written from sourceCount sources found across questionCount research questions.coverageNote to coverageNote droppedCount lines the model wrote were dropped because they did not point at one of those sources. Every statement above is what its own source says, not a conclusion drawn beyond it.Change coverageNote to coverageNote droppedCount lines the model wrote were dropped because they did not point at one of those sources. Every statement above is what its own source says, not a conclusion drawn beyond it.pageBlocks to [{object:block,type:heading_2,heading_2:{rich_text:[{type:text,text:{content:Questions asked}}]}}].Set pageBlocks to [{object:block,type:heading_2,heading_2:{rich_text:[{type:text,text:{content:Questions asked}}]}}].pageBlocks and questionBlocks into one list and save it as pageBlocks.Combine pageBlocks and questionBlocks into one list and save it as pageBlocks.object:block,type:heading_2,heading_2:{rich_text:[{type:text,text:{content:Findings}}]}} to the end of pageBlocks and save it as pageBlocks.Add {object:block,type:heading_2,heading_2:{rich_text:[{type:text,text:{content:Findings}}]}} to the end of pageBlocks and save it as pageBlocks.pageBlocks and findingBlocks into one list and save it as pageBlocks.Combine pageBlocks and findingBlocks into one list and save it as pageBlocks.object:block,type:heading_2,heading_2:{rich_text:[{type:text,text:{content:Sources}}]}} to the end of pageBlocks and save it as pageBlocks.Add {object:block,type:heading_2,heading_2:{rich_text:[{type:text,text:{content:Sources}}]}} to the end of pageBlocks and save it as pageBlocks.pageBlocks and sourceBlocks into one list and save it as pageBlocks.Combine pageBlocks and sourceBlocks into one list and save it as pageBlocks.pageBlocks and save it as pageBlocks.Add a record of object, type, and paragraph to the end of pageBlocks and save it as pageBlocks.pageId.Add content to pageId.acceptedCount sourced findings into Notion from sourceCount sources.Show in the output: Filed acceptedCount sourced findings into Notion from sourceCount sources.