WEBVTT

NOTE Sentence-level transcript of https://www.youtube.com/watch?v=XsvUhpnHepE

NOTE One cue per sentence. Cue ids are the line anchors on /transcripts/XsvUhpnHepE.html. A cue ends where the next begins, or 2 s after its last word.

s1
00:00:01.309 --> 00:00:03.309
[music]

s2
00:00:13.679 --> 00:00:16.000
What a beautiful voice.

s3
00:00:16.000 --> 00:00:18.400
All right, thank you for coming.

s4
00:00:18.400 --> 00:00:27.279
Um, today I'm going to talk a lot about about missing layer of Aentic AI and explain a little bit about how web scraping infrastructure can actually help you.

s5
00:00:27.279 --> 00:00:32.719
But first, let me talk uh a little bit about my friend's idea.

s6
00:00:32.719 --> 00:00:34.399
So, my friend had this idea.

s7
00:00:34.399 --> 00:00:48.079
Uh he built this AI chatbot that, you know, chatted with people about their style and it was supposed to help them pick out new items uh as you know, some sort of a personal shopper.

s8
00:00:48.079 --> 00:01:00.160
And once those items were picked out, you know, this uh this this this chatbot would uh produce prompts that a shopping agent would then take and attempt to find them online

s9
00:01:00.160 --> 00:01:04.159
and purchase them for uh you know for for for the customers.

s10
00:01:04.159 --> 00:01:15.520
Um this idea I know is not new and uh it could be applicable to many scenarios but my friend was kind of you know uh he was u he was good at building agents uh but u he ran into

s11
00:01:15.520 --> 00:01:27.200
different problems and asked me for advice and when he ran it he he would usually you know instead of you know product pages or whatever he would get things like that

s12
00:01:27.200 --> 00:01:35.520
it's uh you know he would get captured you know and uh you know of course you So he was uh he was doing it very very quickly.

s13
00:01:35.520 --> 00:01:43.360
So he wipe coded the whole thing while having a you know a thought about you know infrastructure and underlying layers and how it should work.

s14
00:01:43.360 --> 00:01:45.360
I didn't at all.

s15
00:01:45.360 --> 00:01:55.600
Uh he was using a browser automation framework for everything and it was slow, expensive and unreliable.

s16
00:01:55.600 --> 00:02:03.360
So at the end he made a product that uh uh that does not work and is expensive to run.

s17
00:02:03.360 --> 00:02:12.239
So he asked me for help and you know I was a little bit reluctant at first because uh you know I don't like giving out professional advice you know for free

s18
00:02:12.239 --> 00:02:18.879
but uh I took a look at it and uh you know I got a little curious I have to be honest.

s19
00:02:18.879 --> 00:02:22.560
I noticed that he was missing something.

s20
00:02:22.640 --> 00:02:32.239
Um he was missing a layer an infrastructural layer that would allow this agent to operate freely on the open web.

s21
00:02:32.239 --> 00:02:33.360
My name is Gedrus.

s22
00:02:33.360 --> 00:02:49.360
I I work for Oxyabs uh where in the past 10 years we've helped you know companies that trained large language models uh get their data and now we use this infrastructure to help AI agents

s23
00:02:49.360 --> 00:02:56.000
to access uh web on scale and at low cost.

s24
00:02:56.400 --> 00:03:04.319
And uh before we go into this agent and see how we can build it, I wanted to talk a little bit about the scraping industry and how we operate.

s25
00:03:04.319 --> 00:03:12.560
And uh the principles that we operate on can be summed up by one uh sentence.

s26
00:03:12.560 --> 00:03:15.280
You know, cost matters.

s27
00:03:15.280 --> 00:03:23.280
And the first principle is use a browser when you absolutely have to validate content.

s28
00:03:23.280 --> 00:03:28.319
HTTP response 200 does not mean that we are good to go.

s29
00:03:28.319 --> 00:03:30.720
Lighter content is preferred.

s30
00:03:30.720 --> 00:03:40.000
Websites are full of JavaScript, CSS, HTML, and there's a lot of bites that do not deliver any value whatsoever.

s31
00:03:40.000 --> 00:03:49.360
And today I will demonstrate how these principles are also applicable when building agents that interact with the web.

s32
00:03:49.360 --> 00:03:51.760
So coming back to my friend's agent, right?

s33
00:03:51.760 --> 00:03:58.720
Let's uh let's take a look and see how uh we could do a better job and uh making this agent run more reliably.

s34
00:03:58.720 --> 00:04:01.840
So here's how my friends set it all up, you know?

s35
00:04:01.840 --> 00:04:03.840
So four different stages.

s36
00:04:03.840 --> 00:04:11.120
Discovery, the agent was supposed to find products pages on websites where these items can be bought.

s37
00:04:11.120 --> 00:04:12.879
Then a decision stage, right?

s38
00:04:12.879 --> 00:04:21.040
and uh where an agent can decide uh what products to buy based on you know uh the the content of these pages.

s39
00:04:21.040 --> 00:04:31.759
So the agent has to visit them verify that the the stock is there the price is right the the description fits uh you know the prompt and once that

s40
00:04:31.759 --> 00:04:40.479
decision is made user is given with a choice you know whether to go ahead with the purchase or you know reject it altogether.

s41
00:04:40.479 --> 00:04:53.120
The problem was that sometimes and of course we go to execution right away then execution just making the purchase but the problem was that sometimes it worked and sometimes it did not

s42
00:04:53.120 --> 00:04:55.759
that was a little problematic.

s43
00:04:55.759 --> 00:05:08.560
So let's dissect it step by step and see how we could build this differently while improving performance and reducing the cost dramatically by using the same principles from the scraping industry.

s44
00:05:09.600 --> 00:05:12.800
So the first stage discovery.

s45
00:05:12.800 --> 00:05:23.520
So my friend uh you know he chose to go with a predefined list of websites major retailers uh and query their search pages in order to find these products.

s46
00:05:23.520 --> 00:05:26.320
He used the browser automation tool for that.

s47
00:05:26.320 --> 00:05:29.360
It kind of worked but you know it did have challenges.

s48
00:05:29.360 --> 00:05:34.000
So their browser automation tool lacked what we call stealth.

s49
00:05:34.000 --> 00:05:38.080
So they could so they would get captures and sometimes fail access to access the sites.

s50
00:05:38.080 --> 00:05:38.800
all together.

s51
00:05:38.800 --> 00:05:41.199
This would break down the flow.

s52
00:05:41.199 --> 00:05:46.400
So a retry mechanism would have to be put in place making the whole process very long.

s53
00:05:46.400 --> 00:06:01.360
Uh you know costly um and sometimes the size would not be uh accessed at all and also you know as a result also became very difficult to predict the final cost per transaction.

s54
00:06:01.360 --> 00:06:05.440
The list of websites that my friend was checking was also deterministic.

s55
00:06:05.440 --> 00:06:11.919
So selection of items would only be limited to the few choices he put in.

s56
00:06:12.080 --> 00:06:18.560
Websites themselves were heavy on JavaScript, making the whole process very slow and costly.

s57
00:06:18.800 --> 00:06:32.240
And finally, even if it worked, items ended up being unavailable at checkout because in the discovery phase, the he was not able to use energy location capabilities and a lot of e-commerce

s58
00:06:32.240 --> 00:06:42.800
websites are uh you know uh they take your users location into account when displaying stock options sizes and soever.

s59
00:06:45.199 --> 00:06:48.319
So now we solve these problems at Oxabs every day.

s60
00:06:48.319 --> 00:06:58.000
So when scraping you always want the results to appear on the first try and to not to use browser unless absolutely necessary.

s61
00:06:58.000 --> 00:07:04.639
However, for this specific discovery phase, you also want to use to allow your agent to search the web.

s62
00:07:04.639 --> 00:07:07.680
Doing so with a browser is very cumbersome.

s63
00:07:07.680 --> 00:07:14.720
That is why I chose to use a product that we built especially for agents fast search API.

s64
00:07:14.720 --> 00:07:19.759
It returns a compact JSON which is less than 2,000 tokens per response.

s65
00:07:19.759 --> 00:07:24.560
Has fast response times less than 700 milliseconds on average.

