Skip to main content

hamilton-llm

LLM and AI workflow patterns for Hamilton including RAG pipelines, embeddings, vector databases, and prompt engineering. Use for building AI applications with Hamilton.

Informações da origem

Repositório
apache/hamilton
Última atividade na origem
25 de setembro de 2026 às 21:50
Idioma detectado do SKILL.md
inglês
Estrelas
2.610
Forks
221

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
hamilton-llm
description
LLM and AI workflow patterns for Hamilton including RAG pipelines, embeddings, vector databases, and prompt engineering. Use for building AI applications with Hamilton.
allowed-tools
Read, Grep, Glob, Bash(python:*), Bash(pytest:*)
user-invocable
true
disable-model-invocation
false
<!-- SPDX-License-Identifier: Apache-2.0 --> # Hamilton for LLM & AI Workflows This skill covers patterns for building LLM applications, RAG pipelines, and AI workflows with Apache Hamilton. ## Why Hamilton for LLM Workflows? **Key Benefits:** - **Modular prompts**: Each prompt component is a testable function - **Dependency tracking**: Clear lineage from data → embeddings → retrieval → generation - **Async parallelization**: Multiple LLM calls happen concurrently - **Caching**: Avoid redundant expensive API calls - **Observability**: Track LLM calls, costs, and performance - **Testing**: Unit test prompts, retrieval, and generation separately ## RAG Pipeline Pattern **Complete RAG Implementation:** ```python """RAG pipeline with Hamilton.""" import openai from typing import List, Dict import aiohttp # 1. Document Loading & Processing async def document_text(document_url: str) -> str: """Fetch document from URL.""" async with aiohttp.ClientSession() as session: async with session.get(document_url) as resp: return await resp.text() def document_chunks(document_text: str, chunk_size: int = 1000, overlap: int = 100) -> List[str]: """Split document into overlapping chunks.""" chunks = [] start = 0 while start < len(document_text): end = start + chunk_size chunks.append(document_text[start:end]) start = end - overlap return chunks # 2. Embedding Generation async def embeddings( document_chunks: List[str], embedding_model: str = "text-embedding-3-small" ) -> List[List[float]]: """Generate embeddings for chunks.""" client = openai.AsyncOpenAI() response = await client.embeddings.create(input=document_chunks, model=embedding_model) return [item.embedding for item in response.data] # 3. Vector Store async def vector_store_ids(embeddings: List[List[float]], document_chunks: List[str]) -> List[str]: """Store embeddings in vector database.""" import pinecone index = pinecone.Index("documents") vectors = [ (f"chunk_{i}", emb, {"text": chunk}) for i, (emb, chunk) in enumerate(zip(embeddings, document_chunks)) ] await index.upsert(vectors) return [v[0] for v in vectors] # 4. Query & Retrieval async def query_embedding( query: str, embedding_model: str = "text-embedding-3-small" ) -> List[float]: """Generate embedding for query.""" client = openai.AsyncOpenAI() response = await client.embeddings.create(input=[query], model=embedding_model) return response.data[0].embedding async def retrieved_chunks(query_embedding: List[float], top_k: int = 5) -> List[str]: """Retrieve relevant chunks from vector store.""" import pinecone index = pinecone.Index("documents") results = await index.query(vector=query_embedding, top_k=top_k, include_metadata=True) return [match["metadata"]["text"] for match in results["matches"]] # 5. Prompt Construction def rag_prompt(query: str, retrieved_chunks: List[str]) -> str: """Construct RAG prompt with context.""" context = "\n\n".join(retrieved_chunks) return f"""Answer the question based on the context below. Context: {context} Question: {query} Answer:""" # 6. LLM Generation async def llm_response(rag_prompt: str, model: str = "gpt-4") -> str: """Generate response using LLM.""" client = openai.AsyncOpenAI() response = await client.chat.completions.create( model=model, messages=[{"role": "user", "content": rag_prompt}] ) return response.choices[0].message.content # Execute the RAG pipeline from hamilton import async_driver import rag_pipeline dr = await async_driver.Builder().with_modules(rag_pipeline).build() # Indexing phase await dr.execute(["vector_store_ids"], inputs={"document_url": "https://example.com/doc.pdf"}) # Query phase result = await dr.execute(["llm_response"], inputs={"query": "What is the main topic?"}) ``` ## Multi-Provider Pattern **Support multiple LLM providers:** ```python """Multi-provider LLM configuration.""" from hamilton.function_modifiers import config import openai import anthropic @config.when(provider="openai") def llm_client__openai() -> openai.AsyncOpenAI: """OpenAI client.""" return openai.AsyncOpenAI() @config.when(provider="anthropic") def llm_client__anthropic() -> anthropic.AsyncAnthropic: """Anthropic client.""" return anthropic.AsyncAnthropic() @config.when(provider="openai") async def llm_response__openai(llm_client: openai.AsyncOpenAI, prompt: str) -> str: """Generate with OpenAI.""" response = await llm_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}] ) return response.choices[0].message.content @config.when(provider="anthropic") async def llm_response__anthropic(llm_client: anthropic.AsyncAnthropic, prompt: str) -> str: """Generate with Anthropic.""" response = await llm_client.messages.create( model="claude-sonnet-4-6", max_tokens=1024, messages=[{"role": "user", "content": prompt}] ) return response.content[0].text # Switch providers via config dr = ( await async_driver.Builder() .with_config({"provider": "anthropic"}) .with_modules(llm_module) .build() ) ``` ## Parallel LLM Calls **Multiple analyses in parallel:** ```python """Run multiple LLM analyses concurrently.""" import openai async def llm_client() -> openai.AsyncOpenAI: """Shared LLM client.""" return openai.AsyncOpenAI() def summarization_prompt(document: str) -> str: """Prompt for summarization.""" return f"Summarize this document:\n\n{document}" def keyword_prompt(document: str) -> str: """Prompt for keyword extraction.""" return f"Extract 5 key topics from this document:\n\n{document}" def sentiment_prompt(document: str) -> str: """Prompt for sentiment analysis.""" return f"Analyze the sentiment of this document:\n\n{document}" # These three run in parallel! async def summary(llm_client: openai.AsyncOpenAI, summarization_prompt: str) -> str: """Generate summary.""" response = await llm_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": summarization_prompt}] ) return response.choices[0].message.content async def keywords(llm_client: openai.AsyncOpenAI, keyword_prompt: str) -> List[str]: """Extract keywords.""" response = await llm_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": keyword_prompt}] ) return response.choices[0].message.content.split("\n") async def sentiment(llm_client: openai.AsyncOpenAI, sentiment_prompt: str) -> str: """Analyze sentiment.""" response = await llm_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": sentiment_prompt}] ) return response.choices[0].message.content def document_analysis(summary: str, keywords: List[str], sentiment: str) -> dict: """Combine all analyses.""" return {"summary": summary, "keywords": keywords, "sentiment": sentiment} # Result: 3 LLM calls happen concurrently, ~3x faster! ``` ## Caching LLM Calls **Save API costs with caching:** ```python """Cache expensive LLM calls.""" from hamilton.function_modifiers import cache import openai @cache(behavior="default") # Cache LLM responses async def document_summary(document_text: str, llm_client: openai.AsyncOpenAI) -> str: """Generate summary (cached). First call: Makes API request, caches result Subsequent calls: Retrieves from cache (free & instant!) """ response = await llm_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": f"Summarize this document:\n\n{document_text}"}], ) return response.choices[0].message.content # First run: Costs $0.01 # Second run: $0.00, instant retrieval # Savings on 1000 documents: $10! ``` ## Prompt Engineering Patterns **Modular prompts:** ```python """Build complex prompts from components.""" def system_message(task_type: str) -> str: """System message based on task.""" templates = { "summarize": "You are an expert at creating concise summaries.", "extract": "You are an expert at extracting structured information.", "analyze": "You are an expert at analyzing content and providing insights.", } return templates[task_type] def user_context(document: str, max_length: int = 2000) -> str: """Truncate document if needed.""" return document[:max_length] if len(document) > max_length else document def instruction(task_type: str) -> str: """Task-specific instruction.""" instructions = { "summarize": "Provide a 3-sentence summary.", "extract": "Extract key entities and dates.", "analyze": "Analyze the main themes and sentiment.", } return instructions[task_type] def messages(system_message: str, user_context: str, instruction: str) -> List[dict]: """Combine into message list.""" return [ {"role": "system", "content": system_message}, {"role": "user", "content": f"{user_context}\n\n{instruction}"}, ] async def llm_result(llm_client: openai.AsyncOpenAI, messages: List[dict]) -> str: """Execute LLM call.""" response = await llm_client.chat.completions.create(model="gpt-4", messages=messages) return response.choices[0].message.content ``` ## Structured Output with Pydantic **Parse LLM output into structured data:** ```python """Structured extraction with validation.""" from pydantic import BaseModel, Field from typing import List import openai class ExtractedEntity(BaseModel): """Structured entity.""" name: str = Field(description="Entity name") type: str = Field(description="Entity type (person, org, location)") relevance: float = Field(description="Relevance score 0-1", ge=0, le=1) class ExtractionResult(BaseModel): """Complete extraction result.""" entities: List[ExtractedEntity] summary: str async def structured_extraction(document: str, llm_client: openai.AsyncOpenAI) -> ExtractionResult: """Extract structured data from document.""" response = await llm_client.beta.chat.completions.parse( model="gpt-4o-2024-08-06", messages=[{"role": "user", "content": f"Extract entities from:\n\n{document}"}], response_format=ExtractionResult, ) return response.choices[0].message.parsed ``` ## Agent Patterns **Multi-step agent with Hamilton:** ```python """Agent with tool use.""" from typing import Literal def agent_prompt(query: str, available_tools: List[str]) -> str: """Create agent prompt with tools.""" tools_desc = "\n".join(f"- {tool}" for tool in available_tools) return f"""You have access to these tools: {tools_desc} User query: {query} What tool should be used? Respond with just the tool name.""" async def tool_selection( llm_client: openai.AsyncOpenAI, agent_prompt: str
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub