Lightweight framework for building LLM agents with tool use, memory, and multi-round research pipelines.
Project description
KHarness
A lightweight Python framework for building LLM agents with tool use, conversation memory, and multi-round research pipelines. Supports local inference via llama.cpp and Ollama.
Installation
pip install kharness
Optional dependencies (install what you need):
pip install langchain-core # Required for tool decorators
pip install ddgs beautifulsoup4 # Web tools
pip install yahoors # Stock tools
Providers
Providers wrap a local inference backend and expose a unified chat() interface.
Ollama
from kharness.providers import Ollama
provider = Ollama("qwen2.5:7b") # model is required
response = provider.chat(
[{"role": "user", "content": "Hello!"}]
)
| Parameter | Default | Description |
|---|---|---|
model |
— | Model name (required) |
server_url |
"http://localhost" |
Server host |
port |
"11434" |
Server port |
max_iterations |
10 |
Max tool-call loop iterations |
LlamaCpp
Assumes a llama-server process is already running. Connect to it:
from kharness.providers import LlamaCpp
provider = LlamaCpp() # defaults: 127.0.0.1:8080
if provider.check_health():
response = provider.chat(
[{"role": "user", "content": "Hello!"}]
)
| Parameter | Default | Description |
|---|---|---|
server_url |
"http://127.0.0.1" |
Server host |
port |
"8080" |
Server port |
max_iterations |
5 |
Max tool-call loop iterations |
strip_tools_after |
3 |
Force text response after N tool rounds |
Agent
Agent wraps a provider with optional tools and memory, exposing run() for chat and research() for multi-round deep dives.
Basic chat
from kharness.providers import Ollama
from kharness.agent import Agent
provider = Ollama("qwen2.5:7b")
agent = Agent(provider)
response = agent.run("What is the capital of France?")
print(response)
With a system prompt file
agent = Agent(provider, soul_md_path="persona.md")
With tools
Pass a dict or list of dicts mapping tool names to LangChain @tool objects:
from kharness.tools import WEB_TOOL_MAP
agent = Agent(provider, tool_map=WEB_TOOL_MAP)
response = agent.run("What happened in the news today?")
With memory
Attach a Memory object to maintain conversation history across turns:
from kharness.memory import Memory
memory = Memory(max_turns=20)
agent = Agent(provider, memory=memory)
agent.run("My name is Alice.")
agent.run("What's my name?") # remembers "Alice"
Memory
Memory manages a sliding window of conversation history. It stores messages as {"role": ..., "content": ...} dicts — the format all providers expect.
from kharness.memory import Memory
memory = Memory(max_turns=10) # keeps last 10 user/assistant pairs
memory.add("user", "Hello")
memory.add("assistant", "Hi there!")
history = memory.get_history() # list of message dicts
memory.clear()
| Parameter | Default | Description |
|---|---|---|
max_turns |
20 |
Max user/assistant pairs to retain |
Research pipeline
agent.research() runs a structured multi-round research loop:
- Plan — generates search queries from the question
- Gather — runs web searches for each query
- Analyze — synthesizes findings and decides if more searching is needed
- Repeat — loops up to
max_roundstimes if gaps remain - Report — writes a final comprehensive answer
from kharness.providers import Ollama
from kharness.tools import WEB_TOOL_MAP
from kharness.agent import Agent
provider = Ollama("qwen2.5:14b")
agent = Agent(provider, tool_map=WEB_TOOL_MAP)
report = agent.research(
"What are the latest developments in fusion energy?",
max_rounds=3,
planning_tokens=512,
analysis_tokens=2048,
report_tokens=8000,
)
print(report)
| Parameter | Default | Description |
|---|---|---|
max_rounds |
3 |
Maximum search/analyze iterations |
planning_tokens |
1024 |
Token budget for query planning |
analysis_tokens |
2048 |
Token budget for per-round analysis |
report_tokens |
8000 |
Token budget for final report |
debug |
True |
Log phase progress |
Tools
Tools are standard LangChain @tool functions. Convenience maps are exported for easy use with Agent.
Web tools
from kharness.tools import WEB_TOOL_MAP
| Tool | Description |
|---|---|
web_search |
DuckDuckGo text search, returns top snippets |
fetch_page |
Fetches a URL and extracts readable text |
news_search |
DuckDuckGo news search with dates |
image_search |
Returns direct image URLs |
wikipedia_summary |
Wikimedia REST API summary |
search_and_fetch |
Combines search + full page fetch |
search_subreddit |
Fetches top posts from a subreddit |
Stock tools
from kharness.tools import STOCK_TOOL_MAP
| Tool | Description |
|---|---|
get_candles |
OHLCV candlestick data |
get_options |
Options chain (calls and puts) |
get_income_statements |
Income statement financials |
get_balance_sheet |
Balance sheet financials |
get_cash_flow |
Cash flow statement |
Custom tools
Any LangChain @tool works:
from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
agent = Agent(provider, tool_map={"add": add})
Logging
KHarness uses Python's standard logging module. To see runtime output:
import logging
logging.basicConfig(level=logging.INFO)
Use logging.DEBUG to see individual tool calls.
Requirements
- Python >= 3.12
- A running Ollama daemon or llama-server process
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kharness-0.1.1.tar.gz.
File metadata
- Download URL: kharness-0.1.1.tar.gz
- Upload date:
- Size: 14.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c1e49171f486f22e74de846a21eaea557acdb037f8de2f0a2c105dcf6ea2b07
|
|
| MD5 |
f8b4ff5e97df63475ebd2ad465f71a3d
|
|
| BLAKE2b-256 |
1dca658ad538d90415948ceda113afbf6b40436e970104a92ffee7c47cc274b7
|
File details
Details for the file kharness-0.1.1-py3-none-any.whl.
File metadata
- Download URL: kharness-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc8cc7a8f6b0a263bd93fea5d0022ad56bc2c28fa369b6b945f41f982201f4dc
|
|
| MD5 |
5b7065e3fa69721362f4ed1f39e1e8ee
|
|
| BLAKE2b-256 |
19ecc4501b542b88c819d0307cc113aa48738c1bb543cb403ed13ae94dbe4236
|