Skip to content

feat: paper fetch - #163

Open
andrea-gariboldi wants to merge 7 commits into
mainfrom
paper-fetch
Open

andrea-gariboldi wants to merge 7 commits into
mainfrom
paper-fetch

Conversation

@andrea-gariboldi

Copy link
Copy Markdown
Contributor

This PR will:

  • Implement a web-search tool that given a query, retrieves relevant papers and downloads them.

The whole design is summarised in the figure below.

ChatGPT Image Sep 4, 2026, 11_57_29 AM

Please consider this is a first version, where many design choices have been taken on my own. I am more than happy to revise the design of this feature together.

@MartinekV MartinekV self-assigned this Sep 8, 2026

@MartinekV MartinekV left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the sub-agent delegation approach
This PR is the first step of a tool that is basically question -> answer (supported by literature) for the agent. That can be decomposed into question - get paper pdfs - retrieve from paper pdfs - answer. This PR only handles the get paper pdfs part, however its helpful to consider the next part as well as they might become the same subagent. With that in mind:

I suggest switching from duckduckgo search to literature-specific search option (see comments)
We also need to make sure we retrieve the paper if its available. Some sources might be paywalled.
See other comments

This is not a command to change things - simply to explore that option and discuss it together. Duckduck go might still be a reasonable first version.

query: A string describing one scientific topic or question for which relevant papers are to be fetched.
"""
try:
websearch_result = await duckduckgo_search_tool(max_results=config.paper_fetch_max_results).function(query=query)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need separate credits for duckduckgo search?

AFAIK codex sub actually comes with search capability - you dont need an extra token for that, it comes natively with the models. We could put that as a requirement and only support models that offer native websearch capability. Not sure how that would work with self-hosted/local models though.

I had a little bit of a look and i really like semantic scholar's ASTA - its free, specialized on scientific literature, and has a few components, one of them - PaperFinder - could do this job, probably better than a general search. That would allow us to get rid of the search loop also which would be nice.

At some point we will also need some retrieval over these papers. ASTA has also a solution for this - ScholarQA - im not sure if its only summarizer of a query-based retrieval - we'd need to check. Alternatively PaperQA2 (https://github.com/future-house/paper-qa) could be out retrieval agent (it assumes you already have folder with PDFs)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial answers:

  • duckduckgo search does not need separate credits. It is based on the ddgs library: https://pypi.org/project/ddgs/ and as far as I can tell they are not directly enforcing some rate limit
  • Yes, native web search comes natively for different providers and PydanticAI provides a WebSearch capability which is meant for this goal: https://pydantic.dev/docs/ai/capabilities/web-search/ . I wanted to avoid such solution as this would be Provider dependent and we would not have any control on the implementation itself. Additionally, as you mentioned, not all the providers might support such "native" web search capability.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/allenai/asta-paper-finder/blob/main/README.md
I was checking the implementation and README for asta-paper-finder and it seems like it requires many API keys: The needed keys are: OPENAI_API_KEY, S2_API_KEY, COHERE_API_KEY, GOOGLE_API_KEY. I will continue and check if semantic scholar has a different implementation, for now the implementation that seems to not ask for all those API keys is the Asta Scientific Corpus Tool: https://allenai.org/asta/resources/mcp

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I found (which I think is what we need) is the search_papers_by_relevance method in Asta Scientific Corpus. It implements the search of papers given a query.



PAPER_FETCH_SYSTEM_PROMPT = """
Your goal is to find scientific papers informing a machine learning modeling task.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want the search agent to be ML-specific? IMO the query should be fine if its generic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree on this. I will change the prompt to make it more generic. If we are going for fetching with no LLM agent (which seems to be the direction) this prompt will be deleted completely, and only the tool docstring will guide the main agent on how to make the query itself

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, regarding the prompt itself I was thinking ideally we would retrieve papers that are implementing/summarising a ML modeling decision, but as you pointed out, the query does not have to be specific to the ML domain

from agentomics.utils.config import Config


def create_save_paper_pdf_tool(config: Config) -> Tool[Any]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be automated in the validator imo, given a paper doi, there should be tools out there that scout for an available pdf of it.

def create_save_paper_pdf_tool(config: Config) -> Tool[Any]:
fetch = web_fetch_tool(timeout=config.web_fetch_timeout).function

async def save_paper_pdf(url: str, filename: str) -> str:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we fetching the supplementary materials as well? I'm not sure how that is handled in existing solutions, but afaik sometimes these can be a separate pdf.

@andrea-gariboldi

andrea-gariboldi commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Implemented as discussed the "programmatic" way to fetch papers. The search happens using the ASTA scientific corpus search tool: https://allenai.org/asta/resources/mcp. Then we retrieve from semantic scholar the candidates. For each one of the candidates we have a pool of dbs and resources we try to fetch papers from.

I made a small diagram to describe how the implementation works now (the diagram code can be used to show to your agent a schematic representation of the code).

https://mermaid.live/edit#pako:eNp1lv1y2kYQwF9lRzOdaWcwAWNITDvpyIATErAJ2PFH6GQO3cm6WrpT7062qcf_9gH6iH2SrlYCS9Dyl3Ta_e3H7QfPXqC58PoehLF-DCJmHFwMlwro539bev6dUA4CFscWUpYK8z0ULoh-_CMTZv3T0vsNDg7ewwlKLgQzQQS-dQxcZHR2F8F0MPtlZd68nwuUtw6cdLFowBpF6XwoQpbFrg_tVm7UCItvFqkbF04IP0D8LDde2JiTGOjV7yJwlkCFa5I3qiYqnAFxhsgZRCK4B8seBIfZ8LRQX4iUGeYEBhpE-IEpDpkqX4hddWpIsBHCPguRwgOLJd9o5sg90VMUPWGYNliIhCknA1gEkY6ZwZApM-SFH8c7VmE8tLUEiicnjGLxmNsG6FQoPwiEtTMektGN2VMy--F56X28uJjB0eHxr0vvZfP1A36FpXcjkMGcE0nqLDqSMKmkult6pPwRfb5i0kEHrAi04oUjU_YkkyzBU6cdi7f6lZg_FjHvWJsLZ6SwGEHEMusEL-2M0c6lFZBT1pAIxzhzrIIj_TNNwp8womkpArHW91kKNsMUCC54NcRPFaVx7RCjptPPpV0jXGYUJrxmeqMyJtnJt9x_q-OHvEIUlyiHmFAbEHhbO5dW8f1zob55tdnqzrA0AoJlTmqVV0YmY_7Khcv5xIJUkBqpjcSkaMNr1Pw3IfIU1dtNuFQpWz9ij-blR_rbopHYUzA8H1NJX57N_JsrfzL5Ppr648kOckrIM0QeNoGZa_mwwRGNLqksP6xL9KoUQvoO6YxI52WGZ9MBiodGJ9scE_DcRcI8SpRwZk0-_vPX34X0Du-ceDO8_JKlM1W77vw3q1z5l9d5NMoM9kmOhdUaA2BBOYbKFAX6Aftsk6H_sv6FkHNEjkNgwGUYCpNPxdQIvCN8yLWlLdwqOplzWEk9f8L0vMGoOT2V2dzBz6pVuUArnWbV6dqNogNFBtAae2AyZqtY7PDmBah6tKCjC2QfNf_fr-0tb26J4tL5jKIkYX3vX_UFoS8R3W3uT7fahNrawChslqaxzIdAjXZJtK9I6zVhYLS1RoT1FEyw6wHbHl35GZSGe7GmIYqFvkv7SrQrat4EIwCeodFg02OEm2F_CFPt6712E4pvqVeEvEbkh9EFKOyHeuMS81THuE3RK45OBbXZeE36N1jJi4zyEmYx0IxGP1KtbFGWeSniHjU4lx-li-AHTMFBteBvqkVzm1c7LjRgmx0teTMtV0JFvmwO38-nqDbVWVZl-34Vfl0_3jDyjX-e4HpwkbR7c--2EMr3dt4KxezHjUtLnCKsrOkGhDIW31PmogrCL1a2TztbY1WpTBTJ2G6q_c3sn5RK24NiAfsjoiQrqWo7XonHeA1cP6pYM76_vkel9hZXHpxSTeWLA2KJa1mHOzHW_pyMaLWRoAyxZtGHavN6De_OSO71nclEw0uEwfjw1XvOzS49HJMJyvXxEUsqezrgzNwfBDrWmPKlekH9lKlbrZMNgv58ef2QxRbfsjS_4qFkuHteRbCqhRngxHJev91udwji9Z-9J69_2H3XbPd6x61Wr3P0ttftNby11z_odI47zXan1T7sHXc77cPuS8P7k8x2m-86rW7vbbvVOmwdH3ePXv4FHYohFg

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants