Angshul commited on
Commit
7c48529
·
verified ·
1 Parent(s): f8b3fa0

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +15 -0
  2. README.md +64 -10
  3. fgao.yaml +14 -0
  4. pyproject.toml +51 -0
Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12-slim
2
+
3
+ ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1
4
+ RUN useradd --create-home --uid 1000 user
5
+ WORKDIR /home/user/app
6
+
7
+ COPY --chown=user pyproject.toml ./
8
+ COPY --chown=user src ./src
9
+ RUN pip install ".[server,openai]"
10
+ COPY --chown=user fgao.yaml ./
11
+ COPY --chown=user data ./data
12
+
13
+ USER user
14
+ EXPOSE 7860
15
+ CMD ["fgao", "serve", "--config", "fgao.yaml", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,15 +1,69 @@
1
  ---
2
  title: FGAO API
3
- emoji: 🐢
4
- colorFrom: blue
5
- colorTo: pink
6
- sdk: gradio
7
- sdk_version: 6.31.0
8
- python_version: '3.13'
9
- app_file: app.py
10
  pinned: false
11
- license: apache-2.0
12
- short_description: Feedback-Greedy Agentic Orchestration
13
  ---
14
 
15
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: FGAO API
3
+ emoji: 🧭
4
+ colorFrom: indigo
5
+ colorTo: gray
6
+ sdk: docker
7
+ app_port: 7860
 
 
8
  pinned: false
9
+ short_description: HTTP API for training-free FGAO orchestration of RAG
 
10
  ---
11
 
12
+ # FGAO API
13
+
14
+ FGAO (Feedback-Greedy Agentic Orchestration) is a **retrieval-augmented question-answering API**.
15
+
16
+ ## What it does
17
+
18
+ For each question, FGAO decides step by step which retrieval and LLM operations to run:
19
+ - **Sources:** which source to query, and how deep to search it.
20
+ - **Grading:** whether to grade the passages first.
21
+ - **Fallback:** when to fall back to a second source.
22
+ - **Checking:** when to check the answer against the passage it came from.
23
+ - **Abstaining:** when to stop and give no answer.
24
+
25
+ It returns an answer only if that answer is **grounded** in a retrieved passage and **passed a support check**; otherwise it returns `answer: null`. Every response includes the decision trace.
26
+
27
+ ## Why it is supposed to be better
28
+
29
+ - **No LLM decides the control flow.** Each step is chosen by an explicit score: predicted progress on checkable goals, minus cost, plus a one-step lookahead. Decisions are cheap, deterministic and inspectable. A prompt cannot talk the pipeline out of verifying.
30
+ - **Feedback within the question.** When an operation fails, FGAO's estimate for it and for similar operations drops, so it escalates instead of repeating itself. Fixed pipelines such as CRAG and Self-RAG hard-code those rules.
31
+ - **Budget-aware.** Each operation has a cost. FGAO stops when nothing left is worth its cost, rather than running a fixed sequence.
32
+ - **Abstains when unsure.** An answer that is not grounded and supported is never returned.
33
+ - **Training-free.** There are no learned weights, so any LLM and any retriever can be swapped in.
34
+
35
+ ## How to use
36
+
37
+ 1. Add a Space secret `HF_TOKEN` (Settings → Variables and secrets). The LLM is called through Hugging Face Inference Providers; change `model` in `fgao.yaml` to use another model.
38
+ 2. Optionally add `FGAO_API_KEYS=key1,key2` to require `Authorization: Bearer <key>`.
39
+
40
+ Ask with your own passages:
41
+
42
+ ```bash
43
+ curl -X POST https://<space-host>/v1/answer -H "Content-Type: application/json" -d '{
44
+ "question": "What is the capital of Peru?",
45
+ "documents": ["Lima is the capital of Peru.", {"title": "Chile", "text": "Santiago is the capital of Chile."}],
46
+ "trace": false
47
+ }'
48
+ ```
49
+
50
+ To ask over the built-in corpus instead (`data/kb.jsonl`, one `{"text", "title", "id"}` per line; replace it with your own), omit `documents`.
51
+
52
+ From Python:
53
+
54
+ ```python
55
+ import requests
56
+ r = requests.post("https://<space-host>/v1/answer", json={"question": "...", "documents": [...]}).json()
57
+ r["answer"], r["support_passage"], r["trace"]
58
+ ```
59
+
60
+ | endpoint | |
61
+ |---|---|
62
+ | `POST /v1/answer` | `question`, plus optional `documents`, `web_documents`, `budget`, `trace` |
63
+ | `POST /v1/answer/stream` | the same, as Server-Sent Events: one `step` per decision, then `result` |
64
+ | `POST /v1/batch` | `questions: [...]`, plus optional `documents` |
65
+ | `GET /v1/info`, `/health`, `/metrics`, `/docs` | configuration, health, Prometheus metrics, interactive API docs |
66
+
67
+ The `<space-host>` is shown under "Embed this Space" → "Direct URL", for example `angshul-fgao-api.hf.space`.
68
+
69
+ Library and source: https://github.com/AngshulMajumdar/FGAO
fgao.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FGAO API configuration. Paths are relative to this file.
2
+ llm:
3
+ provider: openai # any OpenAI-compatible endpoint
4
+ base_url: https://router.huggingface.co/v1
5
+ model: Qwen/Qwen2.5-7B-Instruct # any chat model served by Hugging Face Inference Providers
6
+ api_key_env: HF_TOKEN # Space secret
7
+ temperature: 0
8
+ max_tokens: 128
9
+ timeout: 60
10
+ resilience: {attempts: 3, backoff: 0.5, timeout: 60, max_concurrency: 32}
11
+ kb: {type: bm25, path: data/kb.jsonl} # default corpus; requests may send their own "documents"
12
+ budget: 16
13
+ on_error: record
14
+ server: {max_inflight: 32, max_queue: 256, request_timeout: 300, max_batch: 64, max_documents: 500}
pyproject.toml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fgao"
7
+ version = "1.0.0"
8
+ description = "Feedback-Greedy Agentic Orchestration: a training-free numerical controller for RAG and tool-using pipelines"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ authors = [{ name = "Angshul Majumdar", email = "angshul@iiitd.ac.in" }]
12
+ keywords = ["rag", "orchestration", "agents", "retrieval-augmented-generation", "langchain", "langgraph", "llm"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Intended Audience :: Developers",
16
+ "Intended Audience :: Science/Research",
17
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
18
+ "Typing :: Typed",
19
+ ]
20
+ dependencies = []
21
+
22
+ [project.urls]
23
+ Homepage = "https://angshulmajumdar.github.io/FGAO/"
24
+ Repository = "https://github.com/AngshulMajumdar/FGAO"
25
+ Documentation = "https://github.com/AngshulMajumdar/FGAO/tree/main/docs"
26
+
27
+ [project.optional-dependencies]
28
+ langchain = ["langchain-core>=0.3"]
29
+ langgraph = ["langgraph>=0.2", "langchain-core>=0.3"]
30
+ huggingface = ["huggingface_hub>=0.24"]
31
+ transformers = ["transformers>=4.40"]
32
+ openai = ["openai>=1.0"]
33
+ anthropic = ["anthropic>=0.30"]
34
+ demo = ["gradio>=4.44", "huggingface_hub>=0.24"]
35
+ server = ["fastapi>=0.110", "uvicorn[standard]>=0.29", "pyyaml>=6", "httpx>=0.27"]
36
+ mcp = ["mcp>=1.0"]
37
+ all = ["langchain-core>=0.3", "langgraph>=0.2", "huggingface_hub>=0.24", "openai>=1.0", "anthropic>=0.30",
38
+ "fastapi>=0.110", "uvicorn[standard]>=0.29", "pyyaml>=6", "httpx>=0.27", "mcp>=1.0"]
39
+ dev = ["pytest>=7"]
40
+
41
+ [project.scripts]
42
+ fgao = "fgao.server.cli:main"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.setuptools.package-data]
48
+ fgao = ["py.typed"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]