<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://blog.jztan.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.jztan.com/" rel="alternate" type="text/html" /><updated>2026-07-12T02:27:23+00:00</updated><id>https://blog.jztan.com/feed.xml</id><title type="html">Kevin Tan</title><subtitle>Thoughts on cloud architecture, AWS, and engineering leadership. By Kevin Tan, Cloud Solutions Architect &amp; Engineering Leader.</subtitle><author><name>Kevin Tan</name></author><entry><title type="html">How to Evaluate LLM Agents: 5 Patterns That Catch Failures</title><link href="https://blog.jztan.com/how-to-evaluate-llm-agents/" rel="alternate" type="text/html" title="How to Evaluate LLM Agents: 5 Patterns That Catch Failures" /><published>2026-07-11T21:00:00+00:00</published><updated>2026-07-11T21:00:00+00:00</updated><id>https://blog.jztan.com/how-to-evaluate-llm-agents</id><author><name>Kevin Tan</name></author><category term="ai-agents" /><category term="llm" /><category term="observability" /><category term="blueclaw" /><summary type="html"><![CDATA[Most LLM agent eval shortcuts break on honesty-trained models. Five assertion patterns that survived production, when to use each, and how to derive your own.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/agent-eval-refusal.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/agent-eval-refusal.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">RAG for AI Agents: 6 Decisions That Make or Break Retrieval</title><link href="https://blog.jztan.com/rag-for-ai-agents-decision-guide/" rel="alternate" type="text/html" title="RAG for AI Agents: 6 Decisions That Make or Break Retrieval" /><published>2026-07-10T12:30:00+00:00</published><updated>2026-07-10T12:30:00+00:00</updated><id>https://blog.jztan.com/rag-for-ai-agents-decision-guide</id><author><name>Kevin Tan</name></author><category term="rag" /><category term="ai-agents" /><category term="llm" /><summary type="html"><![CDATA[Six decisions determine RAG quality for AI agents: search mode, fusion vs routing, chunk granularity, and more. Benchmark-backed defaults for each one.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/rag-for-ai-agents-decision-guide.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/rag-for-ai-agents-decision-guide.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How One Search Change Eliminated an Entire Agent Step</title><link href="https://blog.jztan.com/how-paragraph-excerpts-changed-agent-behavior/" rel="alternate" type="text/html" title="How One Search Change Eliminated an Entire Agent Step" /><published>2026-07-04T21:00:00+00:00</published><updated>2026-07-04T21:00:00+00:00</updated><id>https://blog.jztan.com/how-paragraph-excerpts-changed-agent-behavior</id><author><name>Kevin Tan</name></author><category term="mcp" /><category term="ai-agents" /><category term="python" /><category term="llm" /><summary type="html"><![CDATA[Switching pdf_search from fixed-width snippets to structural paragraph excerpts changed the dominant agent workflow from search-then-read to search-then-done.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/paragraph-excerpts-hero.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/paragraph-excerpts-hero.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to Evaluate an MCP Server With an LLM: 17 Bugs Found and Fixed</title><link href="https://blog.jztan.com/evaluate-mcp-server-with-llm/" rel="alternate" type="text/html" title="How to Evaluate an MCP Server With an LLM: 17 Bugs Found and Fixed" /><published>2026-06-27T21:00:00+00:00</published><updated>2026-06-27T21:00:00+00:00</updated><id>https://blog.jztan.com/evaluate-mcp-server-with-llm</id><author><name>Kevin Tan</name></author><category term="mcp" /><category term="ai-agents" /><category term="production-systems" /><category term="python" /><summary type="html"><![CDATA[I drove my Redmine MCP server like an agent would. Eight rounds of probing found 17 bugs that unit tests, schema tests, and MCP Inspector all missed.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/evaluate-mcp-server-with-llm.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/evaluate-mcp-server-with-llm.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How AI Agents Should Read PDFs: 5 Patterns That Survived Production</title><link href="https://blog.jztan.com/ai-agent-pdf-reading-patterns/" rel="alternate" type="text/html" title="How AI Agents Should Read PDFs: 5 Patterns That Survived Production" /><published>2026-06-24T21:00:00+00:00</published><updated>2026-06-24T21:00:00+00:00</updated><id>https://blog.jztan.com/ai-agent-pdf-reading-patterns</id><author><name>Kevin Tan</name></author><category term="ai-agents" /><category term="mcp" /><category term="rag" /><category term="llm" /><summary type="html"><![CDATA[Five patterns for AI agents reading PDFs at scale: scout-then-read, tool decomposition, persistent caching, reading-order recovery, and search-mode routing.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/ai-agent-pdf-patterns.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/ai-agent-pdf-patterns.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How I Built a Serverless Newsletter on AWS (SES + Lambda + DynamoDB)</title><link href="https://blog.jztan.com/how-i-built-a-serverless-newsletter-on-aws/" rel="alternate" type="text/html" title="How I Built a Serverless Newsletter on AWS (SES + Lambda + DynamoDB)" /><published>2026-06-20T21:00:00+00:00</published><updated>2026-06-20T21:00:00+00:00</updated><id>https://blog.jztan.com/how-i-built-a-serverless-newsletter-on-aws</id><author><name>Kevin Tan</name></author><category term="aws" /><category term="serverless" /><category term="python" /><summary type="html"><![CDATA[Most newsletters run on Mailchimp or Substack. Yours doesn't have to. Here's how I built a fully serverless newsletter on AWS for under $1/month with full data ownership.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/serverless-newsletter-aws.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/serverless-newsletter-aws.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">MCP Tool Sprawl: How I Cut 69 Tools to 43 With a Decorator</title><link href="https://blog.jztan.com/mcp-tool-sprawl-consolidation/" rel="alternate" type="text/html" title="MCP Tool Sprawl: How I Cut 69 Tools to 43 With a Decorator" /><published>2026-06-13T21:00:00+00:00</published><updated>2026-06-13T21:00:00+00:00</updated><id>https://blog.jztan.com/mcp-tool-sprawl-consolidation</id><author><name>Kevin Tan</name></author><category term="mcp" /><category term="python" /><category term="ai-agents" /><category term="production-systems" /><summary type="html"><![CDATA[When your MCP server hits 60+ tools, agents start picking the wrong ones. Here's how the Resource-Action Pattern cut mcp-redmine from 69 tools to 43 without losing a single capability.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/mcp-tool-sprawl-consolidation.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/mcp-tool-sprawl-consolidation.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to Deploy a Python MCP Server: Remote HTTP, Auth, and Docker</title><link href="https://blog.jztan.com/how-to-deploy-a-python-mcp-server/" rel="alternate" type="text/html" title="How to Deploy a Python MCP Server: Remote HTTP, Auth, and Docker" /><published>2026-06-09T12:30:00+00:00</published><updated>2026-06-23T11:51:02+00:00</updated><id>https://blog.jztan.com/how-to-deploy-a-python-mcp-server</id><author><name>Kevin Tan</name></author><category term="mcp" /><category term="security" /><category term="ai-agents" /><category term="llm" /><summary type="html"><![CDATA[Your MCP server runs locally over STDIO. Here's how to deploy it as a remote HTTP service with bearer-token auth and Docker, ready for any host.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/mcp-server-deploy-launch.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/mcp-server-deploy-launch.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Section-Level RAG: Why BM25 Beat Hybrid Search in My Benchmark</title><link href="https://blog.jztan.com/bm25-vs-hybrid-search-section-rag/" rel="alternate" type="text/html" title="Section-Level RAG: Why BM25 Beat Hybrid Search in My Benchmark" /><published>2026-06-06T21:00:00+00:00</published><updated>2026-06-06T21:00:00+00:00</updated><id>https://blog.jztan.com/bm25-vs-hybrid-search-section-rag</id><author><name>Kevin Tan</name></author><category term="mcp" /><category term="ai-agents" /><category term="rag" /><category term="llm" /><summary type="html"><![CDATA[Hybrid search lost to BM25 at section grain in my pdf-mcp benchmark: fusion caused a 33% lexical regression. Why granularity flips the verdict in RAG.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/section-rag-bm25-hero.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/section-rag-bm25-hero.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Section Chunking vs Page Chunking for AI Agents: ~6 Fewer Tool Calls Per PDF Query</title><link href="https://blog.jztan.com/section-chunking-vs-page-chunking-ai-agents/" rel="alternate" type="text/html" title="Section Chunking vs Page Chunking for AI Agents: ~6 Fewer Tool Calls Per PDF Query" /><published>2026-05-30T21:00:00+00:00</published><updated>2026-05-30T21:00:00+00:00</updated><id>https://blog.jztan.com/section-chunking-vs-page-chunking-ai-agents</id><author><name>Kevin Tan</name></author><category term="mcp" /><category term="ai-agents" /><category term="rag" /><category term="python" /><summary type="html"><![CDATA[Section-aware PDF search beats page-mode by 2 to 6 tool calls per query. Benchmarked on GPT-3, an LLM survey, and a GNN review against pdf-mcp v1.12.1.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.jztan.com/assets/images/section-chunking-hero.webp" /><media:content medium="image" url="https://blog.jztan.com/assets/images/section-chunking-hero.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>