# Technical Documentation: ed-donner/agents

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/ed-donner/agents)

### Overview (README.md)

## Master AI Agentic Engineering -  build autonomous AI Agents

### 6 week journey to code and deploy AI Agents with OpenAI Agents SDK, CrewAI, LangGraph, Google ADK, Pydantic AI and MCP



_If you're looking at this in Cursor, please right click on the filename in the Explorer on the left, and select "Open preview", to view the formatted version._

I couldn't be more excited to welcome you! This is the start of your 6 week adventure into the powerful, astonishing and often surreal world of Agentic AI.

### This is the refreshed version from Summer 2026

This has fully refreshed content with the latest tools, models and techniques. Answers to common questions:  
[What changed in the upgrade?](https://edwarddonner.com/avatar?q=67)  
[Why was there an upgrade?](https://edwarddonner.com/avatar?q=65)  
[I was in the middle of the course - how do I upgrade my code](https://edwarddonner.com/avatar?q=66)  

### Answers to the most common questions

[My Cursor looks different to yours (new splash screen)](https://edwarddonner.com/avatar?q=54)  
[Can I use Gemini or free models instead of OpenAI Yes!](https://edwarddonner.com/avatar?q=8)  
[Where are the course resources](https://edwarddonner.com/2025/04/21/the-complete-agentic-ai-engineering-course/)   
[How does this course fit in with your others?](https://edwarddonner.com/curriculum)  
[Can I take this course with no programming background?](https://edwarddonner.com/avatar?q=2)  
[What job can I get after taking this course?](https://edwarddonner.com/avatar?q=3)  

### Before you begin

I'm here to help you be most successful! Please do reach out if I can help, either in the platform or by emailing me direct (ed@edwarddonner.com). It's always great to connect with people on LinkedIn to build up the community - you'll find me here:  
https://www.linkedin.com/in/eddonner/  

And my YouTube channel has many supplemental videos to add to the course; you'll find it here:  
https://youtube.com/@edward.donner

### The not-so-dreaded setup instructions

Perhaps famous last words: but I really, truly hope that I've put together an environment that will be not too horrific to set up!

- Windows people, your instructions are [here](setup/SETUP-PC.md)
- Mac people, yours are [here](setup/SETUP-mac.md)
- Linux people, yours are [here](setup/SETUP-linux.md)

Any problems, please do contact me.

### Super useful resources

- The course [resources](https://edwarddonner.com/2025/04/21/the-complete-agentic-ai-engineering-course/) with videos
- Many essential guides in the [guides](guides/01_intro.ipynb) section
- My [Avatar](https://edwarddonner.com/avatar) that can answer all common questions

### API costs - please read me!

This course does involve making calls to OpenAI and other frontier models, requiring an API key and a small spend, which we set up in the SETUP instructions. If you'd prefer not to spend on API calls, there are cheaper alternatives like DeepSeek and free alternatives like using Ollama!

Details are [here](guides/09_ai_apis_and_ollama.ipynb).

Be sure to monitor your API costs to ensure you are totally happy with any spend. For OpenAI, the dashboard is [here](https://platform.openai.com/usage).

### ABOVE ALL ELSE -

Be sure to have fun with the course! You could not have picked a better time to be learning about Agentic AI. I hope you enjoy every single minute! And if you get stuck at any point - [contact me](https://www.linkedin.com/in/eddonner/).

---

### 2 Openai Community Contributions Deep Research With Openllmetry Docs Readme (`2_openai/community_contributions/deep_research_with_openllmetry/docs/readme.md`)

This example, shows instrumentation using OpenLMMetry. With this auto instrucmentation you get for 'free' attributes which aling with https://opentelemetry.io/docs/specs/semconv/gen-ai/ Makes it easier when using multi-LLMs as you have a consistent set of attributes to query from. 


Uses a local otel collector which forwards to Dynatrace as the backend

>>pip3 install traceloop-sdk

1. set the .env file with the otel endpoint and Dynatrace API token
2. run deep-research.py
3. open Dynatrace and view Distributed Traces app; the traces from the llm calls will be shown
>example: ../dynatrace-trace.png

misc:
https://www.linkedin.com/in/jason-godbold-smith-4788a515b/

--Dynatrace trial environment: https://www.dynatrace.com/signup/
--Authentication is handled using an API access token and the Authorization HTTP header. For more information on access tokens, see Dynatrace API - Tokens and authentication.
---scope: ingest traces, logs + metrics

---

### 1 Foundations Community Contributions Odinachi Docs Summary (`1_foundations/community_contributions/Odinachi/docs/summary.txt`)

PROFESSIONAL SUMMARY - ODINACHI DAVID

Odinachi David is a highly experienced Mobile Engineer and Software
Developer with over four years of hands-on experience designing,
building, and scaling mobile applications across fintech, healthcare,
and mobility sectors. He specializes in cross-platform and native mobile
development, with strong expertise in Flutter, SwiftUI, Kotlin, and
JavaScript.

Currently serving as a Lead Mobile Developer at DownToDate and Heala,
Odinachi plays a critical role in architecting and delivering robust
mobile solutions. His work involves leading development efforts,
designing scalable application structures, integrating APIs, and
ensuring high performance and reliability in production environments.
His leadership extends beyond coding, contributing to product direction,
system design decisions, and mentoring development processes.

Previously, Odinachi worked as a Mobile Engineer at Shuttlers and as a
Mobile Developer at Bloomm MFB and Bankly, where he gained significant
experience in building fintech and transportation applications. During
these roles, he contributed to developing user-centric applications with
secure payment integrations, real-time features, and seamless user
experiences.

His technical skill set is extensive and spans multiple programming
languages including Dart, Swift, Kotlin, JavaScript, and Python. He has
deep experience with frameworks such as Flutter and SwiftUI, and works
with backend and cloud technologies including Firebase, Supabase,
MongoDB, Redis, PostgreSQL, and AWS Amplify. He is also proficient in
integrating monitoring and analytics tools such as Firebase Crashlytics,
AppsFlyer, and Mixpanel to ensure app performance and user engagement
insights.

Odinachi has strong experience in software architecture patterns,
particularly Flutter BLoC, and emphasizes writing maintainable, testable
code. He actively develops unit tests and ensures full coverage of
application logic, including network interactions and database
integrations such as Firestore.

Beyond engineering, Odinachi is building developer-focused tools and
platforms, including a system that generates API service layers and
models from endpoint configurations, as well as an AI-powered learning
platform called Lenaz Tutor. This demonstrates his ability to think
productively, combining technical depth with product innovation.

He holds a BSc in Economics from the National Open University of
Nigeria, giving him a unique interdisciplinary perspective that blends
technical expertise with economic and business understanding.

Odinachi is also expanding his skillset toward AI and Machine Learning,
positioning himself for future roles in intelligent systems development.

With a strong foundation in mobile engineering, backend systems, and
product development, Odinachi David brings a combination of technical
excellence, leadership, and innovation, making him a valuable asset in
building modern, scalable digital products.

---

### 1 Foundations Community Contributions Andresr27 Docs Private Generic (`1_foundations/community_contributions/andresr27/docs/private_generic.md`)

# Summary
My name is Andres. I'm a highly creative person who is interested in solving complex problems looking at them from a wide perspective. I feel comfortable
working dynamically in teams and under pressure. Amongst many things, I value knowledge, self-criticism and constant learning as fundamental tools to achieve success in all aspects of life.

# Target Roles_
Roles:
- Senior Full Stack Developer
- Lead Software Engineer
- Technical Lead

Preferred Industries:
- FinTech
- HealthTech
- SaaS Companies

Preferred Locations:
- Remote (Global)


Companies of Interest:
- Netlabs

# Interview Preparation Notes:

## Common Technical Questions:
1. System Design: How would you design a URL shortener?
2. Algorithms: Explain your approach to optimizing database queries
3. Architecture: Experience with microservices vs monoliths

## Behavioral Questions (STAR Format):
- Leadership: Led team through critical production outage
- Conflict: Resolved disagreement about tech stack choice
- Achievement: Implemented CI/CD pipeline reducing deployment time

## Questions to Ask Interviewers:
- What's the biggest technical challenge your team faces?
- How do you approach technical debt?
- What's the career progression path?

## Salary Expectations:
- Current range: $150k-180k
- Negotiation points: Remote work, learning budget, equity, on call hours.

---

### 1 Foundations Community Contributions Amirna2 Contributions Personal Ai Docs Prompt Refactoring Plan (`1_foundations/community_contributions/amirna2_contributions/personal-ai/docs/prompt-refactoring-plan.md`)

# Prompt Management Refactoring Plan

## Overview
This document outlines the plan to refactor the prompt management system in the career_chatbot.py application. The goal is to improve maintainability, organization, and reusability by extracting prompts into separate files and creating a simple prompt loading system.

## Current State Analysis

### Existing Prompts
The application currently has several prompts embedded as f-strings within Python methods:

1. **Main Chat System Prompt** (`_create_system_prompt()` - line 889)
   - Instructions for AI assistant behavior
   - Critical instructions for contact handling
   - Job matching thresholds
   - Tool descriptions
   - Context injection (resume, LinkedIn, summary)

2. **Base System Prompt** (`_create_base_system_prompt()` - line 403)
   - Simplified version without evaluation context
   - Used for initial chat responses

3. **Evaluator System Prompt** (`_create_evaluator_prompt()` - line 293)
   - Instructions for response evaluation
   - Validation logic for tool usage
   - Behavioral rules verification
   - Context provided to evaluator

4. **Evaluator with GitHub Context** (`_create_evaluator_prompt_with_github()` - line 561)
   - Enhanced evaluator prompt
   - Includes GitHub tool results as valid context

5. **Chat Rerun Prompt** (inline in `rerun()` method - line 386)
   - Template for regenerating responses after evaluation failure
   - Includes feedback from failed evaluation

6. **Job Matching Prompt** (inline in `evaluate_job_match()` - line 742)
   - Detailed job analysis instructions
   - Skill assessment levels
   - Match level definitions
   - Contact facilitation thresholds

### Current Issues
- Prompts are scattered throughout the codebase
- Difficult to edit prompts without modifying Python code
- Variable substitution using f-strings is tightly coupled
- No clear separation between prompt logic and application logic
- Hard to track prompt changes in version control

## Proposed Solution

### 1. Directory Structure
```
personal-ai/
├── prompts/
│   ├── chat_init.md          # Main AI assistant system prompt
│   ├── chat_base.md          # Base system prompt without evaluation
│   ├── evaluator.md          # Evaluator system prompt
│   ├── evaluator_github.md   # Evaluator prompt with GitHub context
│   ├── chat_rerun.md         # Rerun prompt for failed evaluations
│   └── job_match.md          # Job matching analysis prompt
├── promptkit.py              # Prompt loading and rendering module
└── career_chatbot.py         # Updated to use promptkit
```

### 2. PromptKit Module Implementation

```python
from pathlib import Path
import re

_pat = re.compile(r"\{([a-zA-Z0-9_\.]+)\}")

def _get(ctx, path):
    """Navigate nested objects/dicts to retrieve values"""
    cur = ctx
    for p in path.split("."):
        cur = cur[p] if isinstance(cur, dict) else getattr(cur, p)
    return cur

def render(path, vars):
    """Load and render a prompt template with variable substitution"""
    txt = Path(path).read_text(encoding="utf-8")
    return _pat.sub(lambda m: str(_get(vars, m.group(1))), txt)
```

### 3. Prompt File Format

Each prompt will be a markdown file with variable placeholders using `{variable_name}` syntax.

Example: `prompts/chat_init.md`
```markdown
You are an AI assistant designed by {config.name} and representing them, helping visitors learn about their professional background.
Your knowledge comes from {config.name}'s resume, LinkedIn profile, and professional summary provided below.
Your knowledge can also be augmented with real-time data from GitHub if needed and/or when appropriate.

CRITICAL INSTRUCTIONS:
1. ALWAYS search through ALL the provided context (Summary, LinkedIn, Resume) before claiming you don't have information. Be precise and thorough.
2. CONTACT IS A TWO-STEP PROCESS:
   a. First, OFFER to facilitate contact for i) professional questions you can't fully answer, or ii) job matches rated '{config.job_match_threshold}' or better. Your response should just be text making the offer.
   b. Second, WAIT for the user to provide their email. ONLY THEN should you use the `record_user_details` tool. Never invent an email.
...

## CONTEXT:

### Summary:
{context.summary}

### LinkedIn Profile:
{context.linkedin}

### Resume:
{context.resume}
```

### 4. Integration Changes

Update methods in `career_chatbot.py`:

```python
from promptkit import render

class ChatAgent:
    def _create_system_prompt(self) -> str:
        """Create the system prompt for the AI assistant"""
        vars = {
            'config': self.config,
            'context': self.context
        }
        base_prompt = render('prompts/chat_init.md', vars)

        # Add conditional tools section if web_search_service exists
        if self.web_search_service:
            tools_section = render('prompts/tools_github.md', vars)
            base_prompt += "\n" + tools_section

        return base_prompt
```

### 5. Variable Mapping

Variables to be passed to prompt templates:

- **config**: ChatbotConfig object
  - `config.name`
  - `config.job_match_threshold`
  - `config.evaluator_model`
  - etc.

- **context**: Dictionary with document content
  - `context.summary`
  - `context.linkedin`
  - `context.resume`

- **Dynamic variables**: For specific prompts
  - `role_title` (job matching)
  - `job_description` (job matching)
  - `feedback` (rerun prompt)
  - `github_context` (evaluator with GitHub)
  - `evaluation_criteria` (evaluator prompts)

### 6. Migration Steps

1. **Phase 1: Setup**
   - Create `prompts/` directory
   - Implement `promptkit.py` module
   - Add unit tests for promptkit

2. **Phase 2: Extract Prompts**
   - Extract each prompt to its corresponding .md file
   - Preserve all existing formatting and variables
   - Test each extraction individually

3. **Phase 3: Update Code**
   - Modify each `_create_*_prompt()` method to use promptkit
   - Update inline prompts to use promptkit
   - Ensure backward compatibility

4. **Phase 4: Testing**
   - Run existing tests
   - Manual testing of all chat flows
   - Verify prompt rendering with various inputs

5. **Phase 5: Documentation**
   - Update README with prompt management section
   - Document variable naming conventions
   - Add examples of prompt customization

## Benefits

1. **Separation of Concerns**: Prompts are separate from code logic
2. **Easier Maintenance**: Edit prompts without touching Python code
3. **Better Version Control**: Clear diffs for prompt changes
4. **Reusability**: Promptkit can be used for future prompt needs
5. **Consistency**: Unified approach to variable substitution
6. **Flexibility**: Easy to add new prompts or modify existing ones
7. **Testing**: Prompts can be tested independently

## Risks and Mitigations

| Risk | Mitigation |
|------|------------|
| Breaking existing functionality | Comprehensive testing, gradual migration |
| Variable naming conflicts | Clear documentation, naming conventions |
| Performance impact | Minimal - file reads are cached, regex is efficient |
| Complex nested variables | Enhanced _get() function handles nested access |

## Future Enhancements

1. **Prompt Versioning**: Support for multiple prompt versions
2. **Prompt Validation**: Schema validation for required variables
3. **Prompt Inheritance**: Base prompts that others can extend
4. **Dynamic Loading**: Hot-reload prompts without restart
5. **Prompt Library**: Shared prompts across multiple agents
6. **Localization**: Support for multi-language prompts

## Implementation Timeline

- **Step 1**: Create promptkit module and tests
- **Step 2**: Extract and migrate prompts
- **Step 3**: Update career_chatbot.py integration
- **Step 4**: Testing and documentation
- **Step 5**: Review and refinements

## Success Criteria

- [ ] All existing functionality preserved
- [ ] All tests pass
- [ ] Prompts are in separate .md files
- [ ] Promptkit successfully renders all prompts
- [ ] Documentation is complete
- [ ] Code is cleaner and more maintainable

---

--- METRICS ---
- Files Extracted: 5
- Estimated Token Budget: ~4375 tokens
- Canonical Reference: https://codewiki.google/github.com/ed-donner/agents