s66
00:07:24.560 --> 00:07:30.160
And it's uh has a a high success rate at a predictable low price.

s67
00:07:30.160 --> 00:07:42.560
And most importantly, it gives your agent access to the mo to you know to many popular search engines that all of these websites have been instant indexed already a long time ago.

s68
00:07:42.560 --> 00:07:55.360
So in the discovery phase instead of predefined list and the browser we give agent a tool to search the web fast search API agent formulates fan out queries and selects the relevant URLs from search results.

s69
00:07:55.360 --> 00:08:04.960
Since the responses are quite small and there's no need for complicated models we can have the agent run quite quickly in this stage.

s70
00:08:05.919 --> 00:08:07.199
Um, yeah.

s71
00:08:07.199 --> 00:08:13.120
So, so now the agent has searched the web and selected some relevant URLs.

s72
00:08:13.120 --> 00:08:25.280
It is time for those for for the agent to visit those pages to see what they're all about in order to confirm price, stock level, description, and product details and so on.

s73
00:08:25.280 --> 00:08:28.240
With this, we can go to in the decision phase.

s74
00:08:28.240 --> 00:08:32.240
This is where agent selects the items we will purchase.

s75
00:08:32.240 --> 00:08:34.560
For this, my friend also used the browser.

s76
00:08:34.560 --> 00:08:42.399
He ran many browsers on parallel so it could uh you know so the whole process could happen faster and that is not a bad thing.

s77
00:08:42.399 --> 00:08:58.800
He managed to get some results however many of the results would end up like this and the result the agent would be left with very few choices with the majority of popular retailers

s78
00:08:58.800 --> 00:09:00.880
being left out.

s79
00:09:00.880 --> 00:09:03.200
It's a good thing he did well with observability.

s80
00:09:03.200 --> 00:09:05.600
So he actually noticed when it happened.

s81
00:09:05.600 --> 00:09:13.440
But what we see when working with these types of customers is that they often fail to detect the failure.

s82
00:09:13.440 --> 00:09:21.120
They end up checking only the content size and HTTP response code and then feeding this large HTML to an LLM.

s83
00:09:21.120 --> 00:09:27.200
Now an a large language model of course can distinguish between valid esop content and a capture.

s84
00:09:27.200 --> 00:09:30.720
But we need to spend tokens in order to do that.

s85
00:09:30.720 --> 00:09:44.399
And when we attempt to open 10 websites, but only three return valid content but feed all of the 10 to the to the model, it is a problem.

s86
00:09:44.399 --> 00:09:52.240
It means that we waste 70% of the tokens and that is a little crazy in my in my opinion.

s87
00:09:53.600 --> 00:09:55.440
So I noticed this problem as well.

s88
00:09:55.440 --> 00:10:00.959
Uh my initial hunch was compression was to compress the output.

s89
00:10:00.959 --> 00:10:04.240
But then I thought wait the problem is not the compression.

s90
00:10:04.240 --> 00:10:07.440
The problem is that the content is not valid.

s91
00:10:07.440 --> 00:10:12.880
We need to make sure that the content is valid before even attempting any compression.

s92
00:10:12.880 --> 00:10:18.959
This will lead to more options for the agent to choose from and fewer wasted tokens.

s93
00:10:18.959 --> 00:10:21.920
And then I remember rule number one of scraping.

s94
00:10:21.920 --> 00:10:26.160
Use the browser when you absolutely need it.

s95
00:10:26.160 --> 00:10:29.279
Otherwise look for other solutions.

s96
00:10:29.279 --> 00:10:39.040
So I I tried to rebuild the stage without a browser and I uh only by using ox web scraper API and this gave me many benefits.

s97
00:10:39.040 --> 00:10:43.200
Uh but firstly only valid content was returned.

s98
00:10:43.200 --> 00:10:48.480
In case of captures or other blocks the request would fail with an explicit error message.

s99
00:10:48.480 --> 00:10:51.920
So I know not to include it when sending to a large language model.

s100
00:10:51.920 --> 00:10:56.560
But the success rates are quite high and even for protected websites.

s101
00:10:56.560 --> 00:11:00.320
So that wasn't that much of you know much of a problem.

s102
00:11:00.320 --> 00:11:04.959
So no browser was needed and uh everything is a lightweight rest API.

s103
00:11:04.959 --> 00:11:11.120
I can run hundreds of requests in parallel and receive content at the same time.

s104
00:11:11.519 --> 00:11:13.760
Also the API supports markdown.

s105
00:11:13.760 --> 00:11:18.160
So no need to submit raw HTML uh to LLMs.

s106
00:11:18.160 --> 00:11:25.680
If a website is dynamic, it runs a full browser under the hood to render the content correctly.

s107
00:11:25.839 --> 00:11:28.399
And finally, it supports geoloccation options.

s108
00:11:28.399 --> 00:11:33.920
So I can localize my results and get relevant content.

s109
00:11:33.920 --> 00:11:39.200
The best part, customers only pay for successful results.

s110
00:11:39.200 --> 00:11:45.680
So actually, yeah, that's uh that's what's uh that's what that's what the best thing about it.

s111
00:11:45.680 --> 00:11:47.040
No cure or no pay.

s112
00:11:47.040 --> 00:11:52.399
If if the scraper fails, there's no cost and it fails loudly.

s113
00:11:54.880 --> 00:11:58.880
So now we have all of the information to make a decision.

s114
00:11:58.880 --> 00:12:03.279
We present a decision to the user and the user makes the final call.

s115
00:12:03.279 --> 00:12:09.920
Once it's affirmative, we move to the last stage of the workflow, the purchase.

s116
00:12:09.920 --> 00:12:13.200
So I remember what I said a couple of times about browsers.

s117
00:12:13.200 --> 00:12:15.600
This time, but this time is different.

s118
00:12:15.600 --> 00:12:20.320
you this time you absolutely need to use a browser.

s119
00:12:20.320 --> 00:12:24.800
We need to process inputs and the content is highly dynamic.

s120
00:12:24.800 --> 00:12:29.519
Now this time my implementation, my friend's implementation does not differ much.

s121
00:12:29.519 --> 00:12:36.000
We both use playright MCP with a browser and a large language model.

s122
00:12:37.680 --> 00:12:45.680
The main problem my friend faced however just like in in the previous stages while using browser was access.

s123
00:12:45.680 --> 00:12:55.200
Just like in the beginning as he was using the browser he was getting captured into oblivion making it impossible to automate the flow.

s124
00:12:55.920 --> 00:12:58.399
Well the fix was quite easy.

s125
00:12:58.399 --> 00:13:04.880
I just connected Oxab's headless browser since it supports playright MCP is just a drop in replacement.

s126
00:13:04.880 --> 00:13:18.320
With this replacement, I hardened this agent with years of scraping experience and got proper stealth done at the browser source code level, a residential proxy attached to it out of the box,

s127
00:13:18.320 --> 00:13:24.160
and most importantly in this in this case, a geoloccation capability.

s128
00:13:24.160 --> 00:13:31.040
So my results are localized the same way as in the verification stage.

s129
00:13:31.040 --> 00:13:45.200
So if we run it, we actually have a a a a browser that that access the content and can actually automate the flow by, you know, selecting the right size from the prompt,

s130
00:13:45.200 --> 00:13:49.680
add it to cart and complete the purchase.

s131
00:13:49.680 --> 00:14:00.639
And boom, we have an agent that commands a powerful infrastructure hardened by years of web scraping experience.

s132
00:14:00.800 --> 00:14:08.560
Not only does it open the up the web, but also saves the time on implementation and token cost.

s133
00:14:08.560 --> 00:14:20.880
And if I can leave you with a few lessons we learned today was that you know when building agents use the same principles from the scraping industry.

s134
00:14:20.880 --> 00:14:24.720
Use the browser when you absolutely need to.

s135
00:14:24.720 --> 00:14:38.800
You have to validate content before feeding it to the large language models and most importantly fill the missing layer with the proper infrastructure so you can focus on building stuff.

s136
00:14:38.800 --> 00:14:42.079
But remember cost matters.

s137
00:14:42.079 --> 00:14:44.720
Thank you very much.

s138
00:14:44.915 --> 00:14:46.915
[applause]
