What spiega is about
- Knowledge sharing
- Portfolio
agentic interview
agentic interview
In an agentic world agent should be able to run an interview with you. This means agents should retrieve enough information about your experience.
personal information
First of all I created the following yaml files describing those main areas:
- skills
- languages, programming languages, technologies
- personal profile
- profile description, soft skills
- portfolio
- project descriptions, verticals
- resume
- working experiences, education, certificates
file input
The files look like:
head -n 4 ~/lav/src/spiega/markdown/skills.yml
- topic: languages skill: 'Native: Italian. Fluent: English, German, Spanish. Intermediate: French, Portuguese.' - topic: programming skill: python, js, c++, c, R, spark, go (viz) openGL, Qt, GTK+
Those file are used to create as well the resume website using the script gen_portfolio.py.
technical sources
We need now more detailed information about the actual skills and proficiency. For some source files we can’t provide access but we let a language model to summarize the skills and competences for that work. We analyze:
| source | quantity | link | website | summary |
|---|---|---|---|---|
| code | 3k3 sources | src | blog | summary |
| tech | 120 blog posts | spiega | blog | summary |
| thoughts | 30 posts | scritti | blog | summary |
| pictures | 2k images | f/ | blog | summary |
| science | 30 works | PhD | physics | summary |
| videos | 180 videos | videos | viudi | summary |
summaries
Given the sensitivity of information we run everything locally
- IPs
- LLMs summarize the content and don’t expose the sources
- impartial
- let LLMs judge the quality of your work
- concise
- pre-parse your knowledge base to build your digital twin
---title: knowledge parsingfontSize: 10darkMode: Truetheme: neo-dark---flowchart LRKN["`source codeknowledgepersonal`"]DOC@{ shape: docs, label: "Knowledge"}LLM@{ shape: procs, label: "LLMs"}PY@{ shape: lin-cyl, label: "python" }PY -- transforms --> DOCLLM -- reads --> DOCLLM -- writes --> KN
Figure 1: diagram of the implementation
graphs
We have two main graphs:
- namual: org-roam
- all your knowledge gets linked together
- automated: knowledge graph
- where LLMs need to parse your knowledge base
The technical description of the project is written here knowledge graph and presented here knowledge_graph.html.
graph creation approaches
manual vs automated
- naming
- LLMs find well descriptive names
- relevance
- users have better context to judge
- depth
- LLMs are great help to summarize any type of document
| conf | workload | control | relevance | usefulness | integration | depth | versatility |
|---|---|---|---|---|---|---|---|
| manual | 5.0 | 5.0 | 4,7 | 5.0 | 4.7 | 3.0 | 3.8 |
| automated | 2.0 | 3.0 | 3.4 | 3.7 | 3.8 | 5.0 | 3.6 |
Figure 2: Manual vs automated knowledge creation
graph creation
- first approach
- we create directly the graph
- issues
- inconsistencies between links and nodes
from ollama import chatmessages = [{"role":"user","content":identify_relationship},{"role":"user","content":d["description"]}]response = chat(messages=messages,model=model_id,format=GraphD3.model_json_schema(),)
The results of the summaries is processed by this script
links creation
Then:
- links
- created first with description of the nodes
- node
- definition enrichment asking a second model
- graph
- the combination of the two
messages = [{"role":"user","content":identify_links},{"role":"user","content":d["description"]}]response = chat(messages=messages,model=model_id,format=GraphD3L.model_json_schema(),)enD, relD = g_r.relation2graph(blogD)enD = g_r.categorize_node(enD,model_id)
links creation
The sketch of the process is as following
---title: graph entity---erDiagramDOCS ||--o{ LINKS : "parsed into"LINKS ||--o{ NODES : "generates"GRAPH ||--|{ NODES : "contains"GRAPH ||--|{ LINKS : "contains"DOCS {string file_namestring summarystring tagsstring description}LINKS {string sourcestring targetstring relationship_typestring relationship_desc}NODES {string id PKstring namestring description}GRAPH {list NODESlist LINKS}
Figure 3: diagram of the implementation
graph database
We then import the graph into neo4j dashboard and type the query to select all nodes and links with a cypher neo4j query:
MATCH (n)-[r]->(m)RETURN *;
parent graph
Information is too atomistic and we need to create a parent graph.
- embed
- the text
- cluster
- the nodes around the embedding
- summarize
- the text for all the clustered nodes
- link
- all the entities together
- nodes
- categorized from the links
- connections
- preserved between clusters and nodes
llm = c_t.get_llm_mcp(model_id=model_id)relD, grpD = k_h.level_up_link(enD,llm,embed_model,clusterN=clusterN)grpD = g_r.gen_relationship_grp(llm,grpD,model_id=model_id)enD1, relD1 = g_r.relation2graph(grpD,dtype="group")enD1 = g_r.categorize_node(enD1,model_id)
org-roam
- org-roam
- is a extraordinary tool fed by ordinary typing.
- .html files
- more than text files the look like operating systems
.html files
.html files are a mixture of any possible application for daily use:
- agenda
- to schedule a task or to set an alert
- tags
- to specify meta information
- logbook
- the time spent on tasks
- status
- whether an action is done or pending
- trees
- explain hierarchical structures
- nodes
- tag every element to create interconnections
- code
- define code to execute
- plots
- plot data with gnuplot
- link
- link to anything: files, websites, buffers, images…
- webpage content
- show the text of a web page
- local org files
- open new buffers from shell
- roam
- organizes the .html node information into graphs
- spreadsheet
- formulas on tables
And pipe all together as you like.
done emacs present
The tool where .html show their best expression is emacs (text editor).
- emacs with .html files
- there is no other program you need to use.
- preview
- emacs show .html files as any other text editor
.html and LLMs
Emacs has nice integration with many agentic tools
- ellama
- quick support in any buffer
- gptel
- for the integration with mcp
- gptel base
- base package
- mcp.el
- start the hub
- custom gptel tools
- user defined tools
- gptel-mcp
- integration between the packages
- mcp
- for adding my own tools and external mcp
- aideremacs
- connect aider with emacs
- pi agent
- connect pi-agent with emacs
- opencode
- open-code support
MCP server
We set up a MCP server where we can check the status of the tools that the LLMs can use control panel.
MCP hub
Emacs has it’s internal tool to check the status of the interactions between LLMs and MCP server.
emacs flow
Here is an example of a flow with emacs and LLMs
sequenceDiagramemacs-->ellama: promptemacs-->gptel: toolsemacs-->pi_agent : instructionpi_agent-->ollama: promptgptel-->mcp_server: promptmcp_server-->llama.cpp: instruction(use-package ox-reveal)gptel-->emacs: codepi_agent-->emacs: code
Figure 4: result of mermaid plot
org-roam
While you edit your .html files org-roam runs in the background, reads all your edits and:
- database
- creates entry for all links, nodes
- search
- allow to search any node in your knowledge base
- org-roam-ui
- fully featured, nice looking and useful knowledge graph updating in real time while typing
Example of org-roam database query
(org-roam-db-query [:select * :from nodes])
customization
We can customize any function. Here we customize a tool for the MCP hub
;; (insert (duckduckgo-search-text "intertino"))(defun my/read-buffer-content (buffer-name)(let ((buffer (get-buffer buffer-name)))(if (bufferp buffer)(with-current-buffer buffer(concat "[BUFFER CONTENT]: "(buffer_string)))"[ERROR]: Buffer does not exist")))(gptel-make-tool:name "get-buffer-content-as-string":function 'my/read-buffer-content:description "returns the string contents inside the emacs buffer":args '(list '(:name "buffer":type "string":description "buffer name to read")):category "emacs")
extensions
We can use .html functionalities to let LLMs operate on the system
| Headline | Time |
|---|---|
| Total time | 0:00 |
Call internal endpoint
curl -s -X PORT http://localhost:9876/run -H 'Content-Type: applicationon/json -d {"text":"Add a cube at origin and rotate it by 90 degrees z"}'
plot results
LLMs can use .html internal functionalities to save a lot of time
| LLM | token/s | token/s |
|---|---|---|
| qwen2.5 | 257.72 | 21.39 |
| qwen3.5 | 165.77 | 19.68 |
| llama3.2 | 71.00 | 11.50 |
| mistral | 134.19 | 14.33 |
| deepseek | 257.56 | 17.67 |
Figure 5: results of org plotting
publish / present
.html have many options to export/convert the file for presentations:
- blog post
- customize the export and the style
- export
- export all the media for publishing
- slides
- custom or reveal.js
graphics
.html has many integration with many handy visualization tools:
- mermaid
- for graphs
- graphviz/dot
- graphs more text like
- gnuplot
- many plotting options
- lilypond
- for music
\version "2.24.4"\relative c' {g a b cd e f gg1}
Figure 6: lilypond sheet music
animations
To create video animations we can:
- manim
- the 1Blue3Brown animation python library we use in manim_animations.py documented in manim_animations.html.
- blender
- where we created scripts to load the svg created by the other software and animate them
- d3.js
- library for graphs visualization
We need to first run the web server and then hit network-viz which can export to blender
cd ~/lav/src/blender_twin/physics/phys_opt/bash run.sh &
kill $(ps | grep uvicorn | awk '{print $1}')
agentic interview
export the content
Now that we have set up all the knowledge base
(org-reveal-export-to-html)
agent_interview.html
mv $outF ~/lav/siti/spiega/a/${outF/.html/_slide.html}