{"id":136894,"date":"2025-09-14T14:38:10","date_gmt":"2025-09-14T14:38:10","guid":{"rendered":"https:\/\/www.newsbeep.com\/uk\/136894\/"},"modified":"2025-09-14T14:38:10","modified_gmt":"2025-09-14T14:38:10","slug":"building-research-agents-for-tech-insights","status":"publish","type":"post","link":"https:\/\/www.newsbeep.com\/uk\/136894\/","title":{"rendered":"Building Research Agents for Tech Insights"},"content":{"rendered":"<p class=\"wp-block-paragraph\"> ChatGPT something like: \u201cPlease scout all of tech for me and summarize trends and patterns based on what you think I would be interested in,\u201d you know that you\u2019d get something generic, where it searches a few websites and news sources and hands you those.<\/p>\n<p class=\"wp-block-paragraph\">This is because ChatGPT is built for general use cases. It applies normal search methods to fetch information, often limiting itself to a few web pages.<\/p>\n<p><img decoding=\"async\" style=\"\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*8r7ycVNiQx13dPT54VVv-g.png\" alt=\"Simple illustration of using ChatGPT search to build a report | Image by author\"\/><\/p>\n<p class=\"wp-block-paragraph\">This article will show you how to build a niche agent that can scout all of tech, aggregate millions of texts, filter data based on a persona, and find patterns and themes you can act on.<\/p>\n<p class=\"wp-block-paragraph\">The point of this workflow is to avoid sitting and scrolling through forums and social media on your own. The agent should do it for you, grabbing whatever is useful.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*DuMZsxtAuw88NkdM-QEdoA.png\" alt=\"\" style=\"\"\/><br \/>We\u2019ll be able to pull this off using a unique data source, a controlled workflow, and some prompt chaining techniques.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*SH4-l1WzE_E46J5-30_8zA.png\" alt=\"\"\/>The three different processes, the API, fetching\/filtering data, summarizing | Image by author<\/p>\n<p class=\"wp-block-paragraph\" id=\"d392\">By caching data, we can keep the cost down to a few cents per report.<\/p>\n<p class=\"wp-block-paragraph\">If you want to try the bot without booting it up yourself, you can join this <a href=\"https:\/\/discord.gg\/v6BV49DCpp\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Discord<\/a> channel. You\u2019ll find the repository <a href=\"https:\/\/github.com\/ilsilfverskiold\/ai-personalized-tech-reports-discord\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">here<\/a> if you want to build it on your own.<\/p>\n<p class=\"wp-block-paragraph\">This article focuses on the general architecture and how to build it, not the smaller coding details as you can find those in <a href=\"https:\/\/github.com\/ilsilfverskiold\/ai-personalized-tech-reports-discord\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Github<\/a>.<\/p>\n<p>Notes on building<\/p>\n<p class=\"wp-block-paragraph\">If you\u2019re new to building with agents, you might feel like this one isn\u2019t groundbreaking enough.<\/p>\n<p class=\"wp-block-paragraph\">Still, if you want to build something that works, you will need to apply quite a lot of software engineering to your AI applications. Even if LLMs can now act on their own, they still need guidance and guardrails.<\/p>\n<p class=\"wp-block-paragraph\">For workflows like this, where there is a clear path the system should take, you should build more structured \u201cworkflow-like\u201d systems. If you have a human in the loop, you can work with something more dynamic.<\/p>\n<p class=\"wp-block-paragraph\">The reason this workflow works so well is because I have a very good data source behind it. Without this data moat, the workflow wouldn\u2019t be able to do better than ChatGPT.<\/p>\n<p>Preparing and caching data<\/p>\n<p class=\"wp-block-paragraph\">Before we can build an agent, we need to prepare a data source it can tap into.<\/p>\n<p class=\"wp-block-paragraph\">Something I think a lot of people get wrong when they work with LLM systems is the belief that AI can process and aggregate data entirely on its own.<\/p>\n<p class=\"wp-block-paragraph\">At some point, we might be able to give them enough tools to build on their own, but we\u2019re not there yet in terms of reliability.<\/p>\n<p class=\"wp-block-paragraph\">So when we build systems like this, we need data pipelines to be just as clean as for any other system.<\/p>\n<p class=\"wp-block-paragraph\">The system I\u2019ve built here uses a data source I already had available, which means I understand how to teach the LLM to tap into it.<\/p>\n<p class=\"wp-block-paragraph\">It ingests thousands of texts from tech forums and websites per day and uses small NLP models to break down the main keywords, categorize them, and analyze sentiment.<\/p>\n<p class=\"wp-block-paragraph\">This lets us see which keywords are trending within different categories over a specific time period.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*FbxmuzeKGWDbEQ--6l6Z3w.png\" alt=\"\" style=\"\"\/><br \/>To build this agent, I added another endpoint that collects \u201cfacts\u201d for each of these keywords.<\/p>\n<p class=\"wp-block-paragraph\">This endpoint receives a keyword and a time period, and the system sorts comments and posts by engagement. Then it process the texts in chunks with smaller models that can decide which \u201cfacts\u201d to keep.<\/p>\n<p><img decoding=\"async\" style=\"\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*-5QFtVXlnzZM83DN51RtkQ.png\" alt=\"The \u201cfacts\u201d extracting process for each keyword | Image by author\"\/><br \/>We apply a last LLM to summarize which facts are most important, keeping the source citations intact.<\/p>\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*cYUMYC4PIsyTI8r-EkSgNw.png\" alt=\"\" style=\"\"\/><br \/>This is a kind of prompt chaining process, and I built it to mimic LlamaIndex\u2019s citation engine.<\/p>\n<p class=\"wp-block-paragraph\">The first time the endpoint is called for a keyword, it can take up to half a minute to complete. But since the system caches the result, any repeat request takes just a few milliseconds.<\/p>\n<p class=\"wp-block-paragraph\">As long as the models are small enough, the cost of running this on a few hundred keywords per day is minimal. Later, we can have the system run several keywords in parallel.<\/p>\n<p class=\"wp-block-paragraph\">You can probably imagine now that we can build a system to fetch these keywords and facts to build different reports with LLMs.<\/p>\n<p>When to work with small vs larger models<\/p>\n<p class=\"wp-block-paragraph\">Before moving on, let\u2019s just mention that choosing the right model size matters.<\/p>\n<p class=\"wp-block-paragraph\">I think this is on everyone\u2019s mind right now.<\/p>\n<p class=\"wp-block-paragraph\">There are quite advanced models you can use for any workflow, but as we start to apply more and more LLMs to these applications, the number of calls per run adds up quickly and this can get expensive.<\/p>\n<p class=\"wp-block-paragraph\">So, when you can, use smaller models.<\/p>\n<p class=\"wp-block-paragraph\">You saw that I used smaller models to cite and group sources in chunks. Other tasks that are great for small models include routing and parsing natural language into structured data.<\/p>\n<p class=\"wp-block-paragraph\">If you find that the model is faltering, you can break the task down into smaller problems and use prompt chaining, first do one thing, then use that result to do the next, and so on.<\/p>\n<p class=\"wp-block-paragraph\">You still want to use larger LLMs when you need to find patterns in very large texts, or when you\u2019re communicating with humans.<\/p>\n<p class=\"wp-block-paragraph\">In this workflow, the cost is minimal because the data is cached, we use smaller models for most tasks, and the only unique large LLM calls are the final ones.<\/p>\n<p>How this agent works<\/p>\n<p class=\"wp-block-paragraph\">Let\u2019s go through how the agent works under the hood. I built the agent to run inside Discord, but that\u2019s not the focus here. We\u2019ll focus on the agent architecture.<\/p>\n<p class=\"wp-block-paragraph\">I split the process into two parts: one setup, and one news. The first process asks the user to set up their profile.<\/p>\n<p><img decoding=\"async\" style=\"\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*SISHqaWHDMHY-gZEluWkEQ.png\" alt=\"\"\/><br \/>Since I already know how to work with the data source, I\u2019ve built a fairly extensive system prompt that helps the LLM translate those inputs into something we can fetch data with later.<\/p>\n<p>PROMPT_PROFILE_NOTES = &#8220;&#8221;&#8221;<br \/>\nYou are tasked with defining a user persona based on the user&#8217;s profile summary.<br \/>\nYour job is to:<br \/>\n1. Pick a short personality description for the user.<br \/>\n2. Select the most relevant categories (major and minor).<br \/>\n3. Choose keywords the user should track, strictly following the rules below (max 6).<br \/>\n4. Decide on time period (based only on what the user asks for).<br \/>\n5. Decide whether the user prefers concise or detailed summaries.<br \/>\nStep 1. Personality<br \/>\n&#8211; Write a short description of how we should think about the user.<br \/>\n&#8211; Examples:<br \/>\n&#8211; CMO for non-technical product \u2192 &#8220;non-technical, skip jargon, focus on product keywords.&#8221;<br \/>\n&#8211; CEO \u2192 &#8220;only include highly relevant keywords, no technical overload, straight to the point.&#8221;<br \/>\n&#8211; Developer \u2192 &#8220;technical, interested in detailed developer conversation and technical terms.&#8221;<br \/>\n[&#8230;]<br \/>\n&#8220;&#8221;&#8221;<\/p>\n<p class=\"wp-block-paragraph\">I\u2019ve also defined a schema for the outputs I need:<\/p>\n<p>class ProfileNotesResponse(BaseModel):<br \/>\n personality: str<br \/>\n major_categories: List[str]<br \/>\n minor_categories: List[str]<br \/>\n keywords: List[str]<br \/>\n time_period: str<br \/>\n concise_summaries: bool<\/p>\n<p class=\"wp-block-paragraph\">Without having domain knowledge of the API and how it works, it\u2019s unlikely that an LLM would figure out how to do this on its own.<\/p>\n<p class=\"wp-block-paragraph\">You could try building a more extensive system where the LLM first tries to learn the API or the systems it is supposed to use, but that would make the workflow more unpredictable and costly.<\/p>\n<p class=\"wp-block-paragraph\">For tasks like this, I try to always use structured outputs in JSON format. That way we can validate the result, and if validation fails, we re-run it.<\/p>\n<p class=\"wp-block-paragraph\">This is the easiest way to work with LLMs in a system, especially when there\u2019s no human in the loop to check what the model returns.<\/p>\n<p class=\"wp-block-paragraph\">Once the LLM has translated the user profile into the properties we defined in the schema, we store the profile somewhere. I used MongoDB, but that\u2019s optional.<\/p>\n<p class=\"wp-block-paragraph\">Storing the personality isn\u2019t strictly required, but you do need to translate what the user says into a form that lets you generate data.<\/p>\n<p>Generating the reports<\/p>\n<p class=\"wp-block-paragraph\">Let\u2019s look at what happens in the second step when the user triggers the report.<\/p>\n<p class=\"wp-block-paragraph\">When the user hits the \/news command, with or without a time period set, we first fetch the user profile data we\u2019ve stored.<\/p>\n<p class=\"wp-block-paragraph\">This gives the system the context it needs to fetch relevant data, using both categories and keywords tied to the profile. The default time period is weekly.<\/p>\n<p class=\"wp-block-paragraph\">From this, we get a list of top and trending keywords for the selected time period that may be interesting to the user.<\/p>\n<p><img decoding=\"async\" style=\"\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*ffL_Ce6h_VO4S1nlT4LaOQ.png\" alt=\"Example of trending keywords that can come up from the system in two different categories | Image by author&#10;\"\/><br \/>Without this data source, building something like this would have been difficult. The data needs to be prepared in advance for the LLM to work with it properly.<\/p>\n<p class=\"wp-block-paragraph\">After fetching keywords, it could make sense to add an LLM step that filters out keywords irrelevant to the user. I didn\u2019t do that here.<\/p>\n<p class=\"wp-block-paragraph\">The more unnecessary information an LLM is handed, the harder it becomes for it to focus on what really matters. Your job is to make sure that whatever you feed it is relevant to the user\u2019s actual question.<\/p>\n<p class=\"wp-block-paragraph\">Next, we use the endpoint prepared earlier, which contains cached \u201cfacts\u201d for each keyword. This gives us already vetted and sorted information for each one.<\/p>\n<p class=\"wp-block-paragraph\">We run keyword calls in parallel to speed things up, but the first person to request a new keyword still has to wait a bit longer.<\/p>\n<p class=\"wp-block-paragraph\">Once the results are in, we combine the data, remove duplicates, and parse the citations so each fact links back to a specific source via a keyword number.<\/p>\n<p class=\"wp-block-paragraph\">We then run the data through a prompt-chaining process. The first LLM finds 5 to 7 themes and ranks them by relevance, based on the user profile. It also pulls out the key points.<\/p>\n<p><img decoding=\"async\" style=\"\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*iEe8LrF9wZ-XT2QpVRiiHw.png\" alt=\"Short chain of prompting, breaking the task into smaller ones | Image by author\"\/><br \/>The second LLM pass uses both the themes and original data to generate two different summary lengths, along with a title.<\/p>\n<p class=\"wp-block-paragraph\">We can do this to make sure to reduce cognitive load on the model.<br \/>This last step to build the report takes the most time, since I chose to use a reasoning model like GPT-5.<\/p>\n<p class=\"wp-block-paragraph\">You could swap it for something faster, but I find advanced models are better at this last stuff.<\/p>\n<p class=\"wp-block-paragraph\">The full process takes a few minutes, depending on how much has already been cached that day.<\/p>\n<p class=\"wp-block-paragraph\">Check out the finished result below.<\/p>\n<p><img decoding=\"async\" style=\"\" src=\"https:\/\/www.newsbeep.com\/uk\/wp-content\/uploads\/2025\/09\/1*Ba8MIy046w9bH3_g34QjeQ.gif\" alt=\"How the tech scounting bot works in Discord | Image by author\"\/><br \/>If you want to look at the code and build this bot yourself, you can find it <a href=\"https:\/\/github.com\/ilsilfverskiold\/ai-personalized-tech-reports-discord\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">here<\/a>. If you just want to generate a report, you can join this <a href=\"https:\/\/discord.gg\/v6BV49DCpp\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">channel<\/a>.<\/p>\n<p class=\"wp-block-paragraph\">I have some plans to improve it, but I\u2019m happy to hear feedback if you find it useful.<\/p>\n<p class=\"wp-block-paragraph\">And if you want a challenge, you can rebuild it into something else, like a content generator.<\/p>\n<p>Notes on building agents<\/p>\n<p class=\"wp-block-paragraph\">Every agent you build will be different, so this is by no means a blueprint for building with LLMs. But you can see the level of software engineering this demands.<\/p>\n<p class=\"wp-block-paragraph\">LLMs, at least for now, do not remove the need for good software and data engineers.<\/p>\n<p class=\"wp-block-paragraph\">For this workflow, I\u2019m mostly using LLMs to translate natural language into JSON and then move that through the system programmatically. It\u2019s the easiest way to control the agent process, but also not what people usually imagine when they think of AI applications.<\/p>\n<p class=\"wp-block-paragraph\">There are situations where using a more free-moving agent is ideal, especially when there is a human in the loop.<\/p>\n<p>Nevertheless, hopefully you learned something, or got inspiration to build something on your own.<\/p>\n<p class=\"wp-block-paragraph\">If you want to follow my writing, follow me here, my <a href=\"https:\/\/www.ilsilfverskiold.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">website<\/a>, <a href=\"https:\/\/howtouseai.substack.com\/\" data-type=\"link\" data-id=\"https:\/\/howtouseai.substack.com\/\" rel=\"nofollow noopener\" target=\"_blank\">Substack<\/a>, or <a href=\"https:\/\/www.linkedin.com\/in\/ida-silfverskiold\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">LinkedIn<\/a>.<\/p>\n<p class=\"wp-block-paragraph\">\u2764<\/p>\n","protected":false},"excerpt":{"rendered":"ChatGPT something like: \u201cPlease scout all of tech for me and summarize trends and patterns based on what&hellip;\n","protected":false},"author":2,"featured_media":136895,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[554,6175,733,4308,7470,25801,27604,86,56,54,55],"class_list":{"0":"post-136894","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-artificial-intelligence","8":"tag-ai","9":"tag-ai-agent","10":"tag-artificial-intelligence","11":"tag-artificialintelligence","12":"tag-editors-pick","13":"tag-llm","14":"tag-prompt-engineering","15":"tag-technology","16":"tag-uk","17":"tag-united-kingdom","18":"tag-unitedkingdom"},"_links":{"self":[{"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/posts\/136894","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/comments?post=136894"}],"version-history":[{"count":0,"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/posts\/136894\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/media\/136895"}],"wp:attachment":[{"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/media?parent=136894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/categories?post=136894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.newsbeep.com\/uk\/wp-json\/wp\/v2\/tags?post=136894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}